From 88a3aa78e924668189a527b99601942530d0af0b Mon Sep 17 00:00:00 2001 From: Sylvain Leclerc Date: Thu, 30 May 2024 15:58:35 +0200 Subject: [PATCH 001/127] Feature/vcpkg linux (#2078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continuing work on VCPKG for Linux, basically trying to simplify workflows from https://github.com/AntaresSimulatorTeam/Antares_Simulator/pull/2049 and using manifest mode. **Status** - Build OK for all workflows - Caching OK for all workflows **Overall strategy** Merge this in feature branch `feature/vcpkg-dependencies` first. The whole feature branch will be merged only once it brings sufficient added value to existing mechanisms. In particular, when we are able to remove the use of `antares-deps` in favor of using vcpkg would be a good time to do so. Documentation should be updated in `feature/vcpkg-dependencies` when the developer workflow is clear. --------- Signed-off-by: Sylvain Leclerc Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> Co-authored-by: Jason Marechal Co-authored-by: Jason Maréchal <45510813+JasonMarechal25@users.noreply.github.com> Co-authored-by: Florian OMNES --- .github/workflows/centos7.yml | 59 +- .github/workflows/oracle8.yml | 52 +- .github/workflows/sonarcloud.yml | 24 + .github/workflows/ubuntu.yml | 57 +- .github/workflows/windows-vcpkg.yml | 583 +++++++++--------- src/CMakeLists.txt | 43 +- src/cmake/wxWidgets/FindwxWidgets.cmake | 1 - src/libs/antares/writer/CMakeLists.txt | 1 - src/packaging/Config.cmake.in | 12 +- .../test_binding_constraints.cpp | 40 +- .../end-to-end/simple_study/simple-study.cpp | 40 +- .../libs/antares/array/tests-matrix-load.cpp | 38 +- .../libs/antares/array/tests-matrix-save.cpp | 38 +- .../benchmarking/test_duration_collector.cpp | 38 +- .../antares/concurrency/test_concurrency.cpp | 41 +- .../area/test-save-area-optimization-ini.cpp | 38 +- .../study/area/test-save-link-properties.cpp | 38 +- .../study/constraint/test_constraint.cpp | 38 +- .../antares/study/constraint/test_group.cpp | 38 +- .../antares/study/output-folder/study.cpp | 38 +- .../study/parameters/parameters-tests.cpp | 38 +- .../study/parts/hydro/test-hydro-series.cpp | 21 + .../parts/hydro/test-hydroreader-class.cpp | 21 + .../test-sc-builder-file-read-line.cpp | 38 +- .../test-sc-builder-file-save.cpp | 38 +- .../antares/study/series/timeseries-tests.cpp | 38 +- .../short-term-storage-input-output.cpp | 38 +- .../src/libs/antares/study/test_study.cpp | 38 +- .../thermal-price-definition.cpp | 38 +- src/tests/src/libs/antares/test_utils.cpp | 38 +- .../src/libs/antares/writer/CMakeLists.txt | 10 +- .../src/libs/antares/writer/test_writer.cpp | 40 +- .../test-unfeasible-problem-analyzer.cpp | 2 - .../solver/optimisation/adequacy_patch.cpp | 38 +- .../test-store-timeseries-number.cpp | 38 +- .../solver/simulation/test-time_series.cpp | 38 +- .../solver/simulation/tests-ts-numbers.cpp | 38 +- src/tests/src/solver/utils/basis_status.cpp | 38 +- src/triplets/x64-linux-antares.cmake | 5 + src/triplets/x64-linux-release.cmake | 7 + src/triplets/x64-windows-antares.cmake | 11 + src/triplets/x64-windows-release.cmake | 15 + src/vcpkg.json | 32 + vcpkg_manifest/vcpkg.json | 8 - 44 files changed, 1048 insertions(+), 875 deletions(-) create mode 100644 src/triplets/x64-linux-antares.cmake create mode 100644 src/triplets/x64-linux-release.cmake create mode 100644 src/triplets/x64-windows-antares.cmake create mode 100644 src/triplets/x64-windows-release.cmake create mode 100644 src/vcpkg.json delete mode 100644 vcpkg_manifest/vcpkg.json diff --git a/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index b43fde4cd1..5f5a34d4b6 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -46,7 +46,28 @@ jobs: yum install -y centos-release-scl yum install -y devtoolset-10-gcc* - - uses: ./.github/workflows/install-cmake-328 + - name: Install cmake 3.28 + run: pip3 install cmake==3.28.4 + + - name: Install VCPKG + # Note: we need to use environment variables instead of workflow variables + # because github messes up path variables when running in container, + # see https://github.com/actions/runner/issues/2058 + run: | + git submodule update --init vcpkg && ./vcpkg/bootstrap-vcpkg.sh -disableMetrics + echo "VCPKG_ROOT=$GITHUB_WORKSPACE/vcpkg" >> $GITHUB_ENV + echo "VCPKG_CACHE_DIR=$GITHUB_WORKSPACE/vcpkg_cache" >> $GITHUB_ENV + echo "VCPKG_BINARY_SOURCES=clear;files,$GITHUB_WORKSPACE/vcpkg_cache,readwrite" >> $GITHUB_ENV + + - name: Restore vcpkg binary dir from cache + id: cache-vcpkg-binary + # Note: we are stuck with v3, because v4 is not compatible with oracle8 image + uses: actions/cache/restore@v3 + with: + path: ${{ env.VCPKG_CACHE_DIR }} + key: vcpkg-cache-centos7-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} + # Allows to restore a cache when deps have only partially changed (like adding a dependency) + restore-keys: vcpkg-cache-centos7- - name: Init submodule run: | @@ -80,20 +101,22 @@ jobs: dnf -y config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo dnf -y install gh - - name: Configure run: | - source /opt/rh/devtoolset-10/enable - cmake -B _build -S src \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DDEPS_INSTALL_DIR=/rte-antares-deps-Release \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=ON \ - -DBUILD_not_system=OFF \ - -DBUILD_TOOLS=ON \ - -DBUILD_UI=OFF \ - -DCMAKE_PREFIX_PATH=${{ env.ORTOOLSDIR }}/install \ + source /opt/rh/devtoolset-10/enable + source /opt/rh/rh-git227/enable + cmake -B _build -S src \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ + -DDEPS_INSTALL_DIR=/rte-antares-deps-Release \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DBUILD_not_system=OFF \ + -DBUILD_TOOLS=ON \ + -DBUILD_UI=OFF \ + -DCMAKE_PREFIX_PATH=${{ env.ORTOOLSDIR }}/install \ - name: Build run: | @@ -139,5 +162,11 @@ jobs: tag: ${{ github.event.inputs.release_tag }} run: | gh release upload "$tag" _build/*.tar.gz _build/*.rpm - - + + - name: Cache vcpkg binary dir + if: always() + id: save-cache-vcpkg-binary + uses: actions/cache/save@v3 + with: + path: ${{ env.VCPKG_CACHE_DIR }} + key: vcpkg-cache-centos7-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} diff --git a/.github/workflows/oracle8.yml b/.github/workflows/oracle8.yml index 82666b7876..23c5d49d57 100644 --- a/.github/workflows/oracle8.yml +++ b/.github/workflows/oracle8.yml @@ -25,7 +25,6 @@ env: IS_PUSH: ${{ github.event_name == 'push' }} REF: ${{ inputs.target_branch =='' && github.ref_name || inputs.target_branch}} - jobs: build: @@ -50,7 +49,28 @@ jobs: - name: Checkout run: | - git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git -b ${{ env.REF }} . + git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git -b ${{ env.REF }} . + git config --global safe.directory '*' + + - name: Install VCPKG + # Note: we need to use environment variables instead of workflow variables + # because github messes up path variables when running in container, + # see https://github.com/actions/runner/issues/2058 + run: | + git submodule update --init vcpkg && ./vcpkg/bootstrap-vcpkg.sh -disableMetrics + echo "VCPKG_ROOT=$GITHUB_WORKSPACE/vcpkg" >> $GITHUB_ENV + echo "VCPKG_CACHE_DIR=$GITHUB_WORKSPACE/vcpkg_cache" >> $GITHUB_ENV + echo "VCPKG_BINARY_SOURCES=clear;files,$GITHUB_WORKSPACE/vcpkg_cache,readwrite" >> $GITHUB_ENV + + - name: Restore vcpkg binary dir from cache + id: cache-vcpkg-binary + # Note: we are stuck with v3, because v4 is not compatible with oracle8 image + uses: actions/cache/restore@v3 + with: + path: ${{ env.VCPKG_CACHE_DIR }} + key: vcpkg-cache-oracle8-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} + # Allows to restore a cache when deps have only partially changed (like adding a dependency) + restore-keys: vcpkg-cache-oracle8- - name: Config OR-Tools URL run: | @@ -65,9 +85,7 @@ jobs: rm ortools.zip - name: Init submodule - run: | - git config --global safe.directory '*' - git submodule update --init --remote src/antares-deps src/tests/resources/Antares_Simulator_Tests + run: git submodule update --init --remote src/antares-deps src/tests/resources/Antares_Simulator_Tests - name: Install dependencies run: | @@ -82,13 +100,15 @@ jobs: - name: Configure run: | - source /opt/rh/gcc-toolset-11/enable - cmake -B _build -S src \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=OFF \ - -DBUILD_TOOLS=ON \ - -DBUILD_UI=OFF \ - -DCMAKE_PREFIX_PATH=${{ env.ORTOOLS_DIR }}/install + source /opt/rh/gcc-toolset-11/enable + cmake -B _build -S src \ + -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DBUILD_TOOLS=ON \ + -DBUILD_UI=OFF \ + -DCMAKE_PREFIX_PATH=${{ env.ORTOOLS_DIR }}/install - name: Build run: | @@ -138,3 +158,11 @@ jobs: tag: ${{ github.event.inputs.release_tag }} run: | gh release upload "$tag" _build/*.tar.gz _build/*.rpm + + - name: Cache vcpkg binary dir + if: always() + id: save-cache-vcpkg-binary + uses: actions/cache/save@v3 + with: + path: ${{ env.VCPKG_CACHE_DIR }} + key: vcpkg-cache-oracle8-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 9c061abe15..cf326c2d72 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -15,12 +15,26 @@ jobs: env: SONAR_SERVER_URL: "https://sonarcloud.io" ORTOOLS_DIR: ${{ github.workspace }}/or-tools + # Caching strategy of VCPKG dependencies + VCPKG_BINARY_SOURCES: "clear;files,${{ github.workspace }}/vcpkg_cache,readwrite" steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Install VCPKG + run: git submodule update --init vcpkg && ./vcpkg/bootstrap-vcpkg.sh -disableMetrics + + - name: Restore vcpkg binary dir from cache + id: cache-vcpkg-binary + uses: actions/cache/restore@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-cache-ubuntu-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} + # Allows to restore a cache when deps have only partially changed (like adding a dependency) + restore-keys: vcpkg-cache-ubuntu- + - name: Config OR-Tools URL run: | echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV @@ -81,6 +95,8 @@ jobs: -DCMAKE_C_COMPILER=/usr/bin/gcc-10 \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 \ + -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ -DDEPS_INSTALL_DIR=./rte-antares-deps-Debug \ -DCODE_COVERAGE=ON \ -DCMAKE_BUILD_TYPE=Debug \ @@ -109,3 +125,11 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" + + - name: Cache vcpkg binary dir + if: always() + id: save-cache-vcpkg-binary + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-cache-ubuntu-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 0ee8848977..2de211c08c 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -40,6 +40,8 @@ jobs: env: ORTOOLS_DIR: ${{ github.workspace }}/or-tools os: ubuntu-20.04 + # Caching strategy of VCPKG dependencies + VCPKG_BINARY_SOURCES: "clear;files,${{ github.workspace }}/vcpkg_cache,readwrite" runs-on: ubuntu-20.04 if: "!contains(github.event.head_commit.message, '[skip ci]')" @@ -49,6 +51,18 @@ jobs: with: ref: ${{ env.REF }} + - name: Install VCPKG + run: git submodule update --init vcpkg && ./vcpkg/bootstrap-vcpkg.sh -disableMetrics + + - name: Restore vcpkg binary dir from cache + id: cache-vcpkg-binary + uses: actions/cache/restore@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-cache-ubuntu-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} + # Allows to restore a cache when deps have only partially changed (like adding a dependency) + restore-keys: vcpkg-cache-ubuntu- + - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: @@ -78,9 +92,9 @@ jobs: - name: Install libraries run: | - sudo apt-get update - sudo apt-get install uuid-dev libwxgtk3.0-gtk3-dev - sudo apt-get install g++-10 gcc-10 + sudo apt-get update + sudo apt-get install uuid-dev libwxgtk3.0-gtk3-dev + sudo apt-get install g++-10 gcc-10 - name: export wxWidgets script shell: bash @@ -135,26 +149,25 @@ jobs: - name: Configure run: | - cmake -B _build -S src \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DVCPKG_ROOT="${{env.VCPKG_ROOT}}" \ - -DVCPKG_TARGET_TRIPLET=${{ env.triplet }} \ - -DCMAKE_C_COMPILER=/usr/bin/gcc-10 \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 \ - -DDEPS_INSTALL_DIR=${{github.workspace}}/rte-antares-deps-Release \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=ON \ - -DBUILD_not_system=OFF \ - -DBUILD_TOOLS=ON \ - -DCMAKE_PREFIX_PATH=${{ env.ORTOOLS_DIR }}/install \ - -DPython3_EXECUTABLE="${{ env.Python3_ROOT_DIR }}/bin/python" + cmake -B _build -S src \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_C_COMPILER=/usr/bin/gcc-10 \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 \ + -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ + -DDEPS_INSTALL_DIR=${{github.workspace}}/rte-antares-deps-Release \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DBUILD_not_system=OFF \ + -DBUILD_TOOLS=ON \ + -DCMAKE_PREFIX_PATH=${{ env.ORTOOLS_DIR }}/install \ + -DPython3_EXECUTABLE="${{ env.Python3_ROOT_DIR }}/bin/python" - name: Build run: | cmake --build _build -j$(nproc) - # simtest - name: Read simtest version id: simtest-version @@ -338,3 +351,11 @@ jobs: tag: ${{ github.event.inputs.release_tag }} run: | gh release upload "$tag" _build/*.tar.gz _build/*.deb + + - name: Cache vcpkg binary dir + if: always() + id: save-cache-vcpkg-binary + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-cache-ubuntu-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index 04d9f72c53..4eb484b8d0 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -39,307 +39,302 @@ jobs: ORTOOLS_DIR: ${{ github.workspace }}/or-tools os: windows-latest test-platform: windows-2022 - vcpkgPackages: wxwidgets boost-test yaml-cpp antlr4 - triplet: x64-windows + vcpkgPackages: wxwidgets boost-test + triplet: x64-windows-release + # Caching strategy of VCPKG dependencies + VCPKG_BINARY_SOURCES: "clear;files,${{ github.workspace }}/vcpkg_cache,readwrite" runs-on: windows-latest steps: - - uses: actions/checkout@v4 - with: - ref: ${{ env.REF }} + - uses: actions/checkout@v4 + with: + ref: ${{ env.REF }} - - name: Config OR-Tools URL - run: | + - name: Config OR-Tools URL + run: | echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_windows-latest_static_sirius.zip" >> $GITHUB_ENV - shell: bash + shell: bash - - name: Pre-requisites - shell: cmd - run: | + - name: Pre-requisites + shell: cmd + run: | choco install wget unzip zip --no-progress - # Downloads ccache, and copies it to "cl.exe" in order to trick cmake into using it, - # see ccache wiki for background on using it with MSVC: - # https://github.com/ccache/ccache/wiki/MS-Visual-Studio - - name: Install ccache - shell: bash - run: | - wget https://github.com/ccache/ccache/releases/download/v4.8.3/ccache-4.8.3-windows-x86_64.zip -O ccache.zip - unzip ccache.zip - rm ccache.zip - mv ccache-4.8.3-windows-x86_64 ccache - cp ccache/ccache.exe ccache/cl.exe - echo "${GITHUB_WORKSPACE}/ccache" >> $GITHUB_PATH - - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: windows - - - name : Init VCPKG submodule - run: | - git submodule update --init vcpkg - - # Restore both vcpkg and its artifacts from the GitHub cache service. - - name: Restore vcpkg and its artifacts. - uses: actions/cache@v4 - with: - # The first path is the location of vcpkg (it contains the vcpkg executable and data files). - # The other paths starting with '!' are exclusions: they contain temporary files generated during the build of the installed packages. - path: | - ${{ env.VCPKG_ROOT }} - !${{ env.VCPKG_ROOT }}/buildtrees - !${{ env.VCPKG_ROOT }}/packages - !${{ env.VCPKG_ROOT }}/downloads - # The key is composed in a way that it gets properly invalidated: this must happen whenever vcpkg's Git commit id changes, or the list of packages changes. In this case a cache miss must happen and a new entry with a new key with be pushed to GitHub the cache service. - # The key includes: hash of the vcpkg.json file, the hash of the vcpkg Git commit id, and the used vcpkg's triplet. The vcpkg's commit id would suffice, but computing an hash out it does not harm. - # Note: given a key, the cache content is immutable. If a cache entry has been created improperly, in order the recreate the right content the key must be changed as well, and it must be brand new (i.e. not existing already). - key: | - ${{ hashFiles( 'vcpkg_manifest/vcpkg.json' ) }}-${{ hashFiles( '.git/modules/vcpkg/HEAD' )}}-${{ env.triplet }} - - - name : Install deps with VCPKG - run: | - cd vcpkg - ./bootstrap-vcpkg.sh - vcpkg install ${{env.vcpkgPackages}} --triplet ${{env.triplet}} - rm -rf buildtrees packages downloads - shell: bash - - - name: Read antares-deps version - id: antares-deps-version - uses: notiz-dev/github-action-json-property@release - with: - path: 'antares-deps-version.json' - prop_path: 'antares_deps_version' - - - name: Download pre-compiled librairies - uses: ./.github/workflows/download-extract-precompiled-libraries-zip - with: - antares-deps-version: ${{steps.antares-deps-version.outputs.prop}} - os: ${{env.os}} - ortools-url: ${{env.ORTOOLS_URL}} - ortools-dir: ${{env.ORTOOLS_DIR}} - - - name: Setup Python 3.12 - uses: actions/setup-python@v5 - id: setup-python - with: - architecture: 'x64' - python-version: '3.12' - - - name: Install pip dependencies if necessary - run: pip install -r src/tests/examples/requirements.txt - - - name: Init submodule - run: | - git submodule update --init src/antares-deps - git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests - - - name: Enable git longpaths - run: git config --system core.longpaths true - - - name: Configure - shell: bash - run: | - cmake -B _build -S src \ - -DDEPS_INSTALL_DIR=rte-antares-deps-Release \ - -DCMAKE_PREFIX_PATH="${{ env.ORTOOLS_DIR }}/install" \ - -DVCPKG_ROOT="${{env.VCPKG_ROOT}}" \ - -DVCPKG_TARGET_TRIPLET=${{ env.triplet }} \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=ON \ - -DBUILD_TOOLS=ON \ - -DBUILD_not_system=OFF \ - -DPython3_EXECUTABLE="${{ env.Python3_ROOT_DIR }}/python.exe" \ - -DCMAKE_VS_GLOBALS="CLToolExe=cl.exe;CLToolPath=${GITHUB_WORKSPACE}/ccache;TrackFileAccess=false;UseMultiToolTask=true;DebugInformationFormat=OldStyle" - - - name: Build - shell: bash - run: | - cmake --build _build --config Release -j$(nproc) - # simtest - - name: Read simtest version - id: simtest-version - uses: notiz-dev/github-action-json-property@release - with: - path: 'simtest.json' - prop_path: 'version' - - - name: Run named mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-named-mps - os: ${{ env.test-platform }} - variant: "named-mps" - - - name: Run unfeasibility-related tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - run: | - cd _build - ctest -C Release --output-on-failure -R "^unfeasible$" - - - name: Run unit and end-to-end tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - run: | - cd _build - ctest -C Release --output-on-failure -L "unit|end-to-end" -LE ortools - - - name: Upload build on failure - if: ${{ failure() }} - uses: actions/upload-artifact@v4 - with: - name: MPS-diff - path: ${{ github.workspace }}/src/tests/mps - - - - name: Run tests for adequacy patch (CSR) - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: adequacy-patch-CSR - os: ${{ env.test-platform }} - - - name: Run tests about infinity on BCs RHS - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-v830 - os: ${{ env.test-platform }} - - - name: Run MILP with CBC - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-milp - variant: "milp-cbc" - os: ${{ env.test-platform }} - - - name: Run tests introduced in v860 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-v860 - os: ${{ env.test-platform }} - - - name: Run tests introduced in v870 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-v870 - os: ${{ env.test-platform }} - - - name: Run tests introduced in v910 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-v910 - os: ${{ env.test-platform }} - - - name: Run short-tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: short-tests - os: ${{ env.test-platform }} - - - name: Run mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-mps - os: ${{ env.test-platform }} - - - name: Run parallel tests - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-parallel - os: ${{ env.test-platform }} - variant: "parallel" - - - name: Run medium-tests - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: medium-tests - os: ${{ env.test-platform }} - - - name: Run long-tests-1 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: long-tests-1 - os: ${{ env.test-platform }} - - - name: Run long-tests-2 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: long-tests-2 - os: ${{ env.test-platform }} - - - name: Run long-tests-3 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: long-tests-3 - os: ${{ env.test-platform }} - - - name: Solver archive creation - shell: bash - run: | - cd _build - zip -r antares-solver_windows.zip solver/Release/antares-solver.exe solver/Release/*.dll - - - name: NSIS Installer creation - shell: bash - run: | - rm -rf src/tests/resources/Antares_Simulator_Tests - cd _build - cpack -GNSIS - export NSIS_NAME=$(ls *.exe) - echo "NSIS_NAME=$NSIS_NAME" >> $GITHUB_ENV - - - name: Upload NSIS log on failure - if: ${{ failure() }} - uses: actions/upload-artifact@v4 - with: - name: NSISError.log - path: _build/_CPack_Packages/win64/NSIS/NSISOutput.log - - - name: .zip creation - run: | - cd _build - cpack -G ZIP - - - name: Installer upload - uses: actions/upload-artifact@v4 - with: - name: installer - path: _build/${{env.NSIS_NAME}} - - - name: Publish assets - if: ${{ env.IS_RELEASE == 'true' }} - env: - GITHUB_TOKEN: ${{ github.token }} - tag: ${{ github.event.inputs.release_tag }} - run: | - gh release upload "$tag" _build/*.zip _build/*.exe - shell: bash + # Downloads ccache, and copies it to "cl.exe" in order to trick cmake into using it, + # see ccache wiki for background on using it with MSVC: + # https://github.com/ccache/ccache/wiki/MS-Visual-Studio + - name: Install ccache + shell: bash + run: | + wget https://github.com/ccache/ccache/releases/download/v4.8.3/ccache-4.8.3-windows-x86_64.zip -O ccache.zip + unzip ccache.zip + rm ccache.zip + mv ccache-4.8.3-windows-x86_64 ccache + cp ccache/ccache.exe ccache/cl.exe + echo "${GITHUB_WORKSPACE}/ccache" >> $GITHUB_PATH + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: windows + + - name: Install VCPKG + shell: bash + run: | + git submodule update --init vcpkg && ./vcpkg/bootstrap-vcpkg.bat -disableMetrics + + - name: Restore vcpkg binary dir from cache + id: cache-vcpkg-binary + uses: actions/cache/restore@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-cache-windows-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} + # Allows to restore a cache when deps have only partially changed (like adding a dependency) + restore-keys: vcpkg-cache-windows- + + - name: Read antares-deps version + id: antares-deps-version + uses: notiz-dev/github-action-json-property@release + with: + path: 'antares-deps-version.json' + prop_path: 'antares_deps_version' + + - name: Download pre-compiled librairies + uses: ./.github/workflows/download-extract-precompiled-libraries-zip + with: + antares-deps-version: ${{steps.antares-deps-version.outputs.prop}} + os: ${{env.os}} + ortools-url: ${{env.ORTOOLS_URL}} + ortools-dir: ${{env.ORTOOLS_DIR}} + + - name: Setup Python 3.12 + uses: actions/setup-python@v5 + id: setup-python + with: + architecture: 'x64' + python-version: '3.12' + + - name: Install pip dependencies if necessary + run: pip install -r src/tests/examples/requirements.txt + + - name: Init submodule + run: | + git submodule update --init src/antares-deps + git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests + + - name: Enable git longpaths + run: git config --system core.longpaths true + + - name: Configure + shell: bash + run: | + cmake -B _build -S src \ + -DDEPS_INSTALL_DIR=rte-antares-deps-Release \ + -DCMAKE_PREFIX_PATH="${{ env.ORTOOLS_DIR }}/install" \ + -DVCPKG_ROOT="${{env.VCPKG_ROOT}}" \ + -DVCPKG_TARGET_TRIPLET=${{ env.triplet }} \ + -DCMAKE_TOOLCHAIN_FILE="${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake" \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DBUILD_TOOLS=ON \ + -DBUILD_not_system=OFF \ + -DPython3_EXECUTABLE="${{ env.Python3_ROOT_DIR }}/python.exe" \ + -DCMAKE_VS_GLOBALS="CLToolExe=cl.exe;CLToolPath=${GITHUB_WORKSPACE}/ccache;TrackFileAccess=false;UseMultiToolTask=true;DebugInformationFormat=OldStyle" + + - name: Build + shell: bash + run: | + cmake --build _build --config Release -j$(nproc) + # simtest + - name: Read simtest version + id: simtest-version + uses: notiz-dev/github-action-json-property@release + with: + path: 'simtest.json' + prop_path: 'version' + + - name: Run named mps tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-named-mps + os: ${{ env.test-platform }} + variant: "named-mps" + + - name: Run unfeasibility-related tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + run: | + cd _build + ctest -C Release --output-on-failure -R "^unfeasible$" + + - name: Run unit and end-to-end tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + run: | + cd _build + ctest -C Release --output-on-failure -L "unit|end-to-end" -LE ortools + + - name: Upload build on failure + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: MPS-diff + path: ${{ github.workspace }}/src/tests/mps + + - name: Run tests for adequacy patch (CSR) + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: adequacy-patch-CSR + os: ${{ env.test-platform }} + + - name: Run tests about infinity on BCs RHS + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-v830 + os: ${{ env.test-platform }} + + - name: Run MILP with CBC + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-milp + variant: "milp-cbc" + os: ${{ env.test-platform }} + + - name: Run tests introduced in v860 + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-v860 + os: ${{ env.test-platform }} + + - name: Run tests introduced in v870 + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-v870 + os: ${{ env.test-platform }} + + - name: Run tests introduced in v910 + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-v910 + os: ${{ env.test-platform }} + + - name: Run short-tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: short-tests + os: ${{ env.test-platform }} + + - name: Run mps tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-mps + os: ${{ env.test-platform }} + + - name: Run parallel tests + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-parallel + os: ${{ env.test-platform }} + variant: "parallel" + + - name: Run medium-tests + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: medium-tests + os: ${{ env.test-platform }} + + - name: Run long-tests-1 + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: long-tests-1 + os: ${{ env.test-platform }} + + - name: Run long-tests-2 + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: long-tests-2 + os: ${{ env.test-platform }} + + - name: Run long-tests-3 + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: long-tests-3 + os: ${{ env.test-platform }} + + - name: Solver archive creation + shell: bash + run: | + cd _build + zip -r antares-solver_windows.zip solver/Release/antares-solver.exe solver/Release/*.dll + + - name: NSIS Installer creation + shell: bash + run: | + rm -rf src/tests/resources/Antares_Simulator_Tests + cd _build + cpack -GNSIS + export NSIS_NAME=$(ls *.exe) + echo "NSIS_NAME=$NSIS_NAME" >> $GITHUB_ENV + + - name: Upload NSIS log on failure + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: NSISError.log + path: _build/_CPack_Packages/win64/NSIS/NSISOutput.log + + - name: .zip creation + run: | + cd _build + cpack -G ZIP + + - name: Installer upload + uses: actions/upload-artifact@v4 + with: + name: installer + path: _build/${{env.NSIS_NAME}} + + - name: Publish assets + if: ${{ env.IS_RELEASE == 'true' }} + env: + GITHUB_TOKEN: ${{ github.token }} + tag: ${{ github.event.inputs.release_tag }} + run: | + gh release upload "$tag" _build/*.zip _build/*.exe + shell: bash + + - name: Cache vcpkg binary dir + if: always() + id: save-cache-vcpkg-binary + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-cache-windows-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index adfa646d54..763c40cb96 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -260,10 +260,6 @@ if (NOT sirius_solver_FOUND) message (FATAL_ERROR "Sirius solver not found. Sirius solver can be compiled with -DBUILD_sirius=ON or you can specify previous dependency install directory with -DCMAKE_PREFIX_PATH or -DDEPS_INSTALL_DIR") endif() -#gflags needed for ortools -set(GFLAGS_USE_TARGET_NAMESPACE TRUE) -find_package(gflags) - find_package(ortools) if(NOT ortools_FOUND OR BUILD_ORTOOLS) message(STATUS "OR-Tools tag ${ORTOOLS_TAG}") @@ -290,36 +286,17 @@ message(STATUS "OR-Tools tag ${ORTOOLS_TAG}") FetchContent_MakeAvailable(ortools) endif() -find_package(minizip QUIET) - -if(NOT minizip_FOUND OR BUILD_MINIZIP) - if (NOT minizip_FOUND) - message("minizip not found, downloading") +find_package(minizip-ng) +if (minizip-ng_FOUND) + add_library(MINIZIP::minizip ALIAS MINIZIP::minizip-ng) +else () + find_package(minizip) + if (minizip_FOUND) + message (STATUS "Found minizip (not minizip-ng).") + else () + message (FATAL_ERROR "Minizip not found.") endif () - if (BUILD_MINIZIP) - message("BUILD_MINIZIP set, downloading") - endif () - # Repository + tag - set(MZ_REPOSITORY "https://github.com/zlib-ng/minizip-ng.git") - set(MZ_TAG "4.0.1") - # CMake flags - set(MZ_LZMA "OFF" CACHE INTERNAL "") - set(MZ_ZSTD "OFF" CACHE INTERNAL "") - set(MZ_BZIP2 "OFF" CACHE INTERNAL "") - set(MZ_PKCRYPT "OFF" CACHE INTERNAL "") - set(MZ_WZAES "OFF" CACHE INTERNAL "") - set(MZ_OPENSSL "OFF" CACHE INTERNAL "") - set(MZ_ICONV "OFF" CACHE INTERNAL "") - - FetchContent_Declare(minizip - GIT_REPOSITORY ${MZ_REPOSITORY} - GIT_TAG ${MZ_TAG} - OVERRIDE_FIND_PACKAGE - ) - - FetchContent_MakeAvailable(minizip) -endif() -find_package(minizip REQUIRED) +endif () #wxWidget not needed for all library find is done in ui CMakeLists.txt diff --git a/src/cmake/wxWidgets/FindwxWidgets.cmake b/src/cmake/wxWidgets/FindwxWidgets.cmake index dea003dce6..c174be3ed7 100644 --- a/src/cmake/wxWidgets/FindwxWidgets.cmake +++ b/src/cmake/wxWidgets/FindwxWidgets.cmake @@ -820,7 +820,6 @@ else() find_program(wxWidgets_CONFIG_EXECUTABLE NAMES $ENV{WX_CONFIG} wx-config wx-config-3.1 wx-config-3.0 wx-config-2.9 wx-config-2.8 DOC "Location of wxWidgets library configuration provider binary (wx-config)." - ONLY_CMAKE_FIND_ROOT_PATH ) if(wxWidgets_CONFIG_EXECUTABLE) diff --git a/src/libs/antares/writer/CMakeLists.txt b/src/libs/antares/writer/CMakeLists.txt index 21ddd81ba4..9795f6ace4 100644 --- a/src/libs/antares/writer/CMakeLists.txt +++ b/src/libs/antares/writer/CMakeLists.txt @@ -1,5 +1,4 @@ project(result-writer) -find_package(minizip) add_library(result_writer # Helper class diff --git a/src/packaging/Config.cmake.in b/src/packaging/Config.cmake.in index be7a1a62fa..2cbf63a275 100644 --- a/src/packaging/Config.cmake.in +++ b/src/packaging/Config.cmake.in @@ -1,8 +1,16 @@ @PACKAGE_INIT@ include(CMakeFindDependencyMacro) -find_dependency(ortools) -find_dependency(minizip) +find_dependency(ortools REQUIRED) +find_dependency(minizip-ng) +if (minizip-ng_FOUND) + add_library(MINIZIP::minizip ALIAS MINIZIP::minizip-ng) +else () + find_dependency(minizip) + if (NOT minizip_FOUND) + message (FATAL_ERROR "Minizip dependency (minizip or minizip-ng) not found.") + endif () +endif () include("${CMAKE_CURRENT_LIST_DIR}/AntaresTargets.cmake") diff --git a/src/tests/end-to-end/binding_constraints/test_binding_constraints.cpp b/src/tests/end-to-end/binding_constraints/test_binding_constraints.cpp index a40157091a..c1b875378f 100644 --- a/src/tests/end-to-end/binding_constraints/test_binding_constraints.cpp +++ b/src/tests/end-to-end/binding_constraints/test_binding_constraints.cpp @@ -1,25 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ -#include // Fix for Boost < 1.67 - + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test - end - to - end tests_binding_constraints #define WIN32_LEAN_AND_MEAN #include diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index 5c9181ddbf..e5813befd8 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -1,25 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ -#include // Fix for Boost < 1.67 - + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test - end - to - end tests #include #include diff --git a/src/tests/src/libs/antares/array/tests-matrix-load.cpp b/src/tests/src/libs/antares/array/tests-matrix-load.cpp index 1dfecf1517..2c427890eb 100644 --- a/src/tests/src/libs/antares/array/tests-matrix-load.cpp +++ b/src/tests/src/libs/antares/array/tests-matrix-load.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test - lib - antares - matrix tests #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/array/tests-matrix-save.cpp b/src/tests/src/libs/antares/array/tests-matrix-save.cpp index 13560a047e..d1af11d387 100644 --- a/src/tests/src/libs/antares/array/tests-matrix-save.cpp +++ b/src/tests/src/libs/antares/array/tests-matrix-save.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test - lib - antares - matrix tests #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/benchmarking/test_duration_collector.cpp b/src/tests/src/libs/antares/benchmarking/test_duration_collector.cpp index d213dc64d5..4fc74bcda9 100644 --- a/src/tests/src/libs/antares/benchmarking/test_duration_collector.cpp +++ b/src/tests/src/libs/antares/benchmarking/test_duration_collector.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test - benchmarking #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/concurrency/test_concurrency.cpp b/src/tests/src/libs/antares/concurrency/test_concurrency.cpp index 26923159c7..c1188c7a9d 100644 --- a/src/tests/src/libs/antares/concurrency/test_concurrency.cpp +++ b/src/tests/src/libs/antares/concurrency/test_concurrency.cpp @@ -1,27 +1,24 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ -#include // Fix for Boost < 1.67 - + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test - concurrency tests - #include #include diff --git a/src/tests/src/libs/antares/study/area/test-save-area-optimization-ini.cpp b/src/tests/src/libs/antares/study/area/test-save-area-optimization-ini.cpp index 40fcb4b5fd..77672b88c2 100644 --- a/src/tests/src/libs/antares/study/area/test-save-area-optimization-ini.cpp +++ b/src/tests/src/libs/antares/study/area/test-save-area-optimization-ini.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test save area optimization.ini #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/area/test-save-link-properties.cpp b/src/tests/src/libs/antares/study/area/test-save-link-properties.cpp index af30689f4b..305241cd3e 100644 --- a/src/tests/src/libs/antares/study/area/test-save-link-properties.cpp +++ b/src/tests/src/libs/antares/study/area/test-save-link-properties.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test save link properties.ini #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/constraint/test_constraint.cpp b/src/tests/src/libs/antares/study/constraint/test_constraint.cpp index 25322ae361..e6e5cd54c3 100644 --- a/src/tests/src/libs/antares/study/constraint/test_constraint.cpp +++ b/src/tests/src/libs/antares/study/constraint/test_constraint.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ // // Created by marechaljas on 13/03/23. // diff --git a/src/tests/src/libs/antares/study/constraint/test_group.cpp b/src/tests/src/libs/antares/study/constraint/test_group.cpp index 3e87707fe2..21f5c7377a 100644 --- a/src/tests/src/libs/antares/study/constraint/test_group.cpp +++ b/src/tests/src/libs/antares/study/constraint/test_group.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ // // Created by marechaljas on 28/06/23. // diff --git a/src/tests/src/libs/antares/study/output-folder/study.cpp b/src/tests/src/libs/antares/study/output-folder/study.cpp index eba613c781..1675ae7909 100644 --- a/src/tests/src/libs/antares/study/output-folder/study.cpp +++ b/src/tests/src/libs/antares/study/output-folder/study.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE output folder #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp b/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp index 3dde6f5784..f690649668 100644 --- a/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp +++ b/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE "test parameters" #include diff --git a/src/tests/src/libs/antares/study/parts/hydro/test-hydro-series.cpp b/src/tests/src/libs/antares/study/parts/hydro/test-hydro-series.cpp index 9e28c98df0..d534ca7d53 100644 --- a/src/tests/src/libs/antares/study/parts/hydro/test-hydro-series.cpp +++ b/src/tests/src/libs/antares/study/parts/hydro/test-hydro-series.cpp @@ -1,3 +1,24 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + #define BOOST_TEST_MODULE test hydro series #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/parts/hydro/test-hydroreader-class.cpp b/src/tests/src/libs/antares/study/parts/hydro/test-hydroreader-class.cpp index a933b5a3c0..cf519c3cb7 100644 --- a/src/tests/src/libs/antares/study/parts/hydro/test-hydroreader-class.cpp +++ b/src/tests/src/libs/antares/study/parts/hydro/test-hydroreader-class.cpp @@ -1,3 +1,24 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + #define BOOST_TEST_MODULE test hydro reader #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp index 003a24b22a..36346b2014 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test read scenario - builder.dat #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp index b0fd157f03..e1b0666b7d 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test save scenario - builder.dat #include #include diff --git a/src/tests/src/libs/antares/study/series/timeseries-tests.cpp b/src/tests/src/libs/antares/study/series/timeseries-tests.cpp index 4e49aea134..4908d10601 100644 --- a/src/tests/src/libs/antares/study/series/timeseries-tests.cpp +++ b/src/tests/src/libs/antares/study/series/timeseries-tests.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE "test time series" #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp index fed4f02570..83965049e6 100644 --- a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp +++ b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE "test short term storage" #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/test_study.cpp b/src/tests/src/libs/antares/study/test_study.cpp index 77c30ed914..104b304c0e 100644 --- a/src/tests/src/libs/antares/study/test_study.cpp +++ b/src/tests/src/libs/antares/study/test_study.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE study #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/study/thermal-price-definition/thermal-price-definition.cpp b/src/tests/src/libs/antares/study/thermal-price-definition/thermal-price-definition.cpp index e2473fc986..cfef5909e5 100644 --- a/src/tests/src/libs/antares/study/thermal-price-definition/thermal-price-definition.cpp +++ b/src/tests/src/libs/antares/study/thermal-price-definition/thermal-price-definition.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE "test thermal price definition" #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/libs/antares/test_utils.cpp b/src/tests/src/libs/antares/test_utils.cpp index 9e101e34a3..ad7e97d833 100644 --- a/src/tests/src/libs/antares/test_utils.cpp +++ b/src/tests/src/libs/antares/test_utils.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test utils #include diff --git a/src/tests/src/libs/antares/writer/CMakeLists.txt b/src/tests/src/libs/antares/writer/CMakeLists.txt index 6487355a81..b85bcce05c 100644 --- a/src/tests/src/libs/antares/writer/CMakeLists.txt +++ b/src/tests/src/libs/antares/writer/CMakeLists.txt @@ -2,11 +2,11 @@ add_executable(test-writer test_writer.cpp) target_link_libraries(test-writer - PRIVATE - Boost::unit_test_framework - Antares::result_writer - test_utils_unit - MINIZIP::minizip + PRIVATE + Boost::unit_test_framework + Antares::result_writer + test_utils_unit + MINIZIP::minizip ) set_target_properties(test-writer PROPERTIES FOLDER Unit-tests/test-writer) diff --git a/src/tests/src/libs/antares/writer/test_writer.cpp b/src/tests/src/libs/antares/writer/test_writer.cpp index 3a87905607..e3af61cc44 100644 --- a/src/tests/src/libs/antares/writer/test_writer.cpp +++ b/src/tests/src/libs/antares/writer/test_writer.cpp @@ -1,25 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ -#include // Fix for Boost < 1.67 - + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test - writer tests #include #include diff --git a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp index 8d56ec12f2..d333f5104c 100644 --- a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp +++ b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp @@ -18,8 +18,6 @@ * You should have received a copy of the Mozilla Public Licence 2.0 * along with Antares_Simulator. If not, see . */ -#include // Fix for Boost < 1.67 - #define WIN32_LEAN_AND_MEAN #define BOOST_TEST_MODULE unfeasible_problem_analyzer diff --git a/src/tests/src/solver/optimisation/adequacy_patch.cpp b/src/tests/src/solver/optimisation/adequacy_patch.cpp index 6234cc1c65..377969fd5d 100644 --- a/src/tests/src/solver/optimisation/adequacy_patch.cpp +++ b/src/tests/src/solver/optimisation/adequacy_patch.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test adequacy patch functions #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/solver/simulation/test-store-timeseries-number.cpp b/src/tests/src/solver/simulation/test-store-timeseries-number.cpp index 1524b26627..16cbb59fc2 100644 --- a/src/tests/src/solver/simulation/test-store-timeseries-number.cpp +++ b/src/tests/src/solver/simulation/test-store-timeseries-number.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ // // Created by marechaljas on 15/03/23. // diff --git a/src/tests/src/solver/simulation/test-time_series.cpp b/src/tests/src/solver/simulation/test-time_series.cpp index 5c9fdfa942..42f1fbddf4 100644 --- a/src/tests/src/solver/simulation/test-time_series.cpp +++ b/src/tests/src/solver/simulation/test-time_series.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ // // Created by marechaljas on 07/04/23. // diff --git a/src/tests/src/solver/simulation/tests-ts-numbers.cpp b/src/tests/src/solver/simulation/tests-ts-numbers.cpp index a6ecf820c1..e82d432121 100644 --- a/src/tests/src/solver/simulation/tests-ts-numbers.cpp +++ b/src/tests/src/solver/simulation/tests-ts-numbers.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test solver simulation things #define WIN32_LEAN_AND_MEAN diff --git a/src/tests/src/solver/utils/basis_status.cpp b/src/tests/src/solver/utils/basis_status.cpp index b4994b28dc..292dc56c3c 100644 --- a/src/tests/src/solver/utils/basis_status.cpp +++ b/src/tests/src/solver/utils/basis_status.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define BOOST_TEST_MODULE test adequacy patch functions #define WIN32_LEAN_AND_MEAN diff --git a/src/triplets/x64-linux-antares.cmake b/src/triplets/x64-linux-antares.cmake new file mode 100644 index 0000000000..63954c80c5 --- /dev/null +++ b/src/triplets/x64-linux-antares.cmake @@ -0,0 +1,5 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE static) + diff --git a/src/triplets/x64-linux-release.cmake b/src/triplets/x64-linux-release.cmake new file mode 100644 index 0000000000..d9eb98ddae --- /dev/null +++ b/src/triplets/x64-linux-release.cmake @@ -0,0 +1,7 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE static) + +# Avoid building debug artifacts +set(VCPKG_BUILD_TYPE release) diff --git a/src/triplets/x64-windows-antares.cmake b/src/triplets/x64-windows-antares.cmake new file mode 100644 index 0000000000..f2480f7012 --- /dev/null +++ b/src/triplets/x64-windows-antares.cmake @@ -0,0 +1,11 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE dynamic) + +# Link zlib and minizip statically +list(APPEND STATIC_PORTS "zlib.*" "minizip.*") +foreach (STATIC_PORT IN LISTS STATIC_PORTS) + if(PORT MATCHES ${STATIC_PORT}) + set(VCPKG_LIBRARY_LINKAGE static) + endif() +endforeach () diff --git a/src/triplets/x64-windows-release.cmake b/src/triplets/x64-windows-release.cmake new file mode 100644 index 0000000000..7e4eb27f4d --- /dev/null +++ b/src/triplets/x64-windows-release.cmake @@ -0,0 +1,15 @@ +set(VCPKG_TARGET_ARCHITECTURE x64) + +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE dynamic) + +# Avoid building debug artifacts +set(VCPKG_BUILD_TYPE release) + +# Link zlib and minizip statically +list(APPEND STATIC_PORTS "zlib.*" "minizip.*") +foreach (STATIC_PORT IN LISTS STATIC_PORTS) + if(PORT MATCHES ${STATIC_PORT}) + set(VCPKG_LIBRARY_LINKAGE static) + endif() +endforeach () diff --git a/src/vcpkg.json b/src/vcpkg.json new file mode 100644 index 0000000000..f15f208a42 --- /dev/null +++ b/src/vcpkg.json @@ -0,0 +1,32 @@ +{ + "name": "antares-simulator", + "version-string": "9.1.0", + "builtin-baseline": "9484a57dd560b89f0a583be08af6753611c57fd5", + "vcpkg-configuration": { + "overlay-triplets": [ + "./triplets" + ] + }, + "dependencies": [ + { + "name": "wxwidgets", + "platform": "windows" + }, + { + "name": "boost-test", + "version>=": "1.81.0" + }, + { + "name": "boost-algorithm", + "version>=": "1.81.0" + }, + { + "name": "minizip-ng", + "default-features": false, + "version>=": "4.0.0", + "features": [ + "zlib" + ] + } + ] +} diff --git a/vcpkg_manifest/vcpkg.json b/vcpkg_manifest/vcpkg.json deleted file mode 100644 index 15837160b1..0000000000 --- a/vcpkg_manifest/vcpkg.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "antares-simulator", - "version-string": "8.5.0", - "dependencies": [ - "wxwidgets", - "boost-test" - ] -} \ No newline at end of file From 69cf48652880dd097ec4f63aef8c73577390911d Mon Sep 17 00:00:00 2001 From: abdoulbari zaher <32519851+a-zakir@users.noreply.github.com> Date: Fri, 31 May 2024 09:17:32 +0200 Subject: [PATCH 002/127] Fix PDF generation for useguide (#2134) --- docs/user-guide/03-getting_started.md | 4 ++-- docs/user-guide/04-migration-guides.md | 2 +- docs/user-guide/other-features/analyzer.md | 9 ++++--- docs/user-guide/other-features/batchrun.md | 4 ++-- docs/user-guide/other-features/config.md | 2 -- .../kirchhoff-constraints-builder.md | 2 -- .../other-features/study-cleaner.md | 3 +-- .../user-guide/other-features/study-finder.md | 2 -- .../other-features/study-updater.md | 2 -- .../user-guide/other-features/ui-simulator.md | 2 -- docs/user-guide/other-features/vacuum.md | 2 -- .../other-features/ybyaggregator.md | 2 -- docs/user-guide/solver/00-index.md | 2 +- .../{01-overview.md => 01-overview-solver.md} | 0 docs/user-guide/solver/02-inputs.md | 2 +- docs/user-guide/solver/04-parameters.md | 10 ++++---- .../user-guide/solver/07-thermal-heuristic.md | 24 +++++++++---------- docs/user-guide/ts-generator/00-index.md | 2 +- ...overview.md => 01-overview-tsgenerator.md} | 0 docs/user-guide/ts-generator/04-parameters.md | 2 +- 20 files changed, 33 insertions(+), 45 deletions(-) rename docs/user-guide/solver/{01-overview.md => 01-overview-solver.md} (100%) rename docs/user-guide/ts-generator/{01-overview.md => 01-overview-tsgenerator.md} (100%) diff --git a/docs/user-guide/03-getting_started.md b/docs/user-guide/03-getting_started.md index 6ceab3315b..ba4ca923a8 100644 --- a/docs/user-guide/03-getting_started.md +++ b/docs/user-guide/03-getting_started.md @@ -62,9 +62,9 @@ These steps most often involve: 2. Defining the simulation contexts (definition of the "Monte-Carlo years" to simulate) 3. *(Optional)* If some time-series are supposed to be [automatically generated](18-parameters.md#generate), running a simulation to produce actual numeric scenarios, following the directives defined in (2). - *In this step, the [ts-generator](ts-generator/01-overview.md) tool should be used.* + *In this step, the [ts-generator](ts-generator/01-overview-tsgenerator.md) tool should be used.* 4. Running the optimization, to solve all the optimization problems associated with each of the scenarios produced in (3). - *In this step, the main [solver](solver/01-overview.md) tool should be used.* + *In this step, the main [solver](solver/01-overview-solver.md) tool should be used.* 5. Exploiting the detailed [results](solver/03-outputs.md) yielded by (4). *In this step, we recommend using [Antares Web](https://antares-web.readthedocs.io) or [Antares Extensions](#using-extensions).* diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 2fda042306..354dfa692f 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -3,7 +3,7 @@ This is a list of all recent changes that came with new Antares Simulator featur ## v9.1.0 ### Input #### Hydro Maximum Generation/Pumping Power -* For time series ![Migration diagram](migration.png "Migration diagram"), for more details, see [this Python script](migration.py) +* For time series ![Migration diagram](img/migration.png "Migration diagram"), for more details, see [this Python script](img/migration.py) Regarding Hydro time-series, the scenario builder allows the user to choose, for a given year and area, a different time series whether we consider : - inflows, ROR and minimum generation, max pumping & generation (prefix "h") diff --git a/docs/user-guide/other-features/analyzer.md b/docs/user-guide/other-features/analyzer.md index 877b423332..89f79928c7 100644 --- a/docs/user-guide/other-features/analyzer.md +++ b/docs/user-guide/other-features/analyzer.md @@ -5,9 +5,12 @@ hide: # Time-Series Analyzer ---- + +**Executable**: antares-analyzer (currently released for Windows & Ubuntu only) + + > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- -**Executable**: antares-analyzer (currently released for Windows & Ubuntu only) \ No newline at end of file + + diff --git a/docs/user-guide/other-features/batchrun.md b/docs/user-guide/other-features/batchrun.md index eb6c4ead58..97e973501c 100644 --- a/docs/user-guide/other-features/batchrun.md +++ b/docs/user-guide/other-features/batchrun.md @@ -5,10 +5,10 @@ hide: # Batch Runner ---- + > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- + **Executable**: antares-batchrun (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/other-features/config.md b/docs/user-guide/other-features/config.md index b9acd22cca..6d06b1bea4 100644 --- a/docs/user-guide/other-features/config.md +++ b/docs/user-guide/other-features/config.md @@ -5,10 +5,8 @@ hide: # Config Checker ---- > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- **Executable**: antares-config (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/other-features/kirchhoff-constraints-builder.md b/docs/user-guide/other-features/kirchhoff-constraints-builder.md index e0c11c66b8..5aecd43e30 100644 --- a/docs/user-guide/other-features/kirchhoff-constraints-builder.md +++ b/docs/user-guide/other-features/kirchhoff-constraints-builder.md @@ -1,9 +1,7 @@ # Kirchhoff's constraint generator ---- > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- **Executable**: antares-kirchhoff-constraints-builder (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/other-features/study-cleaner.md b/docs/user-guide/other-features/study-cleaner.md index ad2049afc6..ff67c59f24 100644 --- a/docs/user-guide/other-features/study-cleaner.md +++ b/docs/user-guide/other-features/study-cleaner.md @@ -5,10 +5,9 @@ hide: # Study Cleaner ---- + > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- **Executable**: antares-study-cleaner (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/other-features/study-finder.md b/docs/user-guide/other-features/study-finder.md index d7e21a09f8..d681ff07a1 100644 --- a/docs/user-guide/other-features/study-finder.md +++ b/docs/user-guide/other-features/study-finder.md @@ -5,10 +5,8 @@ hide: # Study Finder ---- > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- **Executable**: antares-study-finder (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/other-features/study-updater.md b/docs/user-guide/other-features/study-updater.md index 0f6bafd87b..70b51873c3 100644 --- a/docs/user-guide/other-features/study-updater.md +++ b/docs/user-guide/other-features/study-updater.md @@ -5,10 +5,8 @@ hide: # Study Updater ---- > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- **Executable**: antares-study-updater (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/other-features/ui-simulator.md b/docs/user-guide/other-features/ui-simulator.md index f79bab5c42..2987c7f095 100644 --- a/docs/user-guide/other-features/ui-simulator.md +++ b/docs/user-guide/other-features/ui-simulator.md @@ -5,10 +5,8 @@ hide: # GUI ---- > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- **Executable**: antares-study-ui-simulator (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/other-features/vacuum.md b/docs/user-guide/other-features/vacuum.md index 42af2f9f25..25db8dacb4 100644 --- a/docs/user-guide/other-features/vacuum.md +++ b/docs/user-guide/other-features/vacuum.md @@ -5,9 +5,7 @@ hide: # Vacuum ---- > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- **Executable**: antares-vacuum (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/other-features/ybyaggregator.md b/docs/user-guide/other-features/ybyaggregator.md index 0ca3630116..aa885301d5 100644 --- a/docs/user-guide/other-features/ybyaggregator.md +++ b/docs/user-guide/other-features/ybyaggregator.md @@ -5,9 +5,7 @@ hide: # Year-by-Year Aggregator ---- > _**WARNING:**_ this feature is deprecated and will be removed in a future release. If you are still using it, > please [get in touch](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues) with us. ---- **Executable**: antares-ybyaggregator (currently released for Windows & Ubuntu only) diff --git a/docs/user-guide/solver/00-index.md b/docs/user-guide/solver/00-index.md index d9a519183b..4ef21bd614 100644 --- a/docs/user-guide/solver/00-index.md +++ b/docs/user-guide/solver/00-index.md @@ -4,7 +4,7 @@ ```{toctree} :hidden: -01-overview.md +01-overview-solver.md 02-inputs.md 03-outputs.md 04-parameters.md diff --git a/docs/user-guide/solver/01-overview.md b/docs/user-guide/solver/01-overview-solver.md similarity index 100% rename from docs/user-guide/solver/01-overview.md rename to docs/user-guide/solver/01-overview-solver.md diff --git a/docs/user-guide/solver/02-inputs.md b/docs/user-guide/solver/02-inputs.md index cf3768b7d2..287be4b797 100644 --- a/docs/user-guide/solver/02-inputs.md +++ b/docs/user-guide/solver/02-inputs.md @@ -157,7 +157,7 @@ The user may pick any area appearing in the list and is then given access to dif - The "local data" tab is used to set the parameters of the stochastic generator. These parameters are presented in four sub-tabs whose content is presented in - [Time-series analysis and generation](../ts-generator/01-overview.md). + [Time-series analysis and generation](../ts-generator/01-overview-tsgenerator.md). - The "digest" tab displays for all areas a short account of the local data diff --git a/docs/user-guide/solver/04-parameters.md b/docs/user-guide/solver/04-parameters.md index 7c0515c420..efe0e44ad4 100644 --- a/docs/user-guide/solver/04-parameters.md +++ b/docs/user-guide/solver/04-parameters.md @@ -12,7 +12,7 @@ These parameters are listed under the `[general]` section in the `.ini` file. --- ### Study mode ---- + #### mode [//]: # (TODO: verify if required, remove default value) [//]: # (TODO: add details 'expansion' behavior) @@ -36,7 +36,7 @@ These parameters are listed under the `[general]` section in the `.ini` file. --- ### Study horizon ---- + #### horizon [//]: # (TODO: verify if required, remove default value) - **Expected value:** year (string) @@ -48,7 +48,7 @@ These parameters are listed under the `[general]` section in the `.ini` file. ### Calendar parameters ---- + #### nbyears [//]: # (TODO: verify if required, verify default value) - **Expected value:** unsigned integer @@ -122,7 +122,7 @@ These parameters are listed under the `[general]` section in the `.ini` file. --- ### Additional parameters ---- + #### year-by-year - **Expected value:** `true` or `false` - **Required:** no @@ -219,7 +219,7 @@ These parameters are listed under the `[general]` section in the `.ini` file. --- ### Pre-processor parameters ---- + #### readonly [//]: # (TODO: add usage details) - **Expected value:** `true` or `false` diff --git a/docs/user-guide/solver/07-thermal-heuristic.md b/docs/user-guide/solver/07-thermal-heuristic.md index 67670a36ca..372ceb8bed 100644 --- a/docs/user-guide/solver/07-thermal-heuristic.md +++ b/docs/user-guide/solver/07-thermal-heuristic.md @@ -35,33 +35,33 @@ The way steps 1 and 2 are performed depends on a parameter set by the user in th ### Fast mode #### Step 1: first problem resolution -The general idea of the fast mode is to completely remove the constraints and costs involving integers (the \\(M_\theta\\), \\(M_\theta^+\\) and \\(M_\theta^-\\) variables) in step 1. This means that the first resolution of the weekly problem does not consider constraints (17) to (23) in the [optimisation problem formulation](01-modeling.md). Constraint (16) related to the minimum/maximum output of the thermal cluster is kept. In addition, costs related to integer variables (start-up and hourly fixed costs) are not included in the objective function. +The general idea of the fast mode is to completely remove the constraints and costs involving integers (the $M_\theta$, $M_\theta^+$ and $M_\theta^-$ variables) in step 1. This means that the first resolution of the weekly problem does not consider constraints (17) to (23) in the [optimisation problem formulation](01-modeling.md). Constraint (16) related to the minimum/maximum output of the thermal cluster is kept. In addition, costs related to integer variables (start-up and hourly fixed costs) are not included in the objective function. -The first resolution of the problem is then run, and provides hourly power outputs for each thermal cluster \\(P_{\theta,t}^{optim1}\\). At each hour, an initial value of the NODU of each cluster in then calculated: \\(M_\{\theta, t}^{guide} = ceil(\frac{P_{\theta,t}^{optim1}}{\overline{P_{\theta}}})\\). +The first resolution of the problem is then run, and provides hourly power outputs for each thermal cluster $P_{\theta,t}^{optim1}$. At each hour, an initial value of the NODU of each cluster in then calculated: $M_{\theta,t}^{guide}$ = $ceil(\frac{P_{\theta,t}^{optim1}}{\overline{P_{\theta} } }) $. #### Step 2: fast mode heuristic -In step 2, for each cluster, a parameter \\(\Delta_{adjust,\theta} = max(\Delta_\theta^+, \Delta_\theta^-)\\) is then calculated, which is the maximum of the minimum on and off durations. Hence, they are approximated to be of the same duration. For each week and each thermal cluster, the week is then divided in intervals of length \\(\Delta_{adjust,\theta}\\). The week is supposed to be cyclic (hour 1 is the timestep followin hour 168), just like in the weekly optimization problem solved by Antares. Within each interval, the NODU of the cluster is increased to the maximum value of \\(M_\{\theta, t}^{guide}\\) during this period. This process is run several time by shifting the intervals timestep by timestep until all the possible week splits have been performed. Finally, the solution which minimizes the number of adjustments of the NODU is used as the solution of step 2 \\(M_{\theta,t}^{heuristic}\\). +In step 2, for each cluster, a parameter $\Delta_{adjust,\theta} = max(\Delta_\theta^+, \Delta_\theta^-)$ is then calculated, which is the maximum of the minimum on and off durations. Hence, they are approximated to be of the same duration. For each week and each thermal cluster, the week is then divided in intervals of length $\Delta_{adjust,\theta}$. The week is supposed to be cyclic (hour 1 is the timestep followin hour 168), just like in the weekly optimization problem solved by Antares. Within each interval, the NODU of the cluster is increased to the maximum value of $M_{\theta, t}^{guide}$ during this period. This process is run several time by shifting the intervals timestep by timestep until all the possible week splits have been performed. Finally, the solution which minimizes the number of adjustments of the NODU is used as the solution of step 2 $M_{\theta,t}^{heuristic}$. ![Step 2 of the "fast" thermal mode](img/thermal_heuristic_fast_step_2.png){ .add-padding-and-white-bg }

Illustration of step 2 of the fast mode, with $\Delta_{adjust,\theta}$ equal to 2. Here, both solutions are acceptable as they involve 3 NODU adjustments.

#### Step 3: second resolution -Finally, the result of the heuristic \\(M_{\theta,t}^{heuristic}\\) is converted into a lower bound of the power output of each thermal cluster in step 3: \\(P_{\theta,t}^{min}=\underline{P_\theta}*M_{\theta,t}^{heuristic}\\). The second resolution of the problem is then run considering this lower bound, and still excluding integer variables and constraints (17) to (23) of the [optimisation problem formulation](01-modeling.md). In particular, this means that startup and fixed costs are not considered in the formulation of the optimisation problem in any of the two resolutions. However, they are added ex-post and visible in the output variables. +Finally, the result of the heuristic $M_{\theta,t}^{heuristic}$ is converted into a lower bound of the power output of each thermal cluster in step 3: $P_{\theta,t}^{min}=\underline{P_\theta}*M_{\theta,t}^{heuristic}$. The second resolution of the problem is then run considering this lower bound, and still excluding integer variables and constraints (17) to (23) of the [optimisation problem formulation](01-modeling.md). In particular, this means that startup and fixed costs are not considered in the formulation of the optimisation problem in any of the two resolutions. However, they are added ex-post and visible in the output variables. ### Accurate mode #### Step 1: first problem resolution -The accurate mode aims at taking into account integer variables in both resolutions of the optimisation problem (steps 1 and 3), but considering them as continuous variables in step 1, and fixing them as parameters in step 3. Contrary to the fast mode, constraints (17) to (23) of the [optimisation problem formulation](01-modeling.md) are taken into account in both resolutions, as well as the start-up and fixed costs in the objective function, but the integer variables \\(M_\theta\\) are considered continuous. +The accurate mode aims at taking into account integer variables in both resolutions of the optimisation problem (steps 1 and 3), but considering them as continuous variables in step 1, and fixing them as parameters in step 3. Contrary to the fast mode, constraints (17) to (23) of the [optimisation problem formulation](01-modeling.md) are taken into account in both resolutions, as well as the start-up and fixed costs in the objective function, but the integer variables $M_\theta$ are considered continuous. -The first resolution of the problem is then run. As an output, the integer NODU for each thermal cluster is calculed by rounding up the continuous NODUs which are the output of this resolution: \\(M_{\theta,t}^{guide}=ceil(M_{\theta,t}^{optim1})\\). The variables counting the number of units being started-up or shut-down at any time step \\(M_{\theta,t}^{+}\\) and \\(M_{\theta,t}^{-}\\) are also calculated at that stage. +The first resolution of the problem is then run. As an output, the integer NODU for each thermal cluster is calculed by rounding up the continuous NODUs which are the output of this resolution: $M_{\theta,t}^{guide}=ceil(M_{\theta,t}^{optim1})$. The variables counting the number of units being started-up or shut-down at any time step $M_{\theta,t}^{+}$ and $M_{\theta,t}^{-}$ are also calculated at that stage. #### Step 2: accurate mode heuristic -Step 2 of the accurate mode starts by checking for each cluster and for each week whether any constraint of minimum time up or down (constraints (22) and (23) of the [weekly optimisation problem](01-modeling.md)) is violated. If no constraint is violated for a given thermal cluster at a given week, no further action is performed and the output variable of this step \\(M_{\theta,t}^{heuristic}=M_{\theta,t}^{guide}\\). +Step 2 of the accurate mode starts by checking for each cluster and for each week whether any constraint of minimum time up or down (constraints (22) and (23) of the [weekly optimisation problem](01-modeling.md)) is violated. If no constraint is violated for a given thermal cluster at a given week, no further action is performed and the output variable of this step $M_{\theta,t}^{heuristic}=M_{\theta,t}^{guide}$. -For a given cluster and a given week, if any of these constraints is violated, a small optimisation problem is run, which aims at minimizing the changes to the NODU of the cluster while respecting constraints (22) and (23). The output of this optimisation problem is then \\(M_{\theta,t}^{heuristic}\\). +For a given cluster and a given week, if any of these constraints is violated, a small optimisation problem is run, which aims at minimizing the changes to the NODU of the cluster while respecting constraints (22) and (23). The output of this optimisation problem is then $M_{\theta,t}^{heuristic}$. #### Step 3: second resolution -Finally, the output of step 2 \\(M_{\theta,t}^{heuristic}\\) is converted into a lower bound of the NODU of each thermal cluster for the second resolution: \\(M_{\theta,t} \geq M_{\theta,t}^{heuristic}\\). The second resolution of the problem is then run considering this lower bound, and still including integer variables (as continuous variables) and constraints (17) to (23) of the [optimisation problem formulation](01-modeling.md), and start-up and fixed costs in the objective function. +Finally, the output of step 2 $M_{\theta,t}^{heuristic}$ is converted into a lower bound of the NODU of each thermal cluster for the second resolution: $M_{\theta,t} \geq M_{\theta,t}^{heuristic}$. The second resolution of the problem is then run considering this lower bound, and still including integer variables (as continuous variables) and constraints (17) to (23) of the [optimisation problem formulation](01-modeling.md), and start-up and fixed costs in the objective function. ## Annual smoothing heuristic (step 4) @@ -71,11 +71,11 @@ As a final step of the resolution of a Monte-Carlo year, an annual smoothing heu The general principle of this heuristic is that while respecting the production plan determined at the end of the second resolution and the minimum power output of each unit, we calculate a minimum duration below which it is more economically interesting to leave a group on rather than shutting it down and restarting it at a later stage. This duration is defined as follows: -$$𝑑=\frac{\sigma_\theta^+}{\tau_\theta}$$ -with \\(\sigma_\theta^+\\) the startup cost of a unit of cluster \\(\theta\\), and \\({\tau_\theta}\\) the fixed cost of a unit of cluster \\(\theta\\) when it is on. +$$d=\frac{\sigma_\theta^+}{\tau_\theta}$$ +with $\sigma_\theta^+$ the startup cost of a unit of cluster $\theta$, and ${\tau_\theta}$ the fixed cost of a unit of cluster $\theta$ when it is on. -The smoothing heuristic may then choose to increase the NODU in certain clusters when it identifies that a shut-down/start-up sequence lasted shorter than duration d. The new NODU cannot exceed the maximum accepted NODU to respect the production plan, which is equal to \\(floor(\frac{P_\theta}{\underline{P_\theta}})\\). +The smoothing heuristic may then choose to increase the NODU in certain clusters when it identifies that a shut-down/start-up sequence lasted shorter than duration d. The new NODU cannot exceed the maximum accepted NODU to respect the production plan, which is equal to $floor(\frac{P_\theta}{\underline{P_\theta}})$. ![Step 4: smoothing heuristic](img/thermal_smoothing_heuristic.png). diff --git a/docs/user-guide/ts-generator/00-index.md b/docs/user-guide/ts-generator/00-index.md index 264054542c..d4ead75883 100644 --- a/docs/user-guide/ts-generator/00-index.md +++ b/docs/user-guide/ts-generator/00-index.md @@ -3,7 +3,7 @@ ```{toctree} :hidden: -01-overview.md +01-overview-tsgenerator.md 02-inputs.md 03-outputs.md 04-parameters.md diff --git a/docs/user-guide/ts-generator/01-overview.md b/docs/user-guide/ts-generator/01-overview-tsgenerator.md similarity index 100% rename from docs/user-guide/ts-generator/01-overview.md rename to docs/user-guide/ts-generator/01-overview-tsgenerator.md diff --git a/docs/user-guide/ts-generator/04-parameters.md b/docs/user-guide/ts-generator/04-parameters.md index 2fac490989..debe1465cc 100644 --- a/docs/user-guide/ts-generator/04-parameters.md +++ b/docs/user-guide/ts-generator/04-parameters.md @@ -12,7 +12,7 @@ These parameters are listed under the `[general]` section in the `.ini` file. --- ### Time-series parameters ---- + #### generate - **Expected value:** comma-seperated list of 0 to N elements among the following (case-insensitive): `load`, `wind`, `hydro`, `thermal`, `solar`, `renewables`, `max-power` (ex: `generate = load, hydro, wind`) From 4d7e767172498dc3b89c8548581b27e1ad3c2c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 31 May 2024 10:58:51 +0200 Subject: [PATCH 003/127] Remove multiple definitions for Antares::Statistics::HasWrittenToDisk (#2136) --- src/tests/src/libs/antares/array/fill-matrix.h | 10 ---------- src/tests/src/libs/antares/array/matrix-bypass-load.h | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/src/tests/src/libs/antares/array/fill-matrix.h b/src/tests/src/libs/antares/array/fill-matrix.h index 167e943715..29681740e3 100644 --- a/src/tests/src/libs/antares/array/fill-matrix.h +++ b/src/tests/src/libs/antares/array/fill-matrix.h @@ -31,16 +31,6 @@ using namespace std; using namespace Antares; -namespace Antares -{ -namespace Statistics -{ -void HasWrittenToDisk(uint64_t /* size */) -{ -} -} // namespace Statistics -} // namespace Antares - template class Matrix_easy_to_fill: public Matrix { diff --git a/src/tests/src/libs/antares/array/matrix-bypass-load.h b/src/tests/src/libs/antares/array/matrix-bypass-load.h index 387dcfdc8a..c981a8d199 100644 --- a/src/tests/src/libs/antares/array/matrix-bypass-load.h +++ b/src/tests/src/libs/antares/array/matrix-bypass-load.h @@ -41,16 +41,6 @@ struct PredicateIdentity } // namespace UnitTests } // namespace Antares -namespace Antares -{ -namespace Statistics -{ -void HasReadFromDisk(uint64_t /* size */) -{ -} -} // namespace Statistics -} // namespace Antares - template class Matrix_load_bypass: public Matrix_easy_to_fill { From 8d9c79581bbfd9d6aca3b1fcca7b05dc8ebea0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 31 May 2024 11:35:31 +0200 Subject: [PATCH 004/127] Fix version metadata in SonarQ & docs (v9.1) (#2135) --- docs/pdf-doc-generation-with-sphinx/source/conf.py | 4 ++-- sonar-project.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pdf-doc-generation-with-sphinx/source/conf.py b/docs/pdf-doc-generation-with-sphinx/source/conf.py index 9c84a4fc3b..9226aefac1 100644 --- a/docs/pdf-doc-generation-with-sphinx/source/conf.py +++ b/docs/pdf-doc-generation-with-sphinx/source/conf.py @@ -18,8 +18,8 @@ # -- Project information ----------------------------------------------------- project = 'Antares Simulator User Guide' -release = 'v8.8' -copyright = '2023, RTE' +release = 'v9.1' +copyright = '2024, RTE' author = 'RTE' diff --git a/sonar-project.properties b/sonar-project.properties index 5065cb1141..bf90dbda19 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ sonar.projectName=Antares_Simulator sonar.projectKey=AntaresSimulatorTeam_Antares_Simulator sonar.organization=antaressimulatorteam -sonar.projectVersion=9.0.0 +sonar.projectVersion=9.1.0 # ===================================================== # Properties that will be shared amongst all modules From 26e03f5eb186e8afe80ffd7cd4477ba790d68f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 31 May 2024 14:31:15 +0200 Subject: [PATCH 005/127] Restore correct behavior when options -h/--list-solvers are provided (#2138) #2056 introduced a slight change of behavior : after this PR, when the user requests help (--help) or queries the available OR-Tools solvers (--list-solvers), a warning message is displayed after the requested information. This is a bit annoying, so here is a fix. --- src/solver/application/application.cpp | 19 +++++++++++-------- .../include/antares/application/application.h | 6 ++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index 374982928e..d221d19eb6 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -63,7 +63,7 @@ Application::Application() resetProcessPriority(); } -void Application::parseCommandLine(Data::StudyLoadOptions& options) +bool Application::parseCommandLine(Data::StudyLoadOptions& options) { auto parser = CreateParser(pSettings, options); auto ret = parser->operator()(pArgc, pArgv); @@ -73,27 +73,28 @@ void Application::parseCommandLine(Data::StudyLoadOptions& options) throw Error::CommandLineArguments(parser->errors()); case Yuni::GetOpt::ReturnCode::help: pStudy = nullptr; - return; + return false; default: - break; + return true; } } -void Application::handleOptions(const Data::StudyLoadOptions& options) +bool Application::handleOptions(const Data::StudyLoadOptions& options) { if (options.displayVersion) { PrintVersionToStdCout(); pStudy = nullptr; - return; + return false; } if (options.listSolvers) { printSolvers(); pStudy = nullptr; - return; + return false; } + return true; } void Application::readDataForTheStudy(Data::StudyLoadOptions& options) @@ -335,9 +336,11 @@ void Application::prepare(int argc, char* argv[]) // The parser contains references to members of pSettings and options, // don't de-allocate these. - parseCommandLine(options); + if (!parseCommandLine(options)) // --help + return; - handleOptions(options); + if (!handleOptions(options)) // --version, --list-solvers + return; // Perform some checks checkAndCorrectSettingsAndOptions(pSettings, options); diff --git a/src/solver/application/include/antares/application/application.h b/src/solver/application/include/antares/application/application.h index 7f6dab80d6..788aff68e9 100644 --- a/src/solver/application/include/antares/application/application.h +++ b/src/solver/application/include/antares/application/application.h @@ -124,8 +124,10 @@ class Application final: public Yuni::IEventObserver Date: Fri, 31 May 2024 15:38:57 +0200 Subject: [PATCH 006/127] [ubuntu workflow] remove vcpkg manual install (#2139) --- .github/workflows/ubuntu.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 2de211c08c..cbb66c6df8 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -101,14 +101,6 @@ jobs: run: | export WX_CONFIG=${{env.WX_CONFIG}} - - name : Install deps with VCPKG - run: | - cd vcpkg - ./bootstrap-vcpkg.sh - vcpkg install ${{env.vcpkgPackages}} --triplet ${{env.triplet}} - rm -rf buildtrees packages downloads - shell: bash - - name: Read antares-deps version id: antares-deps-version uses: notiz-dev/github-action-json-property@release From 6e0e94f3dd80ec49c8d86cd25ebbe01f81d7ad30 Mon Sep 17 00:00:00 2001 From: abdoulbari zaher <32519851+a-zakir@users.noreply.github.com> Date: Fri, 31 May 2024 17:28:28 +0200 Subject: [PATCH 007/127] Fix circular dependencies on CMake targets (#2140) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #2137 --------- Co-authored-by: Florian Omnès --- src/solver/optimisation/CMakeLists.txt | 1 - .../solver/optimisation/opt_fonctions.h | 2 +- .../opt_period_string_generator_base.h | 34 ------------------- src/solver/utils/CMakeLists.txt | 1 - src/solver/utils/filename.cpp | 4 --- .../include/antares/solver/utils/filename.h | 2 +- .../utils/opt_period_string_generator.h | 8 ++++- 7 files changed, 9 insertions(+), 43 deletions(-) delete mode 100644 src/solver/optimisation/include/antares/solver/optimisation/opt_period_string_generator_base.h diff --git a/src/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt index 0b5783ae92..2e3f257932 100644 --- a/src/solver/optimisation/CMakeLists.txt +++ b/src/solver/optimisation/CMakeLists.txt @@ -72,7 +72,6 @@ set(RTESOLVER_OPT include/antares/solver/optimisation/adequacy_patch_csr/constraints/CsrBindingConstraintHour.h adequacy_patch_csr/constraints/CsrBindingConstraintHour.cpp - include/antares/solver/optimisation/opt_period_string_generator_base.h include/antares/solver/optimisation/opt_rename_problem.h opt_rename_problem.cpp diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h index 308616f1c4..8aad20d799 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h @@ -22,13 +22,13 @@ #define __SOLVER_OPTIMISATION_FUNCTIONS_H__ #include +#include #include #include "antares/config/config.h" #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" #include "antares/study/parameters/adq-patch-params.h" #include "adequacy_patch_csr/hourly_csr_problem.h" -#include "opt_period_string_generator_base.h" using AdqPatchParams = Antares::Data::AdequacyPatch::AdqPatchParams; using OptimizationOptions = Antares::Solver::Optimization::OptimizationOptions; diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_period_string_generator_base.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_period_string_generator_base.h deleted file mode 100644 index 217d95db0c..0000000000 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_period_string_generator_base.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ - -#pragma once - -#include - -// --------------------------------------------- -// Optimization period as string : base class -// -------------------------------------------- -class OptPeriodStringGenerator -{ -public: - virtual std::string to_string() const = 0; - virtual ~OptPeriodStringGenerator() = default; -}; diff --git a/src/solver/utils/CMakeLists.txt b/src/solver/utils/CMakeLists.txt index e5ad63c05e..16cf2a96e5 100644 --- a/src/solver/utils/CMakeLists.txt +++ b/src/solver/utils/CMakeLists.txt @@ -35,7 +35,6 @@ target_link_libraries(utils Antares::result_writer #ortools_utils.h Antares::optimization-options antares-core #enum.h - model_antares #opt_period_string_generator.h -> antares/solver/optimisation/opt_period_string_generator_base.h ) target_include_directories(utils diff --git a/src/solver/utils/filename.cpp b/src/solver/utils/filename.cpp index 4e8b9e0482..cc71083350 100644 --- a/src/solver/utils/filename.cpp +++ b/src/solver/utils/filename.cpp @@ -22,10 +22,6 @@ #include -#include "antares/solver/optimisation/opt_period_string_generator_base.h" - -#include "include/antares/solver/utils/opt_period_string_generator.h" - // ------------------------------------ // Optimization period factory // ------------------------------------ diff --git a/src/solver/utils/include/antares/solver/utils/filename.h b/src/solver/utils/include/antares/solver/utils/filename.h index 0ce354bfab..472d8f8477 100644 --- a/src/solver/utils/include/antares/solver/utils/filename.h +++ b/src/solver/utils/include/antares/solver/utils/filename.h @@ -23,7 +23,7 @@ #include #include -#include "antares/solver/optimisation/opt_period_string_generator_base.h" +#include "opt_period_string_generator.h" std::shared_ptr createOptPeriodAsString(bool isOptimizationWeekly, unsigned int day, diff --git a/src/solver/utils/include/antares/solver/utils/opt_period_string_generator.h b/src/solver/utils/include/antares/solver/utils/opt_period_string_generator.h index 36b5630211..f19a65bcfa 100644 --- a/src/solver/utils/include/antares/solver/utils/opt_period_string_generator.h +++ b/src/solver/utils/include/antares/solver/utils/opt_period_string_generator.h @@ -19,6 +19,7 @@ ** along with Antares_Simulator. If not, see . */ #pragma once +#include /* MPS and criterion generated files wear the same time interval sequence in their names. @@ -35,7 +36,12 @@ called. */ -#include "antares/solver/optimisation/opt_period_string_generator_base.h" +class OptPeriodStringGenerator +{ +public: + virtual std::string to_string() const = 0; + virtual ~OptPeriodStringGenerator() = default; +}; // ------------------------------------ // Daily optimization From 5e6a57fd368b305d119a654e84e78a45114597cd Mon Sep 17 00:00:00 2001 From: Sylvain Leclerc Date: Wed, 5 Jun 2024 15:13:52 +0200 Subject: [PATCH 008/127] Install sirius solver with VCPKG, remove antares-deps (#2090) **Description** Continues the work of #2078 (which should be merged before in feature branch feature/vcpkg-dependencies), to push further the use of VCPKG, and in particular remove the need for the home-made antares-deps repository. Hence, this includes: - Addition of sirius-solver "overlay" port to install sirius with VCPKG - Removal of antares-deps and associated code --------- Signed-off-by: Sylvain Leclerc --- .github/workflows/centos7.yml | 14 +- .../action.yml | 9 -- .../action.yml | 13 +- .github/workflows/oracle8.yml | 2 +- .github/workflows/sonarcloud.yml | 11 -- .github/workflows/ubuntu.yml | 20 --- .github/workflows/windows-vcpkg.yml | 11 -- .gitmodules | 4 - antares-deps-version.json | 3 - .../1-Development-requirements.md | 12 +- .../developer-guide/2-Dependencies-install.md | 111 ++++++---------- docs/developer-guide/3-Build.md | 122 +++++++++++------- src/CMakeLists.txt | 57 +------- src/antares-deps | 1 - src/ports/sirius-solver/portfile.cmake | 21 +++ src/ports/sirius-solver/vcpkg.json | 16 +++ src/ui/CMakeLists.txt | 5 - src/vcpkg.json | 6 + 18 files changed, 170 insertions(+), 268 deletions(-) delete mode 100644 antares-deps-version.json delete mode 160000 src/antares-deps create mode 100644 src/ports/sirius-solver/portfile.cmake create mode 100644 src/ports/sirius-solver/vcpkg.json diff --git a/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index 5f5a34d4b6..3308dab812 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -7,7 +7,6 @@ on: branches: - develop - dependabot/* - schedule: - cron: '21 2 * * *' workflow_call: @@ -71,15 +70,7 @@ jobs: - name: Init submodule run: | - git submodule update --init --remote src/antares-deps src/tests/resources/Antares_Simulator_Tests - - - name: Download & extract precompiled deps at root - run: | - ANTARES_DEPS_VERSION=$(cut -d'"' -f4 antares-deps-version.json | grep -Ev '\{|\}') - cd / - wget https://github.com/AntaresSimulatorTeam/antares-deps/releases/download/v${ANTARES_DEPS_VERSION}/rte-antares-deps-centos7-Release.tar.gz - tar -xvf rte-antares-deps-centos7-Release.tar.gz - rm -rf rte-antares-deps-centos7-Release.tar.gz + git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests - name: Config OR-Tools URL run: | @@ -110,14 +101,13 @@ jobs: -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/vcpkg/scripts/buildsystems/vcpkg.cmake \ -DVCPKG_TARGET_TRIPLET=x64-linux-release \ - -DDEPS_INSTALL_DIR=/rte-antares-deps-Release \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_TESTING=ON \ - -DBUILD_not_system=OFF \ -DBUILD_TOOLS=ON \ -DBUILD_UI=OFF \ -DCMAKE_PREFIX_PATH=${{ env.ORTOOLSDIR }}/install \ + - name: Build run: | source /opt/rh/devtoolset-10/enable diff --git a/.github/workflows/download-extract-precompiled-libraries-tgz/action.yml b/.github/workflows/download-extract-precompiled-libraries-tgz/action.yml index 00852138af..d6b87bcaa5 100644 --- a/.github/workflows/download-extract-precompiled-libraries-tgz/action.yml +++ b/.github/workflows/download-extract-precompiled-libraries-tgz/action.yml @@ -1,9 +1,6 @@ name: "Download extract .tgz precompiled libraries" description: "Download and extract .tgz precompiled libraries from antares-deps and antares-simulator repository" inputs: - antares-deps-version: - description: 'antares-deps version' - required: true os: description: 'operational system used for github action' required: true @@ -21,12 +18,6 @@ inputs: runs: using: "composite" steps: - - name: Download & extract antares-deps - shell: bash - run: | - wget https://github.com/AntaresSimulatorTeam/antares-deps/releases/download/v${{inputs.antares-deps-version}}/rte-antares-deps-${{inputs.os}}-${{inputs.buildtype}}.tar.gz - tar -xvf rte-antares-deps-${{inputs.os}}-${{inputs.buildtype}}.tar.gz - rm -rf rte-antares-deps-${{inputs.os}}-${{inputs.buildtype}}.tar.gz - name: Download & extract OR-Tools shell: bash diff --git a/.github/workflows/download-extract-precompiled-libraries-zip/action.yml b/.github/workflows/download-extract-precompiled-libraries-zip/action.yml index 745b76236c..52eec0beea 100644 --- a/.github/workflows/download-extract-precompiled-libraries-zip/action.yml +++ b/.github/workflows/download-extract-precompiled-libraries-zip/action.yml @@ -1,9 +1,6 @@ name: "Download extract .zip precompiled libraries" description: "Download and extract .zip precompiled libraries from antares-deps and antares-simulator repository" inputs: - antares-deps-version: - description: 'antares-deps version' - required: true os: description: 'operational system used for github action' required: true @@ -20,15 +17,7 @@ inputs: runs: using: "composite" - steps: - - name: Download & extract antares-deps - shell: bash - run: | - wget https://github.com/AntaresSimulatorTeam/antares-deps/releases/download/v${{inputs.antares-deps-version}}/rte-antares-deps-${{inputs.os}}-${{inputs.buildtype}}.zip - unzip rte-antares-deps-${{inputs.os}}-${{inputs.buildtype}}.zip - rm -rf rte-antares-deps-${{inputs.os}}-${{inputs.buildtype}}.zip - echo "${GITHUB_WORKSPACE}/rte-antares-deps-Release/bin" >> $GITHUB_PATH - + steps: - name: Download & extract OR-Tools shell: bash run: | diff --git a/.github/workflows/oracle8.yml b/.github/workflows/oracle8.yml index 23c5d49d57..92b65a9a72 100644 --- a/.github/workflows/oracle8.yml +++ b/.github/workflows/oracle8.yml @@ -85,7 +85,7 @@ jobs: rm ortools.zip - name: Init submodule - run: git submodule update --init --remote src/antares-deps src/tests/resources/Antares_Simulator_Tests + run: git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests - name: Install dependencies run: | diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index cf326c2d72..cfe5324d3c 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -54,17 +54,9 @@ jobs: sudo apt-get install libboost-test-dev sudo apt-get install g++-10 gcc-10 - - name: Read antares-deps version - id: antares-deps-version - uses: notiz-dev/github-action-json-property@release - with: - path: 'antares-deps-version.json' - prop_path: 'antares_deps_version' - - name: Download pre-compiled librairies uses: ./.github/workflows/download-extract-precompiled-libraries-tgz with: - antares-deps-version: ${{steps.antares-deps-version.outputs.prop}} os: ${{matrix.os}} buildtype: Debug ortools-url: ${{env.ORTOOLS_URL}} @@ -85,7 +77,6 @@ jobs: - name: Init submodule run: | - git submodule update --init src/antares-deps git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests - name: Configure @@ -97,13 +88,11 @@ jobs: -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 \ -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ -DVCPKG_TARGET_TRIPLET=x64-linux-release \ - -DDEPS_INSTALL_DIR=./rte-antares-deps-Debug \ -DCODE_COVERAGE=ON \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_PREFIX_PATH="../install;${{ env.ORTOOLS_DIR }}/install" \ -DBUILD_TESTING=ON \ -DMZ_CODE_COVERAGE=ON \ - -DBUILD_not_system=OFF \ -DPython3_EXECUTABLE='${{ steps.setup-python.outputs.python-path }}' - name: Build diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index cbb66c6df8..2bcf2954a0 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -68,7 +68,6 @@ jobs: with: key: ${{ env.os }} - - name : Init VCPKG submodule run: | git submodule update --init vcpkg @@ -96,19 +95,6 @@ jobs: sudo apt-get install uuid-dev libwxgtk3.0-gtk3-dev sudo apt-get install g++-10 gcc-10 - - name: export wxWidgets script - shell: bash - run: | - export WX_CONFIG=${{env.WX_CONFIG}} - - - name: Read antares-deps version - id: antares-deps-version - uses: notiz-dev/github-action-json-property@release - with: - path: 'antares-deps-version.json' - prop_path: 'antares_deps_version' - - - name: Config OR-Tools URL run: | echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV @@ -116,7 +102,6 @@ jobs: - name: Download pre-compiled librairies uses: ./.github/workflows/download-extract-precompiled-libraries-tgz with: - antares-deps-version: ${{steps.antares-deps-version.outputs.prop}} os: ${{env.os}} ortools-url: ${{env.ORTOOLS_URL}} ortools-dir: ${{env.ORTOOLS_DIR}} @@ -134,11 +119,8 @@ jobs: - name: Init submodule run: | - git submodule update --init src/antares-deps git submodule update --init --remote --recursive src/tests/resources/Antares_Simulator_Tests - - - name: Configure run: | cmake -B _build -S src \ @@ -148,10 +130,8 @@ jobs: -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 \ -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ -DVCPKG_TARGET_TRIPLET=x64-linux-release \ - -DDEPS_INSTALL_DIR=${{github.workspace}}/rte-antares-deps-Release \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_TESTING=ON \ - -DBUILD_not_system=OFF \ -DBUILD_TOOLS=ON \ -DCMAKE_PREFIX_PATH=${{ env.ORTOOLS_DIR }}/install \ -DPython3_EXECUTABLE="${{ env.Python3_ROOT_DIR }}/bin/python" diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index 4eb484b8d0..ccc8794dcb 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -94,17 +94,9 @@ jobs: # Allows to restore a cache when deps have only partially changed (like adding a dependency) restore-keys: vcpkg-cache-windows- - - name: Read antares-deps version - id: antares-deps-version - uses: notiz-dev/github-action-json-property@release - with: - path: 'antares-deps-version.json' - prop_path: 'antares_deps_version' - - name: Download pre-compiled librairies uses: ./.github/workflows/download-extract-precompiled-libraries-zip with: - antares-deps-version: ${{steps.antares-deps-version.outputs.prop}} os: ${{env.os}} ortools-url: ${{env.ORTOOLS_URL}} ortools-dir: ${{env.ORTOOLS_DIR}} @@ -121,7 +113,6 @@ jobs: - name: Init submodule run: | - git submodule update --init src/antares-deps git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests - name: Enable git longpaths @@ -131,7 +122,6 @@ jobs: shell: bash run: | cmake -B _build -S src \ - -DDEPS_INSTALL_DIR=rte-antares-deps-Release \ -DCMAKE_PREFIX_PATH="${{ env.ORTOOLS_DIR }}/install" \ -DVCPKG_ROOT="${{env.VCPKG_ROOT}}" \ -DVCPKG_TARGET_TRIPLET=${{ env.triplet }} \ @@ -139,7 +129,6 @@ jobs: -DCMAKE_BUILD_TYPE=Release \ -DBUILD_TESTING=ON \ -DBUILD_TOOLS=ON \ - -DBUILD_not_system=OFF \ -DPython3_EXECUTABLE="${{ env.Python3_ROOT_DIR }}/python.exe" \ -DCMAKE_VS_GLOBALS="CLToolExe=cl.exe;CLToolPath=${GITHUB_WORKSPACE}/ccache;TrackFileAccess=false;UseMultiToolTask=true;DebugInformationFormat=OldStyle" diff --git a/.gitmodules b/.gitmodules index 9bee42d242..77fb4921c7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,3 @@ -[submodule "src/antares-deps"] - path = src/antares-deps - url = https://github.com/AntaresSimulatorTeam/antares-deps.git - branch = v2.0.2b [submodule "src/tests/resources/Antares_Simulator_Tests"] path = src/tests/resources/Antares_Simulator_Tests url = https://github.com/AntaresSimulatorTeam/Antares_Simulator_Tests.git diff --git a/antares-deps-version.json b/antares-deps-version.json deleted file mode 100644 index ced7f5add0..0000000000 --- a/antares-deps-version.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "antares_deps_version": "2.0.2b" -} diff --git a/docs/developer-guide/1-Development-requirements.md b/docs/developer-guide/1-Development-requirements.md index 7378d198cc..02c0896f33 100644 --- a/docs/developer-guide/1-Development-requirements.md +++ b/docs/developer-guide/1-Development-requirements.md @@ -11,13 +11,17 @@ The compilation of *Antares Simulator* requires C++17 support. === "Centos" By default, GCC version on Centos is old. - Some external repositories must be enabled depedning on your version of the OS: + Some external repositories must be enabled depending on your version of the OS: #### Centos 7 You must enable the EPEL repository: ``` sudo yum install epel-release - sudo yum install centos-release-scl + sudo yum install git redhat-lsb-core make wget centos-release-scl scl-utils rpm-build + sudo yum install devtoolset-10-gcc* + + scl enable devtoolset-10 bash + source /opt/rh/rh-git227/enable ``` #### Centos 8 @@ -25,8 +29,8 @@ The compilation of *Antares Simulator* requires C++17 support. ``` sudo yum install dnf-plugins-core sudo yum config-manager --set-enabled PowerTools - sudo yum install devtoolset-9 - scl enable devtoolset-9 bash + sudo yum install devtoolset-10 + scl enable devtoolset-10 bash ``` === "Ubuntu/Debian" diff --git a/docs/developer-guide/2-Dependencies-install.md b/docs/developer-guide/2-Dependencies-install.md index 45a96e08f0..1177228e6a 100644 --- a/docs/developer-guide/2-Dependencies-install.md +++ b/docs/developer-guide/2-Dependencies-install.md @@ -10,94 +10,61 @@ toc_depth: 2 - [OR-Tools](https://github.com/rte-france.com/or-tools) (fork from [Google](https://github.com/google/or-tools)) - [wxWidgets](https://github.com/wxWidgets/wxWidgets) (Only for the complete Antares Simulator solution with GUI) -- [Boost](https://www.boost.org/) libraries: test (Only for unit tests) +- [minizip](https://github.com/zlib-ng/minizip-ng) library, with its dependency zlib +- [Boost](https://www.boost.org/) libraries: header libraries and boost-test library +- [libuuid](https://linux.die.net/man/3/libuuid) on Linux systems -These third-party libraries can be installed: -- by building them from sources (see [here](3-Build.md) for more information) -- or using a package manager. +We favor using [vcpkg](https://github.com/microsoft/vcpkg) for building and installing most of those dependencies, +see [build instructions](3-Build.md) which explain how it integrates with CMake build. +However, we still have a few exceptions that must be installed in a different way, see next sections. -## Install with package manager +Although not encouraged, it's still possible to install those dependencies yourself and add +their installation path to your `CMAKE_PREFIX_PATH`. -=== "Windows" +## OR-Tools - For Windows we will use [vcpkg](https://github.com/microsoft/vcpkg) to download and compile the libraries. vcpkg is available as a submodule in *ANTARES*. - - You must install the corresponding [vcpkg-triplet](https://vcpkg.readthedocs.io/en/latest/users/integration/#triplet-selection) depending on Antares version and libraries load: - - - ``x64-windows`` : 64 bits version with dynamic libraries load - - ``x86-windows`` : 32 bits version with dynamic libraries load - - ``x64-windows-static``: 64 bits version with static libraries load - - ``x86-windows-static``: 32 bits version with static libraries load - - The vcpkg-triplet used will be named [vcpg-triplet] later in this document. - - - Init submodule and install vcpkg - - ``` - git submodule update --init vcpkg - cd vcpkg - .\bootstrap-vcpkg.bat - ``` - - Note: - > all vcpkg command further described must be run from vcpkg folder. This folder will be named [vcpkg_root] later in this document. +OR-Tools may be installed in one of 2 ways: + +1. **As a pre-compiled dependency** + + You can [download](https://github.com/rte-france/or-tools/releases) a precompiled OR-Tools archive that contains headers & static libraries. + Please note that dynamic linking with OR-Tools is only supported in Linux. - - Install dependencies - ``` - cd vcpkg - vcpkg install wxwidgets boost-test --triplet [vcpg-triplet] - ``` + Decompress the archive, and provide its path as a `CMAKE_PREFIX_PATH`. + +2. **As part of the build** + + You may enable the `BUILD_ORTOOLS` configuration option to build it from source during Antares build, + as documented in [build instructions](3-Build.md). + + The drawback of this second approach is that OR-Tools may need to be built again when you + run again a cmake configure step, therefore it's not advised for developers. + + +## Linux: libuuid and wxWidgets + +On Linux systems, libuuid development packages need to be installed with your +OS package manager. +You will also need to install wxWidgets if you want to build the GUI. + === "Centos" ``` - sudo yum install git redhat-lsb-core gcc gcc-c++ make wget centos-release-scl scl-utils rpm-build - sudo yum install cmake3 devtoolset-9 - sudo yum install libuuid-devel unzip wxGTK3-devel boost-test boost-devel + sudo yum install libuuid-devel + sudo yum install wxGTK3-devel ``` + === "Ubuntu 20.04 or 22.04 / Debian 11" ``` - sudo apt install uuid-dev libwxgtk3.0-gtk3-dev - sudo apt install libboost-test-dev + sudo apt install uuid-dev + sudo apt install libwxgtk3.0-gtk3-dev ``` === "Ubuntu 23.04 / Debian 12" ``` - sudo apt install uuid-dev libwxgtk3.2-dev libboost-test-dev + sudo apt install uuid-dev + sudo apt install libwxgtk3.2-dev ``` - -## Automatic libraries compilation from sources -[The Antares dependencies compilation repository](https://github.com/AntaresSimulatorTeam/antares-deps) is a submodule that can be used for automatic libraries compilation from sources. - -Apart from OR-Tools, all dependencies can be built at configure time using the option `-DBUILD_ALL=ON` (`OFF` by default). -For a list of available options, see [the Antares dependencies compilation repository](https://github.com/AntaresSimulatorTeam/antares-deps). - -You can set `-DBUILD_ORTOOLS=ON` to download & build OR-Tools. It is also possible to use a precompiled archive, see below. - -For compiling the package yourself from git, additional build dependencies are needed (see [here](1-Development-requirements.md)). - -### Pre-compiled OR-Tools: release+static only -You can [download](https://github.com/rte-france/or-tools/releases) a precompiled OR-Tools archive that contains headers & static libraries. - -Please note that dynamic linking with OR-Tools is only supported in Linux. - -Decompress the archive, and provide its path as a `CMAKE_PREFIX_PATH`. If you use XPRESS, you may need also to specify `XPRESS_ROOT`. - -### Defining dependency install directory -When using multiple directories for Antares development with multiple branches, it can be useful to have a common dependency install directory. - -Dependency install directory can be specified with `DEPS_INSTALL_DIR`. By default, install directory is `/../rte-antares-deps-` - -Note: -> `DEPS_INSTALL_DIR` is added to `CMAKE_PREFIX_PATH` - -### Pre-compiled libraries download: release version only -You can download a pre-compiled antares-deps archive from [Antares dependencies compilation repository][antares-deps-url]. Only release versions are available. - -Note: -> For Windows, you must you use a MSVC version compatible with the MSVC version used in the GitHub Action that made the release. - -[antares-deps-url]: https://github.com/AntaresSimulatorTeam/antares-deps/releases - diff --git a/docs/developer-guide/3-Build.md b/docs/developer-guide/3-Build.md index 14f7ccdbe3..860c9f47cb 100644 --- a/docs/developer-guide/3-Build.md +++ b/docs/developer-guide/3-Build.md @@ -1,69 +1,77 @@ # Build -Before build, make sure that dependencies are [installed](2-Dependencies-install.md). -## Environment settings -On CentOS, enable `devtoolset-9` and `rh-git227`: -``` -scl enable devtoolset-9 bash -source /opt/rh/rh-git227/enable -``` -## Update git submodule -``` -git submodule update --init src/antares-deps -``` -> 💡 **Ignore submodules to make git operations faster** -> Antares_Simulator is quite a large project, with a few large submodules. In file .git/config, you can add this line to all [submodule] sections -> ``` -> ignore = all -> ``` -> This way git won't waste time computing diff on these when checking out, diffing commits, etc. git operations should be a lot faster. -> Keep in mind that your submodules won't be updated. +Before building, make sure that dependencies are [installed](2-Dependencies-install.md). + +## Install VCPKG + +Although you may install third party dependencies yourself, the preferred way is +to rely on [vcpkg](https://github.com/microsoft/vcpkg) and its CMake integration +to build and install most of them. + +The first step will be to install VCPKG using its bootstrap script: -## Configure build with CMake === "Windows" ``` - cmake -B _build -S [antares_src] -DVCPKG_ROOT=[vcpkg_root] -DVCPKG_TARGET_TRIPLET=[vcpkg-triplet] -DCMAKE_BUILD_TYPE=release + git submodule update --init vcpkg + cd vcpkg + .\bootstrap-vcpkg.bat ``` - > **Note:** cpack NSIS installer creation needs an 'out-of-source build'. The build directory must be outside `[antares_src]` directory -=== "CentOS" +=== "Linux" ``` - cmake3 -B _build -S [antares_src] -DCMAKE_BUILD_TYPE=release + git submodule update --init vcpkg + cd vcpkg + ./bootstrap-vcpkg.sh ``` -=== "Ubuntu/Debian" + +## Configure build with CMake + +The preferred way of building the project is to use a pre-compiled version of OR-Tools and to install +other dependencies using vcpkg. To achieve this, you will need to define VCPKG-related variables, +and add your OR-tools install path to `CMAKE_PREFIX_PATH`: + + +=== "Windows" ``` - cmake -B _build -S [antares_src] -DCMAKE_BUILD_TYPE=release + cmake -B _build -S src -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-windows-antares \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH= + ``` + + > **Note:** cpack NSIS installer creation needs an 'out-of-source build'. The build directory must be outside `src` directory + + +=== "Linux" + + ``` + cmake -B _build -S src -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-linux-antares \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH= ``` Here is a list of mandatory or optional CMake configuration options: -| Option | Mandatory | Description | Expected value | Default value | -|:----------------------|-----------|----------------------------------------------------------------------------------|----------------------------------------|-----------------------------------------------------------| -| `CMAKE_C_COMPILER` | **yes** | Select C compiler | `gcc_-10` | | -| `CMAKE_CXX_COMPILER` | **yes** | Select C++ compiler | `g++-10` | | -| `CMAKE_BUILD_TYPE` | **yes** | Define build type | `Release` / `Debug` / `RelWithDebInfo` | | -| `BUILD_UI` | no | Enable or disable Antares Simulator UI[^1] compilation | `ON` / `OFF` | `ON` | -| `BUILD_ALL` | no | Enable build of ALL external libraries | `ON` / `OFF` | `OFF` | -| `DEPS_INSTALL_DIR` | no | Define dependencies libraries install directory | absolute path to an existing directory | `/../rte-antares-deps-` | -| `USE_PRECOMPILED_EXT` | no | This option must be set if you use wxWidget as precompiled external library | `ON` / `OFF` | `OFF` | -| `BUILD_TESTING` | no | Enable build for unit tests | `ON` / `OFF` | `OFF` | -| `BUILD_ORTOOLS` | no | Enable build for OR-Tools and its dependencies (requires an Internet connection) | `ON` / `OFF` | `OFF` | +| Option | Mandatory | Description | Expected value | Default value | +|:-----------------------|--------------|----------------------------------------------------------------------------------|---------------------------------------------|-----------------------------------------------------------| +| `CMAKE_C_COMPILER` | OS-dependent | Select C compiler | `gcc-10` | | +| `CMAKE_CXX_COMPILER` | OS-dependent | Select C++ compiler | `g++-10` | | +| `CMAKE_BUILD_TYPE` | **yes** | Define build type | `Release` / `Debug` / `RelWithDebInfo` | | +| `BUILD_UI` | no | Enable or disable Antares Simulator UI[^1] compilation | `ON` / `OFF` | `ON` | +| `BUILD_TESTING` | no | Enable build for unit tests | `ON` / `OFF` | `OFF` | +| `BUILD_ORTOOLS` | no | Enable build for OR-Tools and its dependencies (requires an Internet connection) | `ON` / `OFF` | `OFF` | +| `CMAKE_TOOLCHAIN_FILE` | no | Path to VCPKG toolchain file, allows to integrate VCPKG with cmake build | `../vcpkg/scripts/buildsystems/vcpkg.cmake` | | +| `VCPKG_TARGET_TRIPLET` | no | Define VCPKG triplet (build type for dependencies etc.) | `x64-windows-antares` / `x64-linux-antares` | | > 💡 **Disable the UI build to make builds faster** > The UI takes up a good chunk of compilation time. It is enabled by default, but you can disable it by turning off `BUILD_UI` -Additional options for Windows: - -| Option | Description | -|:-----------------------|------------------------| -| `VCPKG_ROOT` | Define vcpkg directory | -| `VCPKG_TARGET_TRIPLET` | Define [vcpkg-triplet] | - > 💡 **Use Ninja to speed up target generation by CMake** -> At configure time, you may specify Ninja for generation instead of traditional Make. This will speed up the update +> At configure time, you may specify Ninja for generation instead of traditional Make. This will speed up the update > step after you make small changes to the code. > ``` > cmake -S src [...] -G Ninja @@ -74,17 +82,17 @@ Additional options for Windows: === "Windows" ``` - cmake --build _build --config release -j8 + cmake --build _build --config Release -j8 ``` === "CentOS" ``` - cmake3 --build _build --config release -j8 + cmake3 --build _build -j8 ``` === "Ubuntu/Debian" ``` - cmake --build _build --config release -j8 + cmake --build _build -j8 ``` > 💡 Compilation can be done on several processors with `-j` option. @@ -92,4 +100,24 @@ Additional options for Windows: The final GUI file can be executed at `_build/ui/simulator/antares-X.Y-ui-simulator` +## Developer tips + +### Use a compiler cache +In order to avoid unnecessary rebuilds, for example when you switch branches, you may use a compiler cache +such as ccache. Using it under Linux systems is pretty easy with CMake, you only need to specify it +as the compiler launcher at configure time: +``` +cmake ... -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache ... +``` + +### Ignore submodules to make git operations faster +Antares_Simulator is quite a large project, with a few large submodules. In file .git/config, you can add this line to all [submodule] sections +``` +ignore = all +``` +This way git won't waste time computing diff on these when checking out, diffing commits, etc. git operations should be a lot faster. +Keep in mind that your submodules won't be updated. + + + [^1]: GUI support has been dropped in favor of [Antares Web](https://antares-web.readthedocs.io) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 763c40cb96..51fdc67271 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -196,69 +196,15 @@ if (${BUILD_MERSENNE_TWISTER_PYBIND11}) find_package(pybind11 REQUIRED) endif() -#Define install directory -if (NOT DEPS_INSTALL_DIR) - SET(DEPS_INSTALL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../rte-antares-deps-${CMAKE_BUILD_TYPE}) - -else() - if(NOT IS_ABSOLUTE ${DEPS_INSTALL_DIR}) - SET(DEPS_INSTALL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../${DEPS_INSTALL_DIR}) - endif() -endif() - - -# Add DEPS_INSTALL_DIR with antares-xpansion CMAKE_BUILD_TYPE -if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") - - string(REPLACE ${CMAKE_BUILD_TYPE} Release - DEPS_INSTALL_DIR_XPANSION - ${DEPS_INSTALL_DIR}) - - list(APPEND CMAKE_PREFIX_PATH ${DEPS_INSTALL_DIR_XPANSION}) - -elseif("${CMAKE_BUILD_TYPE}" STREQUAL "debug") - - string(REPLACE ${CMAKE_BUILD_TYPE} Debug - DEPS_INSTALL_DIR_XPANSION - ${DEPS_INSTALL_DIR}) - - list(APPEND CMAKE_PREFIX_PATH ${DEPS_INSTALL_DIR_XPANSION}) - -endif() - -list(APPEND CMAKE_PREFIX_PATH ${DEPS_INSTALL_DIR}) -message(STATUS "CMAKE_PREFIX_PATH : ${CMAKE_PREFIX_PATH}") - -# Build Needed dependencies -add_subdirectory(antares-deps) - -#Add needed definition in case of external dependencies compilation -include (antares-deps/cmake/additionnal-definitions.cmake) - #Boost header libraries find_package(Boost REQUIRED) -#TODO : Add ZLIB if VCPKG used why is this needed -if (VCPKG_TOOLCHAIN) - #zlib - find_package(ZLIB REQUIRED) -endif() - #Sirius solver if(POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif() -if (VCPKG_TOOLCHAIN) - list(APPEND CMAKE_PREFIX_PATH "${sirius_solver_ROOT}") - list(APPEND CMAKE_PREFIX_PATH "${ortools_ROOT}") -endif() - -find_package(sirius_solver) - -if (NOT sirius_solver_FOUND) - message (FATAL_ERROR "Sirius solver not found. Sirius solver can be compiled with -DBUILD_sirius=ON or you can specify previous dependency install directory with -DCMAKE_PREFIX_PATH or -DDEPS_INSTALL_DIR") -endif() +find_package(sirius_solver REQUIRED) find_package(ortools) if(NOT ortools_FOUND OR BUILD_ORTOOLS) @@ -298,7 +244,6 @@ else () endif () endif () - #wxWidget not needed for all library find is done in ui CMakeLists.txt if (VCPKG_TOOLCHAIN AND NOT BUILD_wxWidgets) #Add cmake directory to CMAKE_MODULE_PATH to use specific FindwxWidgets package needed for vcpkg diff --git a/src/antares-deps b/src/antares-deps deleted file mode 160000 index 0d6bebfb90..0000000000 --- a/src/antares-deps +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0d6bebfb901e47ec6ac1c73cb61a522803c81b98 diff --git a/src/ports/sirius-solver/portfile.cmake b/src/ports/sirius-solver/portfile.cmake new file mode 100644 index 0000000000..30cce62622 --- /dev/null +++ b/src/ports/sirius-solver/portfile.cmake @@ -0,0 +1,21 @@ +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO "rte-france/sirius-solver" + REF "antares-integration-v1.4" + SHA512 1eecb351b32490a82a2f93bf91e77ea4fd55cffc92c466b4136314e70d8a70328e4fda5257a46c08c431fd7013475050bc3908fcedee4fbdd746ed1ab6cb0efd + HEAD_REF main +) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}/src" +) + +vcpkg_cmake_install() + +vcpkg_cmake_config_fixup(PACKAGE_NAME sirius_solver CONFIG_PATH cmake) + +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") + +vcpkg_copy_pdbs() + +file(INSTALL "${SOURCE_PATH}/LICENSE.TXT" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright) diff --git a/src/ports/sirius-solver/vcpkg.json b/src/ports/sirius-solver/vcpkg.json new file mode 100644 index 0000000000..8e4a0a36df --- /dev/null +++ b/src/ports/sirius-solver/vcpkg.json @@ -0,0 +1,16 @@ +{ + "name": "sirius-solver", + "version": "1.4", + "port-version": 0, + "description": "Sirius solver", + "dependencies": [ + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 0c8f846f96..8bb000564a 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -1,9 +1,4 @@ - -if (USE_PRECOMPILED_EXT AND UNIX) - set (wxWidgets_CONFIG_EXECUTABLE ${DEPS_INSTALL_DIR}/bin/wx-config) -endif() - #wxWidget required find_package(wxWidgets REQUIRED COMPONENTS net core base richtext propgrid aui adv html xml) include(${wxWidgets_USE_FILE}) diff --git a/src/vcpkg.json b/src/vcpkg.json index f15f208a42..011ede41ad 100644 --- a/src/vcpkg.json +++ b/src/vcpkg.json @@ -3,11 +3,17 @@ "version-string": "9.1.0", "builtin-baseline": "9484a57dd560b89f0a583be08af6753611c57fd5", "vcpkg-configuration": { + "overlay-ports": [ + "./ports" + ], "overlay-triplets": [ "./triplets" ] }, "dependencies": [ + { + "name": "sirius-solver" + }, { "name": "wxwidgets", "platform": "windows" From f485d5245a061b73e9d5cd26a03eac551b8d4365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jason=20Mar=C3=A9chal?= <45510813+JasonMarechal25@users.noreply.github.com> Date: Thu, 6 Jun 2024 13:27:19 +0200 Subject: [PATCH 009/127] Remove extra caching vcpkg (#2145) --- .github/workflows/ubuntu.yml | 530 +++++++++++++++++------------------ 1 file changed, 254 insertions(+), 276 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 2bcf2954a0..c774854d16 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -47,287 +47,265 @@ jobs: if: "!contains(github.event.head_commit.message, '[skip ci]')" steps: - - uses: actions/checkout@v4 - with: - ref: ${{ env.REF }} - - - name: Install VCPKG - run: git submodule update --init vcpkg && ./vcpkg/bootstrap-vcpkg.sh -disableMetrics - - - name: Restore vcpkg binary dir from cache - id: cache-vcpkg-binary - uses: actions/cache/restore@v4 - with: - path: ${{ github.workspace }}/vcpkg_cache - key: vcpkg-cache-ubuntu-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} - # Allows to restore a cache when deps have only partially changed (like adding a dependency) - restore-keys: vcpkg-cache-ubuntu- - - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: + - uses: actions/checkout@v4 + with: + ref: ${{ env.REF }} + + - name: Install VCPKG + run: git submodule update --init vcpkg && ./vcpkg/bootstrap-vcpkg.sh -disableMetrics + + - name: Restore vcpkg binary dir from cache + id: cache-vcpkg-binary + uses: actions/cache/restore@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-cache-ubuntu-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} + # Allows to restore a cache when deps have only partially changed (like adding a dependency) + restore-keys: vcpkg-cache-ubuntu- + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: key: ${{ env.os }} - - name : Init VCPKG submodule - run: | - git submodule update --init vcpkg - - # Restore both vcpkg and its artifacts from the GitHub cache service. - - name: Restore vcpkg and its artifacts. - uses: actions/cache@v4 - with: - # The first path is the location of vcpkg (it contains the vcpkg executable and data files). - # The other paths starting with '!' are exclusions: they contain termporary files generated during the build of the installed packages. - path: | - ${{ env.VCPKG_ROOT }} - !${{ env.VCPKG_ROOT }}/buildtrees - !${{ env.VCPKG_ROOT }}/packages - !${{ env.VCPKG_ROOT }}/downloads - # The key is composed in a way that it gets properly invalidated: this must happen whenever vcpkg's Git commit id changes, or the list of packages changes. In this case a cache miss must happen and a new entry with a new key with be pushed to GitHub the cache service. - # The key includes: hash of the vcpkg.json file, the hash of the vcpkg Git commit id, and the used vcpkg's triplet. The vcpkg's commit id would suffice, but computing an hash out it does not harm. - # Note: given a key, the cache content is immutable. If a cache entry has been created improperly, in order the recreate the right content the key must be changed as well, and it must be brand new (i.e. not existing already). - key: | - ${{ hashFiles( 'vcpkg_manifest/vcpkg.json' ) }}-${{ hashFiles( '.git/modules/vcpkg/HEAD' )}}-${{ env.triplet }} - - - name: Install libraries - run: | - sudo apt-get update - sudo apt-get install uuid-dev libwxgtk3.0-gtk3-dev - sudo apt-get install g++-10 gcc-10 - - - name: Config OR-Tools URL - run: | + - name: Install libraries + run: | + sudo apt-get update + sudo apt-get install uuid-dev libwxgtk3.0-gtk3-dev + sudo apt-get install g++-10 gcc-10 + + - name: Config OR-Tools URL + run: | echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV - - name: Download pre-compiled librairies - uses: ./.github/workflows/download-extract-precompiled-libraries-tgz - with: - os: ${{env.os}} - ortools-url: ${{env.ORTOOLS_URL}} - ortools-dir: ${{env.ORTOOLS_DIR}} - - - name: Set up Python - id: setup-python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Install dependencies - run: | + - name: Download pre-compiled librairies + uses: ./.github/workflows/download-extract-precompiled-libraries-tgz + with: + os: ${{env.os}} + ortools-url: ${{env.ORTOOLS_URL}} + ortools-dir: ${{env.ORTOOLS_DIR}} + + - name: Set up Python + id: setup-python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | python -m pip install --upgrade pip pip3 install -r src/tests/examples/requirements.txt - - name: Init submodule - run: | + - name: Configure + run: | + cmake -B _build -S src \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_C_COMPILER=/usr/bin/gcc-10 \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 \ + -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DBUILD_TOOLS=ON \ + -DCMAKE_PREFIX_PATH=${{ env.ORTOOLS_DIR }}/install \ + -DPython3_EXECUTABLE="${{ env.Python3_ROOT_DIR }}/bin/python" + + - name: Build + run: | + cmake --build _build -j$(nproc) + + # simtest + - name: Read simtest version + id: simtest-version + uses: notiz-dev/github-action-json-property@release + with: + path: 'simtest.json' + prop_path: 'version' + + - name: Init submodule + run: | git submodule update --init --remote --recursive src/tests/resources/Antares_Simulator_Tests - - - name: Configure - run: | - cmake -B _build -S src \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DCMAKE_C_COMPILER=/usr/bin/gcc-10 \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 \ - -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ - -DVCPKG_TARGET_TRIPLET=x64-linux-release \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=ON \ - -DBUILD_TOOLS=ON \ - -DCMAKE_PREFIX_PATH=${{ env.ORTOOLS_DIR }}/install \ - -DPython3_EXECUTABLE="${{ env.Python3_ROOT_DIR }}/bin/python" - - - name: Build - run: | - cmake --build _build -j$(nproc) - - # simtest - - name: Read simtest version - id: simtest-version - uses: notiz-dev/github-action-json-property@release - with: - path: 'simtest.json' - prop_path: 'version' - - - - name: Run named mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-named-mps - os: ${{ env.os }} - variant: "named-mps" - - - name: Run unfeasibility-related tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - run: | - cd _build - ctest -C Release --output-on-failure -R "^unfeasible$" - - - name: Run unit and end-to-end tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - run: | - cd _build - ctest -C Release --output-on-failure -L "unit|end-to-end" - - - name: Upload logs for failed tests - if: ${{ failure() }} - uses: actions/upload-artifact@v4 - with: - name: test-log - path: ${{ github.workspace }}/_build/Testing/Temporary/LastTest.log - - - name: Run tests about infinity on BCs RHS - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-v830 - os: ${{ env.os }} - - - name: Run MILP with CBC - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-milp - variant: "milp-cbc" - os: ${{ env.os }} - - - name: Run tests introduced in v860 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-v860 - os: ${{ env.os }} - - - name: Run tests introduced in v870 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-v870 - os: ${{ env.os }} - - - name: Run tests introduced in v910 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-v910 - os: ${{ env.os }} - - - name: Run short-tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: short-tests - os: ${{ env.os }} - - - name: Run mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-mps - os: ${{ env.os }} - - - name: Run tests for adequacy patch (CSR) - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: adequacy-patch-CSR - os: ${{ env.os }} - - - name: Run parallel tests - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: valid-parallel - os: ${{ env.os }} - variant: "parallel" - - - name: Run medium-tests - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: medium-tests - os: ${{ env.os }} - - - name: Run long-tests-1 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: long-tests-1 - os: ${{ env.os }} - - - name: Run long-tests-2 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: long-tests-2 - os: ${{ env.os }} - - - name: Run long-tests-3 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} - batch-name: long-tests-3 - os: ${{ env.os }} - - - name: Installer .deb creation - run: | - cd _build - cpack -G DEB - - - name: .tar.gz creation - run: | - cd _build - cpack -G TGZ - - - name: Solver archive creation - run: | - cd _build - cmake --install . --prefix install - pushd . - cd install/bin - tar czf ../../antares-solver_ubuntu20.04.tar.gz antares-solver libsirius_solver.so - popd - rm -rf install - - - name: Installer archive upload push - uses: actions/upload-artifact@v4 - with: - name: targz - path: _build/*.tar.gz - - - name: Installer deb upload push - uses: actions/upload-artifact@v4 - with: - name: deb - path: _build/*.deb - - - - name: Publish assets - if: ${{ env.IS_RELEASE == 'true' }} - env: - GITHUB_TOKEN: ${{ github.token }} - tag: ${{ github.event.inputs.release_tag }} - run: | - gh release upload "$tag" _build/*.tar.gz _build/*.deb - - - name: Cache vcpkg binary dir - if: always() - id: save-cache-vcpkg-binary - uses: actions/cache/save@v4 - with: - path: ${{ github.workspace }}/vcpkg_cache - key: vcpkg-cache-ubuntu-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} + + - name: Run named mps tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-named-mps + os: ${{ env.os }} + variant: "named-mps" + + - name: Run unfeasibility-related tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + run: | + cd _build + ctest -C Release --output-on-failure -R "^unfeasible$" + + - name: Run unit and end-to-end tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + run: | + cd _build + ctest -C Release --output-on-failure -L "unit|end-to-end" + + - name: Upload logs for failed tests + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: test-log + path: ${{ github.workspace }}/_build/Testing/Temporary/LastTest.log + + - name: Run tests about infinity on BCs RHS + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-v830 + os: ${{ env.os }} + + - name: Run MILP with CBC + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-milp + variant: "milp-cbc" + os: ${{ env.os }} + + - name: Run tests introduced in v860 + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-v860 + os: ${{ env.os }} + + - name: Run tests introduced in v870 + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-v870 + os: ${{ env.os }} + + - name: Run tests introduced in v910 + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-v910 + os: ${{ env.os }} + + - name: Run short-tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: short-tests + os: ${{ env.os }} + + - name: Run mps tests + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-mps + os: ${{ env.os }} + + - name: Run tests for adequacy patch (CSR) + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: adequacy-patch-CSR + os: ${{ env.os }} + + - name: Run parallel tests + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: valid-parallel + os: ${{ env.os }} + variant: "parallel" + + - name: Run medium-tests + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: medium-tests + os: ${{ env.os }} + + - name: Run long-tests-1 + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: long-tests-1 + os: ${{ env.os }} + + - name: Run long-tests-2 + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: long-tests-2 + os: ${{ env.os }} + + - name: Run long-tests-3 + if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: long-tests-3 + os: ${{ env.os }} + + - name: Installer .deb creation + run: | + cd _build + cpack -G DEB + + - name: .tar.gz creation + run: | + cd _build + cpack -G TGZ + + - name: Solver archive creation + run: | + cd _build + cmake --install . --prefix install + pushd . + cd install/bin + tar czf ../../antares-solver_ubuntu20.04.tar.gz antares-solver libsirius_solver.so + popd + rm -rf install + + - name: Installer archive upload push + uses: actions/upload-artifact@v4 + with: + name: targz + path: _build/*.tar.gz + + - name: Installer deb upload push + uses: actions/upload-artifact@v4 + with: + name: deb + path: _build/*.deb + + + - name: Publish assets + if: ${{ env.IS_RELEASE == 'true' }} + env: + GITHUB_TOKEN: ${{ github.token }} + tag: ${{ github.event.inputs.release_tag }} + run: | + gh release upload "$tag" _build/*.tar.gz _build/*.deb + + - name: Cache vcpkg binary dir + if: always() + id: save-cache-vcpkg-binary + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-cache-ubuntu-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} From a5398197a81a3290942644efba720a63cad4734b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Thu, 6 Jun 2024 14:25:43 +0200 Subject: [PATCH 010/127] Use constexpr instead of enum to eliminate warnings (#2144) --- .../include/antares/solver/variable/constants.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/solver/variable/include/antares/solver/variable/constants.h b/src/solver/variable/include/antares/solver/variable/constants.h index 89f9dcf70e..cea6298346 100644 --- a/src/solver/variable/include/antares/solver/variable/constants.h +++ b/src/solver/variable/include/antares/solver/variable/constants.h @@ -27,16 +27,13 @@ namespace Solver { namespace Variable { -enum Constant -{ - maxHoursInAYear = 8785, - maxDaysInAYear = 7 * 53 + 1, // 366, - maxWeeksInAYear = 53, - maxHoursInADay = 24, - maxMonths = 12, - maxDaysInAWeek = 7, - maxHoursInAWeek = 24 * 7, // 168, -}; +constexpr unsigned int maxHoursInAYear = 8785; +constexpr unsigned int maxDaysInAYear = 7 * 53 + 1; // 366, +constexpr unsigned int maxWeeksInAYear = 53; +constexpr unsigned int maxHoursInADay = 24; +constexpr unsigned int maxMonths = 12; +constexpr unsigned int maxDaysInAWeek = 7; +constexpr unsigned int maxHoursInAWeek = 24 * 7; // 168 template struct PrecisionToPrintfFormat From a89c067326ab7be40442c33174ab4b9d1d58a898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Thu, 6 Jun 2024 17:12:36 +0200 Subject: [PATCH 011/127] Fix changelog for v9.1.0 (#2146) Most of the contents for v9.1.0 were under section 8.8.3 --------- Co-authored-by: abdoulbari zaher <32519851+a-zakir@users.noreply.github.com> --- docs/developer-guide/CHANGELOG.md | 84 +++++++++++++++---------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/docs/developer-guide/CHANGELOG.md b/docs/developer-guide/CHANGELOG.md index 67aa64da57..d6606547da 100644 --- a/docs/developer-guide/CHANGELOG.md +++ b/docs/developer-guide/CHANGELOG.md @@ -10,51 +10,8 @@ toc_depth: 2 * Scenarized & hourly values for hydro pumping and hydro generation. Previously this data was not scenarized and daily. * STS groups are now "dynamic" : group names are no longer fixed by code, user is free to define these groups. * Add optimization options from command line in OR-Tools / XPRESS (#1837) -#### TODO - -## Branch 9.0.x - -### 9.0.0 -#### License -* Use licence MPL 2.0 instead of GPL3_WITH_RTE-Exceptions (#1812) - -#### Improvements -* Include overflow variable in HydroPower constraint (#1903) -* Add total time logging at the end of the simulation (#1908) -* Add STS level constraint to suspect list for infeasible problem analysis (#1891) - -#### For developers -* Use precompiled OR-Tools for Oracle Linux 8 CI (#1893) -* Change version behavior to allow more flexibility (#1898) - -#### Code quality -* Use std::shared_ptr instead of indices for active binding constraints in results (#1887) -* Fix a few compilation warnings (#1880) -* Scratchpad numspace (#1749) - -#### Tests -* Fix invalid index causing segfault in `test-study` test (#1902) - -## Branch 8.8.x (end of support 12/2025) - -### 8.8.5 (05/2024) -#### Bugfix -- [UI] Fix opening a study from the file browser -- Fix crash occurring when duplicate thermal clusters are present in a study (same name) -- Fix formula for "PROFIT BY PLANT" - -### 8.8.4 (03/2024) -#### Bugfix -* Adequacy patch CSR - fix DTG MRG (#1982) -* Fix ts numbers for no gen clusters (#1969) -* Remove unitcount limit for time series generation (#1960) - -### 8.8.3 (02/2024) -#### Bugfix -* Fix an issue where depending on the platform the output archive could contain several entries of the same area and inrco files #### Improvements -* Remove sc-builder prefix "hgp", use "h" instead for max hydro pumping & generation timeseries. * Rationalize consistency checks on the number of columns (#2073) * Documentation reorganization and improvement (#2024) (#2023) (#2022) * Add doc for thermal heuristic (#2048) @@ -102,6 +59,47 @@ toc_depth: 2 * Remove deps-build Actions (#2043) * Remove unused logs.hxx (#2026) +## Branch 9.0.x + +### 9.0.0 +#### License +* Use licence MPL 2.0 instead of GPL3_WITH_RTE-Exceptions (#1812) + +#### Improvements +* Include overflow variable in HydroPower constraint (#1903) +* Add total time logging at the end of the simulation (#1908) +* Add STS level constraint to suspect list for infeasible problem analysis (#1891) + +#### For developers +* Use precompiled OR-Tools for Oracle Linux 8 CI (#1893) +* Change version behavior to allow more flexibility (#1898) + +#### Code quality +* Use std::shared_ptr instead of indices for active binding constraints in results (#1887) +* Fix a few compilation warnings (#1880) +* Scratchpad numspace (#1749) + +#### Tests +* Fix invalid index causing segfault in `test-study` test (#1902) + +## Branch 8.8.x (end of support 12/2025) + +### 8.8.5 (05/2024) +#### Bugfix +- [UI] Fix opening a study from the file browser +- Fix crash occurring when duplicate thermal clusters are present in a study (same name) +- Fix formula for "PROFIT BY PLANT" + +### 8.8.4 (03/2024) +#### Bugfix +* Adequacy patch CSR - fix DTG MRG (#1982) +* Fix ts numbers for no gen clusters (#1969) +* Remove unitcount limit for time series generation (#1960) + +### 8.8.3 (02/2024) +#### Bugfix +* Fix an issue where depending on the platform the output archive could contain several entries of the same area and interco files + ### 8.8.2 #### Bugfix * Fix segfault caused by uninitialized `cluster.series.timeseriesNumbers` (#1876). This bug was introduced in v8.8.1 by #1752 From 8d6cdc4156357f630babc524ffb49612704f6306 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Fri, 7 Jun 2024 09:08:52 +0200 Subject: [PATCH 012/127] Remove state from hydro ventilation (#2143) **State** type is passed to the hydro ventilation. The object **state** is used by the hydro ventilation to reach the weekly optimization problem, in order to update the hydro initial level of a MC year. This important update is hidden in the depth of the code whereas it should be more highlighted (when a year starts). Furthermore, removing state alleviates a bit the hydro ventilation, already too complicated. Eventually, removing dependency of class **HydroManagement** to **State** allows to : - highlight the update of hydro initial level when beginning a year - loose a dependency to **State** --- .../solver/hydro/management/management.h | 7 ++----- src/solver/hydro/management/daily.cpp | 17 +++++------------ src/solver/hydro/management/management.cpp | 3 +-- src/solver/simulation/adequacy.cpp | 1 + src/solver/simulation/common-eco-adq.cpp | 17 +++++++++++++++++ src/solver/simulation/economy.cpp | 1 + .../antares/solver/simulation/common-eco-adq.h | 4 ++++ .../antares/solver/simulation/solver.hxx | 1 - 8 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/solver/hydro/include/antares/solver/hydro/management/management.h b/src/solver/hydro/include/antares/solver/hydro/management/management.h index 29f64fbd93..78f3d4e6ea 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -112,7 +112,6 @@ class HydroManagement final //! Perform the hydro ventilation void makeVentilation(double* randomReservoirLevel, - Solver::Variable::State& state, uint y, Antares::Data::Area::ScratchMap& scratchmap); @@ -152,12 +151,10 @@ class HydroManagement final // \return The total inflow for the whole year double prepareMonthlyTargetGenerations(Data::Area& area, TmpDataByArea& data); - void prepareDailyOptimalGenerations(Solver::Variable::State& state, - uint y, + void prepareDailyOptimalGenerations(uint y, Antares::Data::Area::ScratchMap& scratchmap); - void prepareDailyOptimalGenerations(Solver::Variable::State& state, - Data::Area& area, + void prepareDailyOptimalGenerations(Data::Area& area, uint y, Antares::Data::Area::ScratchMap& scratchmap); diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index 649de96f5d..8391b523d0 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -40,7 +40,6 @@ #include "antares/solver/hydro/daily2/h2o2_j_fonctions.h" #include "antares/solver/hydro/management/management.h" #include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/variable/state.h" using namespace Yuni; @@ -220,10 +219,9 @@ struct DebugData }; inline void HydroManagement::prepareDailyOptimalGenerations( - Solver::Variable::State& state, - Data::Area& area, - uint y, - Antares::Data::Area::ScratchMap& scratchmap) + Data::Area& area, + uint y, + Antares::Data::Area::ScratchMap& scratchmap) { const auto srcinflows = area.hydro.series->storage.getColumn(y); @@ -546,10 +544,6 @@ inline void HydroManagement::prepareDailyOptimalGenerations( H2O2_J_Free(problem); } - uint firstDaySimu = parameters_.simulationDays.first; - state.problemeHebdo->previousSimulationFinalLevel[area.index] - = ventilationResults.NiveauxReservoirsDebutJours[firstDaySimu] * reservoirCapacity; - if (debugData) { debugData->writeDailyDebugData(calendar_, initReservoirLvlMonth, y, area.name); @@ -557,11 +551,10 @@ inline void HydroManagement::prepareDailyOptimalGenerations( } } -void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::State& state, - uint y, +void HydroManagement::prepareDailyOptimalGenerations(uint y, Antares::Data::Area::ScratchMap& scratchmap) { areas_.each([&](Data::Area& area) - { prepareDailyOptimalGenerations(state, area, y, scratchmap); }); + { prepareDailyOptimalGenerations(area, y, scratchmap); }); } } // namespace Antares diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 5d8fb79d47..fe9311280d 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -519,7 +519,6 @@ bool HydroManagement::checksOnGenerationPowerBounds(uint year) const } void HydroManagement::makeVentilation(double* randomReservoirLevel, - Solver::Variable::State& state, uint y, Antares::Data::Area::ScratchMap& scratchmap) { @@ -534,7 +533,7 @@ void HydroManagement::makeVentilation(double* randomReservoirLevel, prepareEffectiveDemand(); prepareMonthlyOptimalGenerations(randomReservoirLevel, y); - prepareDailyOptimalGenerations(state, y, scratchmap); + prepareDailyOptimalGenerations(y, scratchmap); } } // namespace Antares diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index 5d3a54b261..f4e7f433d7 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -136,6 +136,7 @@ bool Adequacy::year(Progression::Task& progression, currentProblem.year = state.year; PrepareRandomNumbers(study, currentProblem, randomForYear); + SetInitialHydroLevel(study, currentProblem, hydroVentilationResults); state.startANewYear(); diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index 8abcb0cb98..b413b632d5 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -395,6 +395,23 @@ void PrepareRandomNumbers(Data::Study& study, }); } + +void SetInitialHydroLevel(Data::Study& study, + PROBLEME_HEBDO& problem, + const HYDRO_VENTILATION_RESULTS& hydroVentilationResults) +{ + uint firstDaySimu = study.parameters.simulationDays.first; + study.areas.each([&](Data::Area& area) + { + if (area.hydro.reservoirManagement) + { + double capacity = area.hydro.reservoirCapacity; + problem.previousSimulationFinalLevel[area.index] = + hydroVentilationResults[area.index].NiveauxReservoirsDebutJours[firstDaySimu] * capacity; + } + }); +} + void BuildThermalPartOfWeeklyProblem(Data::Study& study, PROBLEME_HEBDO& problem, const int PasDeTempsDebut, diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 558c4f2095..0ffdf71d7b 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -126,6 +126,7 @@ bool Economy::year(Progression::Task& progression, currentProblem.year = state.year; PrepareRandomNumbers(study, currentProblem, randomForYear); + SetInitialHydroLevel(study, currentProblem, hydroVentilationResults); state.startANewYear(); diff --git a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h index 2110c4cbe9..14d260af09 100644 --- a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h +++ b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h @@ -56,6 +56,10 @@ void PrepareRandomNumbers(Data::Study& study, PROBLEME_HEBDO& problem, yearRandomNumbers& randomForYear); +void SetInitialHydroLevel(Data::Study& study, + PROBLEME_HEBDO& problem, + const HYDRO_VENTILATION_RESULTS& hydroVentilationResults); + void BuildThermalPartOfWeeklyProblem(Data::Study& study, PROBLEME_HEBDO& problem, const int PasDeTempsDebut, diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 70d88c47af..dc2a7d4e09 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -172,7 +172,6 @@ public: // 4 - Hydraulic ventilation pDurationCollector("hydro_ventilation") << [&] { hydroManagement.makeVentilation(randomReservoirLevel, - state[numSpace], y, scratchmap); }; From a121c7571a4b6e7fed2904b325aa8127dd25261e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 10 Jun 2024 10:59:09 +0200 Subject: [PATCH 013/127] Add `/D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR` to fix segfault (#2151) --- src/cmake/common-settings.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmake/common-settings.cmake b/src/cmake/common-settings.cmake index b659a5f46c..23326f6158 100644 --- a/src/cmake/common-settings.cmake +++ b/src/cmake/common-settings.cmake @@ -11,7 +11,7 @@ if (NOT WIN32) set(COMMON_GCC_FLAGS "${COMMON_GCC_FLAGS} -Werror=return-type") endif() set(COMMON_MSVC_FLAGS "/W3 /MP4") -set(COMMON_MSVC_FLAGS "${COMMON_MSVC_FLAGS} /we4715 /we4716") #adding no return or no return for all code paths as errors +set(COMMON_MSVC_FLAGS "${COMMON_MSVC_FLAGS} /we4715 /we4716 /D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR") #adding no return or no return for all code paths as errors set(ADDITIONAL_C_FLAGS " -Wconversion -Wmissing-prototypes -Wstrict-prototypes") set(ADDITIONAL_C_FLAGS "${ADDITIONAL_C_FLAGS} -Wmissing-noreturn -Wpacked -Wredundant-decls -Wbad-function-cast -W -Wcast-align -Wcast-qual -Wsign-compare -fno-exceptions -Wdeclaration-after-statement") From f1cfbc0a1d3f75928d52a426d536df42aca3e141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 10 Jun 2024 17:07:22 +0200 Subject: [PATCH 014/127] Remove unused arrays & variables from `RESULTATS_HORAIRES` (#2147) Many `*Up`, `*Down`, `*Any` are unused. Remove them & allocations to simplify code and hopefully reduce memory footprint at runtime. --- .../opt_gestion_des_bornes_cas_lineaire.cpp | 3 -- .../sim_structure_probleme_economique.h | 17 ----------- .../simulation/sim_alloc_probleme_hebdo.cpp | 30 +------------------ 3 files changed, 1 insertion(+), 49 deletions(-) diff --git a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp index dda3b10423..5bdbeef705 100644 --- a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp @@ -471,9 +471,6 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob .ValeursHorairesDeDefaillanceNegative[pdtHebdo]); AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = adresseDuResultat; } - - problemeHebdo->ResultatsHoraires[pays].ValeursHorairesDeDefaillanceEnReserve[pdtHebdo] - = 0.0; } } diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h index 307be5b068..8f74ccb94a 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h @@ -250,9 +250,6 @@ struct PDISP_ET_COUTS_HORAIRES_PAR_PALIER std::vector CoutHoraireDeProductionDuPalierThermique; - std::vector CoutHoraireDuPalierThermiqueUp; - std::vector CoutHoraireDuPalierThermiqueDown; - std::vector NombreMaxDeGroupesEnMarcheDuPalierThermique; std::vector NombreMinDeGroupesEnMarcheDuPalierThermique; }; @@ -302,8 +299,6 @@ struct ENERGIES_ET_PUISSANCES_HYDRAULIQUES double PenalisationDeLaVariationDeProductionHydrauliqueSurVariationMax; double WeeklyWaterValueStateRegular; - double WeeklyWaterValueStateUp; - double WeeklyWaterValueStateDown; bool TurbinageEntreBornes; bool SansHeuristique; @@ -405,9 +400,6 @@ struct PRODUCTION_THERMIQUE_OPTIMALE { std::vector ProductionThermiqueDuPalier; - std::vector ProductionThermiqueDuPalierUp; - std::vector ProductionThermiqueDuPalierDown; - std::vector NombreDeGroupesEnMarcheDuPalier; std::vector NombreDeGroupesQuiDemarrentDuPalier; @@ -423,20 +415,11 @@ struct RESULTATS_HORAIRES std::vector ValeursHorairesLmrViolations; // adq patch lmr violations std::vector ValeursHorairesSpilledEnergyAfterCSR; // adq patch spillage after CSR std::vector ValeursHorairesDtgMrgCsr; // adq patch DTG MRG after CSR - std::vector ValeursHorairesDeDefaillancePositiveUp; - std::vector ValeursHorairesDeDefaillancePositiveDown; - std::vector ValeursHorairesDeDefaillancePositiveAny; std::vector ValeursHorairesDeDefaillanceNegative; - std::vector ValeursHorairesDeDefaillanceNegativeUp; - std::vector ValeursHorairesDeDefaillanceNegativeDown; - std::vector ValeursHorairesDeDefaillanceNegativeAny; - std::vector ValeursHorairesDeDefaillanceEnReserve; std::vector PompageHoraire; std::vector TurbinageHoraire; - std::vector TurbinageHoraireUp; - std::vector TurbinageHoraireDown; std::vector niveauxHoraires; std::vector valeurH2oHoraire; diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index aa1a5c90e3..860d2b8bfe 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -387,26 +387,11 @@ void SIM_AllocateAreas(PROBLEME_HEBDO& problem, 0.); // adq patch problem.ResultatsHoraires[k].ValeursHorairesDtgMrgCsr.assign(NombreDePasDeTemps, 0.); // adq patch - problem.ResultatsHoraires[k] - .ValeursHorairesDeDefaillancePositiveUp.assign(NombreDePasDeTemps, 0.); - problem.ResultatsHoraires[k] - .ValeursHorairesDeDefaillancePositiveDown.assign(NombreDePasDeTemps, 0.); - problem.ResultatsHoraires[k] - .ValeursHorairesDeDefaillancePositiveAny.assign(NombreDePasDeTemps, 0.); + problem.ResultatsHoraires[k].ValeursHorairesDeDefaillanceNegative.assign(NombreDePasDeTemps, 0.); - problem.ResultatsHoraires[k] - .ValeursHorairesDeDefaillanceNegativeUp.assign(NombreDePasDeTemps, 0.); - problem.ResultatsHoraires[k] - .ValeursHorairesDeDefaillanceNegativeDown.assign(NombreDePasDeTemps, 0.); - problem.ResultatsHoraires[k] - .ValeursHorairesDeDefaillanceNegativeAny.assign(NombreDePasDeTemps, 0.); - problem.ResultatsHoraires[k] - .ValeursHorairesDeDefaillanceEnReserve.assign(NombreDePasDeTemps, 0.); problem.ResultatsHoraires[k].TurbinageHoraire.assign(NombreDePasDeTemps, 0.); problem.ResultatsHoraires[k].PompageHoraire.assign(NombreDePasDeTemps, 0.); - problem.ResultatsHoraires[k].TurbinageHoraireUp.assign(NombreDePasDeTemps, 0.); - problem.ResultatsHoraires[k].TurbinageHoraireDown.assign(NombreDePasDeTemps, 0.); problem.ResultatsHoraires[k].CoutsMarginauxHoraires.assign(NombreDePasDeTemps, 0.); problem.ResultatsHoraires[k].niveauxHoraires.assign(NombreDePasDeTemps, 0.); problem.ResultatsHoraires[k].valeurH2oHoraire.assign(NombreDePasDeTemps, 0.); @@ -438,25 +423,12 @@ void SIM_AllocateAreas(PROBLEME_HEBDO& problem, problem.PaliersThermiquesDuPays[k] .PuissanceDisponibleEtCout[j] .NombreMinDeGroupesEnMarcheDuPalierThermique.assign(NombreDePasDeTemps, 0); - - problem.PaliersThermiquesDuPays[k] - .PuissanceDisponibleEtCout[j] - .CoutHoraireDuPalierThermiqueUp.assign(NombreDePasDeTemps, 0.); - problem.PaliersThermiquesDuPays[k] - .PuissanceDisponibleEtCout[j] - .CoutHoraireDuPalierThermiqueDown.assign(NombreDePasDeTemps, 0.); } for (unsigned j = 0; j < NombreDePasDeTemps; j++) { problem.ResultatsHoraires[k].ProductionThermique[j].ProductionThermiqueDuPalier.assign( nbPaliers, 0.); - problem.ResultatsHoraires[k] - .ProductionThermique[j] - .ProductionThermiqueDuPalierUp.assign(nbPaliers, 0.); - problem.ResultatsHoraires[k] - .ProductionThermique[j] - .ProductionThermiqueDuPalierDown.assign(nbPaliers, 0.); problem.ResultatsHoraires[k] .ProductionThermique[j] .NombreDeGroupesEnMarcheDuPalier.assign(nbPaliers, 0.); From 7b9a058ef400c9551e1a82fccb29a104ffdbbf57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 11 Jun 2024 15:10:37 +0200 Subject: [PATCH 015/127] Use sirius-solver@antares-integration-v1.5 (#2148) https://github.com/rte-france/sirius-solver/releases/tag/antares-integration-v1.5 --- src/ports/sirius-solver/portfile.cmake | 4 ++-- src/ports/sirius-solver/vcpkg.json | 2 +- src/vcpkg.json | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ports/sirius-solver/portfile.cmake b/src/ports/sirius-solver/portfile.cmake index 30cce62622..287994c152 100644 --- a/src/ports/sirius-solver/portfile.cmake +++ b/src/ports/sirius-solver/portfile.cmake @@ -1,8 +1,8 @@ vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO "rte-france/sirius-solver" - REF "antares-integration-v1.4" - SHA512 1eecb351b32490a82a2f93bf91e77ea4fd55cffc92c466b4136314e70d8a70328e4fda5257a46c08c431fd7013475050bc3908fcedee4fbdd746ed1ab6cb0efd + REF "antares-integration-v1.5" + SHA512 19c6c156861bdeb58c2f17f703124d52020c79f9b81734057bf1bc5dff3dbc464179f99aeab6c8c44a84de1f84ed8f4929f9a919d2bf8bd49ac737f656088e19 HEAD_REF main ) diff --git a/src/ports/sirius-solver/vcpkg.json b/src/ports/sirius-solver/vcpkg.json index 8e4a0a36df..ded804499d 100644 --- a/src/ports/sirius-solver/vcpkg.json +++ b/src/ports/sirius-solver/vcpkg.json @@ -1,6 +1,6 @@ { "name": "sirius-solver", - "version": "1.4", + "version": "1.5", "port-version": 0, "description": "Sirius solver", "dependencies": [ diff --git a/src/vcpkg.json b/src/vcpkg.json index 011ede41ad..fdd3963fd5 100644 --- a/src/vcpkg.json +++ b/src/vcpkg.json @@ -12,7 +12,8 @@ }, "dependencies": [ { - "name": "sirius-solver" + "name": "sirius-solver", + "version>=": "1.5" }, { "name": "wxwidgets", From 9cde7e57b64c07984b06894fb9fae31b47c162b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 11 Jun 2024 15:17:00 +0200 Subject: [PATCH 016/127] Add precision on `playlist_year +/-` properties (generaldata.ini) (#2156) --- docs/user-guide/solver/04-parameters.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/user-guide/solver/04-parameters.md b/docs/user-guide/solver/04-parameters.md index efe0e44ad4..bd46430336 100644 --- a/docs/user-guide/solver/04-parameters.md +++ b/docs/user-guide/solver/04-parameters.md @@ -792,13 +792,15 @@ They are **required** if [user-playlist](#user-playlist) is set to `true`. --- #### playlist_year - **Expected value:** `+ =` or `- =`, followed by a positive integer (example: `playlist_year + = 5`) -- **Required:** **yes**, if [user-playlist](#user-playlist) is set to `true`. +- **Required:** **yes**, if [user-playlist](#user-playlist) is set to `true`, ignored otherwise. - **Usage:** - for every Monte-Carlo year that you want the Antares Simulator to **study**, add the parameter entry `playlist_year + = i`, where `i` is the index of the year. - for every Monte-Carlo year that you want the Antares Simulator to **skip**, add the parameter entry `playlist_year - = i`, where `i` is the index of the year. +_Please note that by convention, the first year has index 0._ + --- #### playlist_year_weight [//]: # (TODO: document this parameter) From f758ed6aadf962367b336358d8d62e8c96a3caad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 14 Jun 2024 15:06:44 +0200 Subject: [PATCH 017/127] Add I/O & doc for CurtailmentSharing::recomputeDTGMRG [ANT-1809] (#2141) --- docs/user-guide/04-migration-guides.md | 1 + src/libs/antares/study/parameters/adq-patch-params.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 354dfa692f..0e5f50726c 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -166,6 +166,7 @@ In file **settings/generaldata.ini**, in section `adequacy patch`, add propertie * `price-taking-order` [string] can take values `DENS` (default value) and `Load`. * `include-hurdle-cost-csr` [bool]. Default value = `false` * `check-csr-cost-function` [bool]. Default value = `false` +* `recompute-dtg-mrg` [bool]. Default value = `false` * `threshold-initiate-curtailment-sharing-rule` [double]. Default value = `0.0` * `threshold-display-local-matching-rule-violations` [double]. Default value = `0.0` * `threshold-csr-variable-bounds-relaxation` [int]. Default value = `3` diff --git a/src/libs/antares/study/parameters/adq-patch-params.cpp b/src/libs/antares/study/parameters/adq-patch-params.cpp index cbce2e51b0..99d0d0db33 100644 --- a/src/libs/antares/study/parameters/adq-patch-params.cpp +++ b/src/libs/antares/study/parameters/adq-patch-params.cpp @@ -71,6 +71,7 @@ void CurtailmentSharing::reset() priceTakingOrder = AdqPatchPTO::isDens; includeHurdleCost = false; checkCsrCostFunction = false; + recomputeDTGMRG = false; resetThresholds(); } @@ -121,6 +122,11 @@ bool CurtailmentSharing::updateFromKeyValue(const Yuni::String& key, const Yuni: { return value.to(checkCsrCostFunction); } + if (key == "recompute-dtg-mrg") + { + return value.to(recomputeDTGMRG); + } + // Thresholds if (key == "threshold-initiate-curtailment-sharing-rule") { @@ -156,6 +162,7 @@ void CurtailmentSharing::addProperties(IniFile::Section* section) const section->add("price-taking-order", PriceTakingOrderToString(priceTakingOrder)); section->add("include-hurdle-cost-csr", includeHurdleCost); section->add("check-csr-cost-function", checkCsrCostFunction); + section->add("recompute-dtg-mrg", recomputeDTGMRG); // Thresholds section->add("threshold-initiate-curtailment-sharing-rule", thresholdRun); From be3301cdb3b2b7ed232db72e68a874c353d51609 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Fri, 14 Jun 2024 16:03:41 +0200 Subject: [PATCH 018/127] Parallel years cleaning : few removal of "numspace" (#2128) See ticket [#1751](https://gopro-tickets.rte-france.com/browse/ANT-1751) For now, just a first analyze of how we could do to isolate **years** (from the simulation and what should not be inside a **year**). We take advantage of this to make some removals of **numSpace**. **Comments** : - **year job** and **simulation** are really intertwined, this is a first and important reason why a **year** are not isolated. For instance, when running a year of simulation, we call a function of the **simulation** object, not of the **year** object. - although what we first thought, **each year job creates a fresh new weekly optimization solver object**. This object solves every week problem, using the previous week's optimization solution as a base. Before creating a solver object, a year first **destroys the previous year's solver** (as well as the start base it holds). - I've heard that CI tests for parallel (currently passed at night run) don't generate the same output results as the same tests run in sequential. We assumed that it was because of the bases. Indeed, if the same simulation year is run starting from 2 different bases, it can lead to different simulation results. But given the previous point, that's not true : the simulation results should be identical whether we run a simulation sequentially or not. We may have broken something in the parallelism by not testing the it on CI. **Goals** : We want to isolate year jobs to make cleaner parallelism. Each year job should be designed so that it can be run in a thread independently from any other year job. In particular, a year job should hold its own memory spaces, and not shared memory as done currently. --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- .../solver/hydro/management/management.h | 1 - src/solver/hydro/management/management.cpp | 2 - src/solver/simulation/adequacy.cpp | 10 +---- src/solver/simulation/economy.cpp | 8 +--- .../antares/solver/simulation/simulation.h | 2 +- .../antares/solver/simulation/solver.hxx | 40 +++++++++---------- .../simulation/sim_calcul_economique.cpp | 2 +- 7 files changed, 23 insertions(+), 42 deletions(-) diff --git a/src/solver/hydro/include/antares/solver/hydro/management/management.h b/src/solver/hydro/include/antares/solver/hydro/management/management.h index 78f3d4e6ea..3050515ca5 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -107,7 +107,6 @@ class HydroManagement final HydroManagement(const Data::AreaList& areas, const Data::Parameters& params, const Date::Calendar& calendar, - unsigned int maxNbYearsInParallel, Solver::IResultWriter& resultWriter); //! Perform the hydro ventilation diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index fe9311280d..b20be5e375 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -117,12 +117,10 @@ double BetaVariable(double a, double b, MersenneTwister& random) HydroManagement::HydroManagement(const Data::AreaList& areas, const Data::Parameters& params, const Date::Calendar& calendar, - unsigned int maxNbYearsInParallel, Solver::IResultWriter& resultWriter): areas_(areas), calendar_(calendar), parameters_(params), - maxNbYearsInParallel_(maxNbYearsInParallel), resultWriter_(resultWriter) { // Ventilation results memory allocation diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index f4e7f433d7..63d8462dfc 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -68,15 +68,7 @@ bool Adequacy::simulationBegin() pProblemesHebdo.resize(pNbMaxPerformedYearsInParallel); for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) { - SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], 168, numSpace); - - assert((uint)nbHoursInAWeek == (uint)pProblemesHebdo[numSpace].NombreDePasDeTemps - && "inconsistency"); - if ((uint)nbHoursInAWeek != (uint)pProblemesHebdo[numSpace].NombreDePasDeTemps) - { - logs.fatal() << "internal error"; - return false; - } + SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], nbHoursInAWeek, numSpace); } } diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 0ffdf71d7b..02fac95314 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -73,13 +73,7 @@ bool Economy::simulationBegin() for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) { - SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], 168, numSpace); - - if ((uint)nbHoursInAWeek != (uint)pProblemesHebdo[numSpace].NombreDePasDeTemps) - { - logs.fatal() << "internal error"; - return false; - } + SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], nbHoursInAWeek, numSpace); auto options = createOptimizationOptions(study); weeklyOptProblems_[numSpace] = Antares::Solver::Optimization::WeeklyOptimization:: diff --git a/src/solver/simulation/include/antares/solver/simulation/simulation.h b/src/solver/simulation/include/antares/solver/simulation/simulation.h index 6d814157d1..bf214beff6 100644 --- a/src/solver/simulation/include/antares/solver/simulation/simulation.h +++ b/src/solver/simulation/include/antares/solver/simulation/simulation.h @@ -45,7 +45,7 @@ void SIM_AllocationProblemeHebdo(const Antares::Data::Study& study, */ void SIM_InitialisationProblemeHebdo(Antares::Data::Study& study, PROBLEME_HEBDO& problem, - int NombreDePasDeTemps, + unsigned int NombreDePasDeTemps, uint numspace); void SIM_RenseignementProblemeHebdo(const Antares::Data::Study& study, diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index dc2a7d4e09..87f38225cc 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -55,7 +55,7 @@ public: randomNumbers& pRandomForParallelYears, bool pPerformCalculations, Data::Study& pStudy, - std::vector& pState, + Variable::State& pState, bool pYearByYear, Benchmarking::DurationCollector& durationCollector, IResultWriter& resultWriter): @@ -75,7 +75,6 @@ public: hydroManagement(study.areas, study.parameters, study.calendar, - study.maxNbYearsInParallel, resultWriter) { hydroHotStart = (study.parameters.initialReservoirLevels.iniLevels == Data::irlHotStart); @@ -96,7 +95,7 @@ private: randomNumbers& randomForParallelYears; bool performCalculations; Data::Study& study; - std::vector& state; + Variable::State& state; bool yearByYear; bool hydroHotStart; Benchmarking::DurationCollector& pDurationCollector; @@ -155,8 +154,7 @@ public: // 1 - Applying random levels for current year if (hydroHotStart && firstSetParallelWithAPerformedYearWasRun) { - randomReservoirLevel = state[numSpace] - .problemeHebdo->previousYearFinalLevels.data(); + randomReservoirLevel = state.problemeHebdo->previousYearFinalLevels.data(); } else { @@ -177,7 +175,7 @@ public: }; // Updating the state - state[numSpace].year = y; + state.year = y; // 5 - Resetting all variables for the output simulation_->variables.yearBegin(y, numSpace); @@ -189,7 +187,7 @@ public: OptimizationStatisticsWriter optWriter(pResultWriter, y); yearFailed[y] = !simulation_->year(progression, - state[numSpace], + state, numSpace, randomForCurrentYear, failedWeekList, @@ -201,7 +199,7 @@ public: // Log failing weeks logFailedWeek(y, study, failedWeekList); - simulation_->variables.yearEndBuild(state[numSpace], y, numSpace); + simulation_->variables.yearEndBuild(state, y, numSpace); // 7 - End of the year, this is the last stade where the variables can retrieve // their data for this year. @@ -1059,19 +1057,19 @@ void ISimulation::loopThroughYears(uint firstYear, // continue; auto task = std::make_shared>( - this, - y, - set_it->yearFailed, - set_it->isFirstPerformedYearOfASet, - pFirstSetParallelWithAPerformedYearWasRun, - numSpace, - randomForParallelYears, - performCalculations, - study, - state, - pYearByYear, - pDurationCollector, - pResultWriter); + this, + y, + set_it->yearFailed, + set_it->isFirstPerformedYearOfASet, + pFirstSetParallelWithAPerformedYearWasRun, + numSpace, + randomForParallelYears, + performCalculations, + study, + state[numSpace], + pYearByYear, + pDurationCollector, + pResultWriter); results.add(Concurrency::AddTask(*pQueueService, task)); } // End loop over years of the current set of parallel years diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 8b921dfec3..c51d8283dc 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -71,7 +71,7 @@ static void importShortTermStorages( void SIM_InitialisationProblemeHebdo(Data::Study& study, PROBLEME_HEBDO& problem, - int NombreDePasDeTemps, + unsigned int NombreDePasDeTemps, uint numspace) { int NombrePaliers; From 6edcad865005d73a8c5d79d6a96515a50bdaa3e0 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:28:15 +0200 Subject: [PATCH 019/127] Remove hydro hotstart (#2131) https://github.com/AntaresSimulatorTeam/Antares_Simulator_Tests_NR/pull/24 Previously, the default value for property `initial-reservoir-levels` was `cold start`. --------- Co-authored-by: Guillaume PIERRE Co-authored-by: Florian OMNES --- docs/user-guide/solver/04-parameters.md | 3 +- docs/user-guide/solver/06-hydro-heuristics.md | 2 +- docs/user-guide/solver/09-appendix.md | 6 +- simtest.json | 2 +- src/libs/antares/study/fwd.cpp | 37 -------- .../antares/study/include/antares/study/fwd.h | 18 ---- .../study/include/antares/study/parameters.h | 11 --- .../antares/study/parts/hydro/container.h | 5 +- .../study/include/antares/study/study.h | 16 ---- src/libs/antares/study/load.cpp | 7 -- src/libs/antares/study/parameters.cpp | 28 ++---- .../antares/study/parts/hydro/container.cpp | 14 +-- src/libs/antares/study/study.cpp | 91 ------------------- src/solver/simulation/adequacy.cpp | 2 - src/solver/simulation/common-hydro-levels.cpp | 49 ++-------- src/solver/simulation/economy.cpp | 2 - .../solver/simulation/common-eco-adq.h | 8 -- .../sim_structure_probleme_economique.h | 2 - .../antares/solver/simulation/solver.h | 2 - .../antares/solver/simulation/solver.hxx | 45 ++------- .../simulation/sim_alloc_probleme_hebdo.cpp | 14 --- .../simulation/sim_calcul_economique.cpp | 18 +--- .../study/parameters/parameters-tests.cpp | 1 - .../windows/options/advanced/advanced.cpp | 63 +------------ .../windows/options/advanced/advanced.h | 7 +- 25 files changed, 46 insertions(+), 407 deletions(-) diff --git a/docs/user-guide/solver/04-parameters.md b/docs/user-guide/solver/04-parameters.md index bd46430336..fc8492a9e4 100644 --- a/docs/user-guide/solver/04-parameters.md +++ b/docs/user-guide/solver/04-parameters.md @@ -588,8 +588,7 @@ _**This section is under construction**_ These parameters are listed under the `[other preferences]` section in the `.ini` file. --- -#### initial-reservoir-levels -[//]: # (TODO: complete the usage paragraph) +#### initial-reservoir-levels (DEPRECATED since 9.2: cold start is default behavior) - **Expected value:** one of the following (case-insensitive): - `cold start` - `hot start` diff --git a/docs/user-guide/solver/06-hydro-heuristics.md b/docs/user-guide/solver/06-hydro-heuristics.md index 4d4de31f48..78ff065933 100644 --- a/docs/user-guide/solver/06-hydro-heuristics.md +++ b/docs/user-guide/solver/06-hydro-heuristics.md @@ -188,6 +188,6 @@ $$V_t^- + S_t \geq \underline{S_t}$$ $$Y - V_t^- \geq 0$$ -[^monthly_allocation]: In the first equation, $S_{t-1}$ is either the initial stock $S_0$ or the final stock of the previous year (hydro hot start) +[^monthly_allocation]: In the first equation, $S_{t-1}$ is equal to initial stock $S_0$ [^daily_allocation]: In the first equation, $S_{t-1}$ is either the initial stock used in M or the final stock of the previous month ($D(m-1)$) diff --git a/docs/user-guide/solver/09-appendix.md b/docs/user-guide/solver/09-appendix.md index 3ab1b49f6d..1f8e24673d 100644 --- a/docs/user-guide/solver/09-appendix.md +++ b/docs/user-guide/solver/09-appendix.md @@ -64,9 +64,9 @@ With `..._MPS` options, the full expression of the faulty problem(s) is printed thus allowing further analysis of the infeasibility issue. -## Details on the "initial-reservoir-levels" parameter -[//]: # (TODO: update this paragraph) -_**This section is under construction**_ +## Details on the "initial-reservoir-levels" parameter (DEPRECATED since 9.2) + +### version 9.2: The reservoir level is now always determined with cold start behavior. This parameter can take the two values "cold start" or "hot start". [default: cold start]. Simulations results may in some circumstances be heavily impacted by this setting, hence proper attention should be paid to its meaning before considering changing the default value. diff --git a/simtest.json b/simtest.json index 9029e0c9bb..422fd8e3bd 100644 --- a/simtest.json +++ b/simtest.json @@ -1,3 +1,3 @@ { - "version": "v9.1.0-rc5" + "version": "v9.2.0a" } diff --git a/src/libs/antares/study/fwd.cpp b/src/libs/antares/study/fwd.cpp index 68dae733e6..100a4b127e 100644 --- a/src/libs/antares/study/fwd.cpp +++ b/src/libs/antares/study/fwd.cpp @@ -91,43 +91,6 @@ const char* SeedToID(SeedIndex seed) return ""; } -// ... Initial reservoir levels ... -InitialReservoirLevels StringToInitialReservoirLevels(const AnyString& text) -{ - if (!text) - { - return irlUnknown; - } - - CString<24, false> s = text; - s.trim(); - s.toLower(); - if (s == "cold start") - { - return irlColdStart; - } - if (s == "hot start") - { - return irlHotStart; - } - - return irlUnknown; -} - -const char* InitialReservoirLevelsToCString(InitialReservoirLevels iniLevels) -{ - switch (iniLevels) - { - case irlColdStart: - return "cold start"; - case irlHotStart: - return "hot start"; - case irlUnknown: - return ""; - } - return ""; -} - // ... Hydro heuristic policy ... HydroHeuristicPolicy StringToHydroHeuristicPolicy(const AnyString& text) { diff --git a/src/libs/antares/study/include/antares/study/fwd.h b/src/libs/antares/study/include/antares/study/fwd.h index 56b6e3982b..6fa2819aca 100644 --- a/src/libs/antares/study/include/antares/study/fwd.h +++ b/src/libs/antares/study/include/antares/study/fwd.h @@ -382,24 +382,6 @@ const char* SeedToCString(SeedIndex seed); */ const char* SeedToID(SeedIndex seed); -// ... Initial reservoir levels ... -enum InitialReservoirLevels -{ - irlColdStart = 0, - irlHotStart, - irlUnknown, -}; - -/*! -** \brief Convert an Initial Reservoir Levels strategy into a text -*/ -const char* InitialReservoirLevelsToCString(InitialReservoirLevels iniLevels); - -/*! -** \brief Convert a text into an Initial Reservoir Levels strategy -*/ -InitialReservoirLevels StringToInitialReservoirLevels(const AnyString& text); - // ... Hydro heuristic policy ... enum HydroHeuristicPolicy { diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index fcbb8b0080..d9a1d467f0 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -463,12 +463,6 @@ class Parameters final RenewableGeneration renewableGeneration; - struct - { - //! Initial reservoir levels - InitialReservoirLevels iniLevels; - } initialReservoirLevels; - struct { //! Hydro heuristic policy @@ -481,11 +475,6 @@ class Parameters final HydroPricingMode hpMode; } hydroPricing; - // In case of hydro hot start and MC years simultaneous run - // ... Answers the question : do all sets of simultaneous years have the same size ? - // (obvious if the parallel mode is not required : answer is yes). - bool allSetsHaveSameSize; - //! Transmission capacities GlobalTransmissionCapacities transmissionCapacities; //! Simplex optimization range (day/week) diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index 5d79c65d30..e7467d9fb7 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -167,10 +167,9 @@ class PartHydro // As this function can be called a lot of times, we pass working variables and returned variables // as arguments, so that we don't have to create them locally (as in a classical function) each // time. -void getWaterValue(const double& level, +double getWaterValue(const double& level, const Matrix& waterValues, - const uint day, - double& waterValueToReturn); + const uint day); // Interpolates a rate from the credit modulation table according to a level double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */, diff --git a/src/libs/antares/study/include/antares/study/study.h b/src/libs/antares/study/include/antares/study/study.h index cbe251805b..709bab62fe 100644 --- a/src/libs/antares/study/include/antares/study/study.h +++ b/src/libs/antares/study/include/antares/study/study.h @@ -421,22 +421,6 @@ class Study: public Yuni::NonCopyable, public LayerData */ void getNumberOfCores(const bool forceParallel, const uint nbYearsParallelForced); - /*! - ** \brief In case hydro hot start is enabled, checking all conditions are met. - ** - ** If hydro hot start is enabled, check that : - ** - For all areas for which reservoir management is enabled : - ** + Their starting level is initialized on the same day - ** + This day is the first day of the simulation calendar - ** - The simulation lasts exactly one year - ** - All batches (or sets) of simultaneous years have the same size (obvious if a parallel run - *is not required : answer is yes). - ** - ** If these conditions are not met, some error message is raised, when attempting to run the - *study. - */ - bool checkHydroHotStart(); - /*! ** \brief Remove timeseries if ts-generator is enabled */ diff --git a/src/libs/antares/study/load.cpp b/src/libs/antares/study/load.cpp index eefe3b2606..dca1b1eb15 100644 --- a/src/libs/antares/study/load.cpp +++ b/src/libs/antares/study/load.cpp @@ -166,13 +166,6 @@ void Study::parameterFiller(const StudyLoadOptions& options) parameters.firstMonthInYear, parameters.leapYear}); - // In case hydro hot start is enabled, check all conditions are met. - // (has to be called after areas load and calendar building) - if (usedByTheSolver && !checkHydroHotStart()) - { - logs.error() << "hydro hot start is enabled, conditions are not met. Aborting"; - } - // Reducing memory footprint reduceMemoryUsage(); } diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index 3ac64a284e..3517b09d21 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -311,15 +311,11 @@ void Parameters::reset() readonly = false; synthesis = true; - // Initial reservoir levels - initialReservoirLevels.iniLevels = irlColdStart; - // Hydro heuristic policy hydroHeuristicPolicy.hhPolicy = hhpAccommodateRuleCurves; // Hydro pricing hydroPricing.hpMode = hpHeuristic; - allSetsHaveSameSize = true; // Shedding strategies power.fluctuations = lssFreeModulations; @@ -810,19 +806,6 @@ static bool SGDIntLoadFamily_OtherPreferences(Parameters& d, d.hydroPricing.hpMode = hpHeuristic; return false; } - if (key == "initial-reservoir-levels") - { - auto iniLevels = StringToInitialReservoirLevels(value); - if (iniLevels != irlUnknown) - { - d.initialReservoirLevels.iniLevels = iniLevels; - return true; - } - logs.warning() << "parameters: invalid initital reservoir levels mode. Got '" << value - << "'. reset to cold start mode."; - d.initialReservoirLevels.iniLevels = irlColdStart; - return false; - } if (key == "number-of-cores-mode") { @@ -1155,6 +1138,15 @@ static bool SGDIntLoadFamily_Legacy(Parameters& d, return true; } + if (key == "initial-reservoir-levels") // ignored since 9.2 + { + if (version >= StudyVersion(9,2)) + logs.warning() << "Option initial-reservoir-levels is deprecated, please remove it from the study"; + else if (value == "hot start") + logs.warning() << "Hydro hot start not supported with this solver, please use a version < 9.2"; + return true; + } + return false; } @@ -1874,8 +1866,6 @@ void Parameters::saveToINI(IniFile& ini) const // Other preferences { auto* section = ini.addSection("other preferences"); - section->add("initial-reservoir-levels", - InitialReservoirLevelsToCString(initialReservoirLevels.iniLevels)); section->add("hydro-heuristic-policy", HydroHeuristicPolicyToCString(hydroHeuristicPolicy.hhPolicy)); section->add("hydro-pricing-mode", HydroPricingModeToCString(hydroPricing.hpMode)); diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index e86b32a568..103d7a83bb 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -938,10 +938,9 @@ bool PartHydro::CheckDailyMaxEnergy(const AnyString& areaName) return ret; } -void getWaterValue(const double& level /* format : in % of reservoir capacity */, +double getWaterValue(const double& level /* format : in % of reservoir capacity */, const Matrix& waterValues, - const uint day, - double& waterValueToReturn) + const uint day) { assert((level >= 0. && level <= 100.) && "getWaterValue function : invalid level"); double levelUp = ceil(level); @@ -949,13 +948,10 @@ void getWaterValue(const double& level /* format : in % of reservoir capacity */ if ((int)(levelUp) == (int)(levelDown)) { - waterValueToReturn = waterValues[(int)(levelUp)][day]; - } - else - { - waterValueToReturn = waterValues[(int)(levelUp)][day] * (level - levelDown) - + waterValues[(int)(levelDown)][day] * (levelUp - level); + return waterValues[(int)(levelUp)][day]; } + return waterValues[(int)(levelUp)][day] * (level - levelDown) + + waterValues[(int)(levelDown)][day] * (levelUp - level); } double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */, diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 8337795ca1..23f547783d 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -500,97 +500,6 @@ void Study::getNumberOfCores(const bool forceParallel, const uint nbYearsParalle // enabled. // Useful for RAM estimation. maxNbYearsInParallel_save = maxNbYearsInParallel; - - // Here we answer the question (useful only if hydro hot start is asked) : do all sets of - // parallel years have the same size ? - if (parameters.initialReservoirLevels.iniLevels == Antares::Data::irlHotStart - && setsOfParallelYears.size() && maxNbYearsInParallel > 1) - { - uint currentSetSize = (uint)setsOfParallelYears[0].size(); - if (setsOfParallelYears.size() > 1) - { - for (uint s = 1; s < setsOfParallelYears.size(); s++) - { - if (setsOfParallelYears[s].size() != currentSetSize) - { - parameters.allSetsHaveSameSize = false; - break; - } - } - } - } // End if hot start -} - -bool Study::checkHydroHotStart() -{ - bool hydroHotStart = (parameters.initialReservoirLevels.iniLevels == irlHotStart); - - // No need to check further if hydro hot start is not required - if (!hydroHotStart) - { - return true; - } - - // Here we answer the question (useful only if hydro hot start is asked) : In case of parallel - // run, do all sets of parallel years have the same size ? - if (maxNbYearsInParallel != 1 && !parameters.allSetsHaveSameSize) - { - logs.error() << "Hot Start Hydro option : conflict with parallelization parameters."; - logs.error() - << "Please update relevant simulation parameters or use Cold Start option. "; - return false; - } - - // Checking calendar conditions - // ... The simulation lasts one year exactly - uint nbDaysInSimulation = parameters.simulationDays.end - parameters.simulationDays.first + 1; - if (nbDaysInSimulation < 364) - { - logs.error() - << "Hot Start Hydro option : simulation calendar must cover one complete year. "; - logs.error() << "Please update data or use Cold Start option."; - return false; - } - - // ... For all areas for which reservoir management is enabled : - // - Their starting level is initialized on the same day - // - This day is the first day of the simulation calendar - const Area::Map::iterator end = areas.end(); - for (Area::Map::iterator i = areas.begin(); i != end; ++i) - { - // Reference to the area - Area* area = i->second; - - // No need to make a check on level initialization when reservoir management - // is not activated for the current area - if (!area->hydro.reservoirManagement) - { - continue; - } - - // Month the reservoir level is initialized according to. - // This month number is given in the civil calendar, from january to december (0 is - // january). - int initLevelOnMonth = area->hydro.initializeReservoirLevelDate; - - // Conversion of the previous month into simulation calendar - uint initLevelOnSimMonth = calendar.mapping.months[initLevelOnMonth]; - - // Previous month's first day in the year - uint initLevelOnSimDay = calendar.months[initLevelOnSimMonth].daysYear.first; - - // Check the day of level initialization is the first day of simulation - if (initLevelOnSimDay != parameters.simulationDays.first) - { - logs.error() - << "Hot Start Hydro option : area '" << area->name - << "' - hydro level must be initialized on the first simulation month. "; - logs.error() << "Please update data or use Cold Start option."; - return false; - } - } // End loop over areas - - return true; } bool Study::initializeRuntimeInfos() diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index 63d8462dfc..2b03f7bcdc 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -361,8 +361,6 @@ bool Adequacy::year(Progression::Task& progression, ++progression; } - updatingAnnualFinalHydroLevel(study.areas, currentProblem); - optWriter.finalize(); finalizeOptimizationStatistics(currentProblem, state); diff --git a/src/solver/simulation/common-hydro-levels.cpp b/src/solver/simulation/common-hydro-levels.cpp index 8564418f62..b322d62dec 100644 --- a/src/solver/simulation/common-hydro-levels.cpp +++ b/src/solver/simulation/common-hydro-levels.cpp @@ -105,12 +105,8 @@ void interpolateWaterValue(const Data::AreaList& areas, RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; - std::vector& waterVal = weeklyResults.valeurH2oHoraire; - - for (uint h = 0; h < nbHoursInAWeek; h++) - { - waterVal[h] = 0.; - } + auto& waterVal = weeklyResults.valeurH2oHoraire; + std::fill(waterVal.begin(), waterVal.end(), 0.); if (!area.hydro.reservoirManagement || !area.hydro.useWaterValue) { @@ -126,17 +122,16 @@ void interpolateWaterValue(const Data::AreaList& areas, std::vector& niv = weeklyResults.niveauxHoraires; - Antares::Data::getWaterValue(problem.previousSimulationFinalLevel[index] * 100 - / reservoirCapacity, - area.hydro.waterValues, - weekFirstDay, - waterVal[0]); + waterVal[0] = Data::getWaterValue(problem.previousSimulationFinalLevel[index] * 100 + / reservoirCapacity, + area.hydro.waterValues, + weekFirstDay); + for (uint h = 1; h < nbHoursInAWeek; h++) { - Antares::Data::getWaterValue(niv[h - 1], - area.hydro.waterValues, - daysOfWeek[h / 24], - waterVal[h]); + waterVal[h] = Data::getWaterValue(niv[h - 1], + area.hydro.waterValues, + daysOfWeek[h / 24]); } }); } @@ -164,28 +159,4 @@ void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& }); } -void updatingAnnualFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& problem) -{ - if (!problem.hydroHotStart) - { - return; - } - - areas.each( - [&](const Data::Area& area) - { - if (!area.hydro.reservoirManagement) - { - return; - } - - uint index = area.index; - - double reservoirCapacity = area.hydro.reservoirCapacity; - - problem.previousYearFinalLevels[index] = problem.previousSimulationFinalLevel[index] - / reservoirCapacity; - }); -} - } // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 02fac95314..934ebc4c2c 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -224,8 +224,6 @@ bool Economy::year(Progression::Task& progression, ++progression; } - updatingAnnualFinalHydroLevel(study.areas, currentProblem); - optWriter.finalize(); finalizeOptimizationStatistics(currentProblem, state); diff --git a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h index 14d260af09..6ea4a9e003 100644 --- a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h +++ b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h @@ -141,14 +141,6 @@ void interpolateWaterValue(const Data::AreaList& areas, */ void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& problem); -/* -** \brief Updating the year final reservoir level, to be used as a start for the year. -** -** \param areas : the areas of study -** \param problem The weekly problem, living over the whole simuation. -*/ -void updatingAnnualFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& problem); - /* ** \brief Compute the weighted average NTC for a link ** diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h index 8f74ccb94a..66400ed678 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h @@ -559,7 +559,6 @@ struct PROBLEME_HEBDO bool YaDeLaReserveJmoins1 = false; - std::vector previousYearFinalLevels; std::vector AllMustRunGeneration; OptimizationStatistics optimizationStatistics[2]; @@ -569,7 +568,6 @@ struct PROBLEME_HEBDO /* Hydro management */ std::vector CoefficientEcretementPMaxHydraulique; - bool hydroHotStart = false; std::vector previousSimulationFinalLevel; /* Results */ diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.h b/src/solver/simulation/include/antares/solver/simulation/solver.h index 29c087759f..fe16b660b9 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver.h @@ -145,8 +145,6 @@ class ISimulation: public Impl uint pNbMaxPerformedYearsInParallel; //! Year by year output results bool pYearByYear; - //! Hydro hot start - bool pHydroHotStart; //! The first set of parallel year(s) with a performed year was already run ? bool pFirstSetParallelWithAPerformedYearWasRun; diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 87f38225cc..adf8c23c4d 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -77,7 +77,6 @@ public: study.calendar, resultWriter) { - hydroHotStart = (study.parameters.initialReservoirLevels.iniLevels == Data::irlHotStart); scratchmap = study.areas.buildScratchMap(numSpace); } @@ -97,7 +96,6 @@ private: Data::Study& study; Variable::State& state; bool yearByYear; - bool hydroHotStart; Benchmarking::DurationCollector& pDurationCollector; IResultWriter& pResultWriter; HydroManagement hydroManagement; @@ -152,14 +150,7 @@ public: double* randomReservoirLevel = nullptr; // 1 - Applying random levels for current year - if (hydroHotStart && firstSetParallelWithAPerformedYearWasRun) - { - randomReservoirLevel = state.problemeHebdo->previousYearFinalLevels.data(); - } - else - { - randomReservoirLevel = randomForCurrentYear.pReservoirLevels; - } + randomReservoirLevel = randomForCurrentYear.pReservoirLevels; // 2 - Preparing the Time-series numbers // removed @@ -265,8 +256,6 @@ inline ISimulation::ISimulation( { pYearByYear = false; } - - pHydroHotStart = (study.parameters.initialReservoirLevels.iniLevels == Data::irlHotStart); } template @@ -765,34 +754,12 @@ void ISimulation::computeRandomNumbers( } } - if (pHydroHotStart) - { - if (!isPerformed || !area.hydro.reservoirManagement) - { - // This initial level should be unused, so -1, as impossible value, is - // suitable. - randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = -1.; - areaIndex++; - return; // Skipping the current area - } - - if (!pFirstSetParallelWithAPerformedYearWasRun) - { - randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = randomLevel; - } - // Else : means the start levels (multiple areas are affected) of a year are - // retrieved from a previous year and - // these levels are updated inside the year job (see year job). - } - else + // Current area's hydro starting (or initial) level computation + // (no matter if the year is performed or not, we always draw a random initial + // reservoir level to ensure the same results) + if (isPerformed) { - // Current area's hydro starting (or initial) level computation - // (no matter if the year is performed or not, we always draw a random initial - // reservoir level to ensure the same results) - if (isPerformed) - { - randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = randomLevel; - } + randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = randomLevel; } areaIndex++; diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index 860d2b8bfe..03126fa752 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -119,20 +119,6 @@ void SIM_AllocationProblemeDonneesGenerales(PROBLEME_HEBDO& problem, problem.ShortTermStorage.resize(nbPays); - problem.previousYearFinalLevels.resize(0); - if (problem.hydroHotStart) - { - for (uint i = 0; i <= nbPays; i++) - { - auto& area = *(study.areas[i]); - if (area.hydro.reservoirManagement) - { - problem.previousYearFinalLevels.assign(nbPays, 0.); - break; - } - } - } - problem.ReserveJMoins1.resize(nbPays); problem.ResultatsHoraires.resize(nbPays); diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index c51d8283dc..155cb6b3bc 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -81,9 +81,6 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, problem.Expansion = (parameters.mode == Data::SimulationMode::Expansion); problem.firstWeekOfSimulation = false; - problem.hydroHotStart = (parameters.initialReservoirLevels.iniLevels - == Antares::Data::irlHotStart); - // gp adq : to be removed if (parameters.adqPatchParams.enabled) { @@ -210,11 +207,6 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, problem.previousSimulationFinalLevel[i] = -1.; - if (!problem.previousYearFinalLevels.empty()) - { - problem.previousYearFinalLevels[i] = -1.; - } - problem.CaracteristiquesHydrauliques[i].WeeklyWaterValueStateRegular = 0.; problem.CaracteristiquesHydrauliques[i].WeeklyGeneratingModulation = 1.; @@ -521,11 +513,11 @@ void SIM_RenseignementProblemeHebdo(const Study& study, if (area.hydro.useWaterValue) { - Antares::Data::getWaterValue( - problem.previousSimulationFinalLevel[k] * 100 / area.hydro.reservoirCapacity, - area.hydro.waterValues, - weekFirstDay, - problem.CaracteristiquesHydrauliques[k].WeeklyWaterValueStateRegular); + problem.CaracteristiquesHydrauliques[k].WeeklyWaterValueStateRegular = + getWaterValue( + problem.previousSimulationFinalLevel[k] * 100 / area.hydro.reservoirCapacity, + area.hydro.waterValues, + weekFirstDay); } if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable > 0) diff --git a/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp b/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp index f690649668..14ee6a4435 100644 --- a/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp +++ b/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp @@ -189,7 +189,6 @@ void Fixture::writeValidFile() threshold-csr-variable-bounds-relaxation = 3 [other preferences] - initial-reservoir-levels = cold start hydro-heuristic-policy = accommodate rule curves hydro-pricing-mode = fast power-fluctuations = free modulations diff --git a/src/ui/simulator/windows/options/advanced/advanced.cpp b/src/ui/simulator/windows/options/advanced/advanced.cpp index 97b0589bd4..a361fc227b 100644 --- a/src/ui/simulator/windows/options/advanced/advanced.cpp +++ b/src/ui/simulator/windows/options/advanced/advanced.cpp @@ -156,14 +156,12 @@ AdvancedParameters::AdvancedParameters(wxWindow* parent) : // Initial reservoir levels { label = Component::CreateLabel(this, wxT("Initial reservoir levels")); - button = new Component::Button(this, wxT("cold start"), "images/16x16/tag.png"); + button = new Component::Button(this, wxT(""), "images/16x16/tag.png"); button->SetBackgroundColour(bgColor); - button->menu(true); - onPopup.bind(this, &AdvancedParameters::onInitialReservoirLevels); button->onPopupMenu(onPopup); + button->caption("hydro hot start deprecated"); s->Add(label, 0, wxRIGHT | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); s->Add(button, 0, wxLEFT | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); - pBtnInitialReservoirLevels = button; } // Hydro heuristic policy { @@ -327,7 +325,6 @@ void AdvancedParameters::onResetToDefault(void*) parameters.timeSeriesAccuracyOnCorrelation &= ~Data::timeSeriesWind; parameters.timeSeriesAccuracyOnCorrelation &= ~Data::timeSeriesSolar; - parameters.initialReservoirLevels.iniLevels = Data::irlColdStart; parameters.hydroHeuristicPolicy.hhPolicy = Data::hhpAccommodateRuleCurves; parameters.hydroPricing.hpMode = Data::hpHeuristic; parameters.power.fluctuations = Data::lssFreeModulations; @@ -375,10 +372,6 @@ void AdvancedParameters::refresh() wxString text; - text = wxStringFromUTF8( - InitialReservoirLevelsToCString(study.parameters.initialReservoirLevels.iniLevels)); - pBtnInitialReservoirLevels->caption(text); - text = wxStringFromUTF8( HydroHeuristicPolicyToCString(study.parameters.hydroHeuristicPolicy.hhPolicy)); pBtnHydroHeuristicPolicy->caption(text); @@ -508,58 +501,6 @@ void AdvancedParameters::onSelectNumericQualityHigh(wxCommandEvent&) } } -void AdvancedParameters::onInitialReservoirLevels(Component::Button&, wxMenu& menu, void*) -{ - wxMenuItem* it; - wxString text; - - text = wxStringFromUTF8(InitialReservoirLevelsToCString(Data::irlColdStart)); - text << wxT(" [default]"); - it = Menu::CreateItem(&menu, wxID_ANY, text, "images/16x16/tag.png"); - menu.Connect(it->GetId(), - wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler(AdvancedParameters::onSelectColdStart), - nullptr, - this); - - text.clear(); - text << wxStringFromUTF8(InitialReservoirLevelsToCString(Data::irlHotStart)); - it = Menu::CreateItem(&menu, wxID_ANY, text, "images/16x16/tag.png"); - menu.Connect(it->GetId(), - wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler(AdvancedParameters::onSelectHotStart), - nullptr, - this); -} - -void AdvancedParameters::onSelectColdStart(wxCommandEvent&) -{ - if (not CurrentStudyIsValid()) - return; - auto& study = *GetCurrentStudy(); - - if (study.parameters.initialReservoirLevels.iniLevels != Data::irlColdStart) - { - study.parameters.initialReservoirLevels.iniLevels = Data::irlColdStart; - MarkTheStudyAsModified(); - refresh(); - } -} - -void AdvancedParameters::onSelectHotStart(wxCommandEvent&) -{ - if (not CurrentStudyIsValid()) - return; - auto& study = *GetCurrentStudy(); - - if (study.parameters.initialReservoirLevels.iniLevels != Data::irlHotStart) - { - study.parameters.initialReservoirLevels.iniLevels = Data::irlHotStart; - MarkTheStudyAsModified(); - refresh(); - } -} - // ... Hydro heuristic policy void AdvancedParameters::onHydroHeuristicPolicy(Component::Button&, wxMenu& menu, void*) { diff --git a/src/ui/simulator/windows/options/advanced/advanced.h b/src/ui/simulator/windows/options/advanced/advanced.h index a42d87c9c8..1410d05595 100644 --- a/src/ui/simulator/windows/options/advanced/advanced.h +++ b/src/ui/simulator/windows/options/advanced/advanced.h @@ -69,11 +69,7 @@ class AdvancedParameters final : public wxDialog void onNumericQuality(Component::Button&, wxMenu&, void*, Data::TimeSeriesType ts); void onSelectNumericQualityStandard(wxCommandEvent& evt); void onSelectNumericQualityHigh(wxCommandEvent& evt); - - void onInitialReservoirLevels(Component::Button&, wxMenu&, void*); - void onSelectHotStart(wxCommandEvent& evt); - void onSelectColdStart(wxCommandEvent& evt); - + void onHydroHeuristicPolicy(Component::Button&, wxMenu& menu, void*); void onSelectAccomodateRuleCurves(wxCommandEvent& evt); void onSelectMaximizeGeneration(wxCommandEvent& evt); @@ -115,7 +111,6 @@ class AdvancedParameters final : public wxDialog Component::Button* pBtnNumericQualityWind; Component::Button* pBtnNumericQualitySolar; Component::Button* pBtnPowerFluctuations; - Component::Button* pBtnInitialReservoirLevels; Component::Button* pBtnHydroHeuristicPolicy; Component::Button* pBtnHydroPricing; Component::Button* pBtnSheddingPolicy; From 08003e3275588c4dff4edb7767951e0063f0ed85 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:16:08 +0200 Subject: [PATCH 020/127] Move data validation to specialized functions [ANT-1213] (#2149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The goal of this PR is to separate loading and validation of data. This separation will allow to have a modular loading. Slight change for admissible values of reservoir capacity (from ]1e-6, +oo[ to ]0, +oo[). --------- Co-authored-by: Florian Omnès Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- src/libs/antares/study/area/list.cpp | 2 + .../antares/study/parts/hydro/container.h | 14 +- .../antares/study/parts/hydro/prepro.h | 3 +- .../antares/study/parts/hydro/container.cpp | 600 ++++++------------ .../parts/hydro/hydromaxtimeseriesreader.cpp | 34 +- src/libs/antares/study/parts/hydro/prepro.cpp | 107 ++-- 6 files changed, 270 insertions(+), 490 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index e7bd727287..417e60bae4 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -944,6 +944,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, // if changes are required, please update reloadXCastData() buffer.clear() << study.folderInput << SEP << "hydro" << SEP << "prepro"; ret = area.hydro.prepro->loadFromFolder(study, area.id, buffer.c_str()) && ret; + ret = area.hydro.prepro->validate(area.id) && ret; } auto* hydroSeries = area.hydro.series; @@ -1160,6 +1161,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) logs.info() << "Loading global hydro data..."; buffer.clear() << pStudy.folderInput << SEP << "hydro"; ret = PartHydro::LoadFromFolder(pStudy, buffer) && ret; + ret = PartHydro::validate(pStudy) && ret; } // Thermal data, specific to areas diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index e7467d9fb7..0297540a4d 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -52,7 +52,6 @@ class PartHydro pumpMod, }; -public: /*! ** \brief Load data for hydro container from a folder ** @@ -61,6 +60,13 @@ class PartHydro */ static bool LoadFromFolder(Study& study, const AnyString& folder); + /*! + ** \brief Check and validate the loaded datas + ** + ** \return A non-zero value if the operation succeeded, 0 otherwise + */ + static bool validate(Study& study); + /*! ** \brief Save data from several containers to a folder (except data for the prepro and *time-series) @@ -71,7 +77,6 @@ class PartHydro */ static bool SaveToFolder(const AreaList& areas, const AnyString& folder); -public: /*! ** \brief Default Constructor */ @@ -100,7 +105,6 @@ class PartHydro bool CheckDailyMaxEnergy(const AnyString& areaName); -public: //! Inter-daily breakdown (previously called Smoothing Factor or alpha) double interDailyBreakdown; //! Intra-daily modulation @@ -161,6 +165,10 @@ class PartHydro Matrix dailyNbHoursAtGenPmax; Matrix dailyNbHoursAtPumpPmax; +private: + static bool checkReservoirLevels(const Study& study); + static bool checkProperties(Study& study); + }; // class PartHydro // Interpolates a water value from a table according to a level and a day. diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h b/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h index dbc015ecce..b35798f862 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h @@ -95,8 +95,9 @@ class PreproHydro ** \param folder The source folder (ex: `input/hydro/prepro`) ** \return A non-zero value if the operation succeeded, 0 otherwise */ - bool loadFromFolder(Study& s, const AreaName& areaID, const char folder[]); + bool loadFromFolder(Study& s, const AreaName& areaID, const std::string& folder); + bool validate(const std::string& areaID); /*! ** \brief Save hydro settings for the prepro into a folder ** diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 103d7a83bb..0343c2878f 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -106,6 +106,37 @@ void PartHydro::reset() } } +template +static bool loadProperties(Study& study, + IniFile::Property* property, + const std::string& filename, + T PartHydro::*ptr) +{ + if (!property) + return false; + + bool ret = true; + + // Browse all properties + for (; property; property = property->next) + { + AreaName id = property->key; + id.toLower(); + + Area* area = study.areas.find(id); + if (area) + { + ret = property->value.to(area->hydro.*ptr) && ret; + } + else + { + logs.warning() << filename << ": `" << id << "`: Unknown area"; + return false; + } + } + return ret; +} + bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) { auto& buffer = study.bufferLoadingTS; @@ -200,46 +231,6 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) Matrix<>::optFixedSize, &study.dataBuffer) && ret; - - if (study.usedByTheSolver) - { - auto& col = area.hydro.inflowPattern[0]; - bool errorInflow = false; - for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) - { - if (col[day] < 0 && !errorInflow) - { - logs.error() << area.name << ": invalid inflow value"; - errorInflow = true; - ret = false; - } - } - bool errorLevels = false; - auto& colMin = area.hydro.reservoirLevel[minimum]; - auto& colAvg = area.hydro.reservoirLevel[average]; - auto& colMax = area.hydro.reservoirLevel[maximum]; - for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) - { - if (!errorLevels - && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] - || colAvg[day] > 100 || colMax[day] > 100)) - { - logs.error() << area.name << ": invalid reservoir level value"; - errorLevels = true; - ret = false; - } - } - - for (int i = 0; i < 101; i++) - { - if ((area.hydro.creditModulation[i][0] < 0) - || (area.hydro.creditModulation[i][1] < 0)) - { - logs.error() << area.name << ": invalid credit modulation value"; - ret = false; - } - } - } }); IniFile ini; @@ -248,432 +239,217 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) return false; } - const char* const sectionName = "inter-daily-breakdown"; + if (IniFile::Section* section = ini.find("inter-daily-breakdown")) + { + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::interDailyBreakdown) && ret; + } - IniFile::Section* section; - IniFile::Property* property; + if (IniFile::Section* section = ini.find("intra-daily-modulation")) + { + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::intraDailyModulation) && ret; + } - if ((section = ini.find(sectionName))) + if (IniFile::Section* section = ini.find("reservoir")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - Area* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.interDailyBreakdown) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirManagement) && ret; } - if ((section = ini.find("intra-daily-modulation"))) + if (IniFile::Section* section = ini.find("reservoir capacity")) { - if ((property = section->firstProperty)) - { - AreaName id; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirCapacity) && ret; + } - // Browse all properties - for (; property; property = property->next) - { - id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.intraDailyModulation) && ret; - if (area->hydro.intraDailyModulation < 1.) - { - logs.error() - << area->id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " - << area->hydro.intraDailyModulation << " (truncated to 1)"; - area->hydro.intraDailyModulation = 1.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + if (IniFile::Section* section = ini.find("follow load")) + { + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::followLoadModulations) && ret; } - if ((section = ini.find("reservoir"))) + if (IniFile::Section* section = ini.find("use water")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.reservoirManagement) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useWaterValue) && ret; } - if ((section = ini.find("reservoir capacity"))) + if (IniFile::Section* section = ini.find("hard bounds")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.reservoirCapacity) && ret; - if (area->hydro.reservoirCapacity < 1e-6) - { - logs.error() << area->id << ": Invalid reservoir capacity."; - area->hydro.reservoirCapacity = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::hardBoundsOnRuleCurves) && ret; } - // Check on reservoir capacity (has to be done after reservoir management and capacity reading, - // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving - // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and - // capacity = 0 because of further division by capacity. reservoir management = no and capacity - // = 0 is possible (no use of capacity further) - study.areas.each( - [&](Data::Area& area) - { - if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) - { - logs.error() << area.name - << ": reservoir capacity not defined. Impossible to manage."; - ret = false && ret; - } - }); + if (IniFile::Section* section = ini.find("use heuristic")) + { + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useHeuristicTarget) && ret; + } - if ((section = ini.find("inter-monthly-breakdown"))) + if (IniFile::Section* section = ini.find("power to level")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.intermonthlyBreakdown) && ret; - if (area->hydro.intermonthlyBreakdown < 0) - { - logs.error() << area->id << ": Invalid intermonthly breakdown"; - area->hydro.intermonthlyBreakdown = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::powerToLevel) && ret; } - if ((section = ini.find("follow load"))) + + if (IniFile::Section* section = ini.find("initialize reservoir date")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.followLoadModulations) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::initializeReservoirLevelDate) && ret; } - if ((section = ini.find("use water"))) + + if (IniFile::Section* section = ini.find("use leeway")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.useWaterValue) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useLeeway) && ret; } - if ((section = ini.find("hard bounds"))) + + if (IniFile::Section* section = ini.find("leeway low")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.hardBoundsOnRuleCurves) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayLowerBound) && ret; } - if ((section = ini.find("use heuristic"))) + + if (IniFile::Section* section = ini.find("leeway up")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.useHeuristicTarget) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayUpperBound) && ret; } - if ((section = ini.find("power to level"))) + + if (IniFile::Section* section = ini.find("pumping efficiency")) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.powerToLevel) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) && ret; } - if ((section = ini.find("initialize reservoir date"))) + + return ret; +} + +bool PartHydro::checkReservoirLevels(const Study& study) +{ + bool ret = true; + + for (const auto& [areaName, area] : study.areas) { - if ((property = section->firstProperty)) + if (!study.usedByTheSolver) + return true; + + auto& col = area->hydro.inflowPattern[0]; + bool errorInflow = false; + for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) { - // Browse all properties - for (; property; property = property->next) + if (col[day] < 0 && !errorInflow) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.initializeReservoirLevelDate) && ret; - if (area->hydro.initializeReservoirLevelDate < 0) - { - logs.error() << area->id << ": Invalid initialize reservoir date"; - area->hydro.initializeReservoirLevelDate = 0; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() << areaName << ": invalid inflow value"; + errorInflow = true; + ret = false; } } - } - // Leeways : use leeway bounds (upper and lower) - if ((section = ini.find("use leeway"))) - { - if ((property = section->firstProperty)) + bool errorLevels = false; + auto& colMin = area->hydro.reservoirLevel[minimum]; + auto& colAvg = area->hydro.reservoirLevel[average]; + auto& colMax = area->hydro.reservoirLevel[maximum]; + for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) { - // Browse all properties - for (; property; property = property->next) + if (!errorLevels + && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] + || colAvg[day] > 100 || colMax[day] > 100)) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.useLeeway) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() << areaName << ": invalid reservoir level value"; + errorLevels = true; + ret = false; } } - } - if ((section = ini.find("leeway low"))) - { - if ((property = section->firstProperty)) + + for (int i = 0; i < 101; i++) { - // Browse all properties - for (; property; property = property->next) + if ((area->hydro.creditModulation[i][0] < 0) + || (area->hydro.creditModulation[i][1] < 0)) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.leewayLowerBound) && ret; - if (area->hydro.leewayLowerBound < 0.) - { - logs.error() - << area->id << ": Invalid leeway lower bound. It must be >= 0.0, Got " - << area->hydro.leewayLowerBound; - area->hydro.leewayLowerBound = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() << areaName << ": invalid credit modulation value"; + ret = false; } } } - if ((section = ini.find("leeway up"))) + + return ret; +} + +bool PartHydro::checkProperties(Study& study) +{ + bool ret = true; + + // Check on reservoir capacity (has to be done after reservoir management and capacity reading, + // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving + // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and + // capacity = 0 because of further division by capacity. reservoir management = no and capacity + // = 0 is possible (no use of capacity further) + study.areas.each([&ret](Data::Area& area) { - if ((property = section->firstProperty)) + if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.leewayUpperBound) && ret; - if (area->hydro.leewayUpperBound < 0.) - { - logs.error() - << area->id << ": Invalid leeway upper bound. It must be >= 0.0, Got " - << area->hydro.leewayUpperBound; - area->hydro.leewayUpperBound = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } + logs.error() << area.name + << ": reservoir capacity not defined. Impossible to manage."; + ret = false; } - } - // they are too small (< 1e-6). We cannot allow these areas to have reservoir management = - // true. - study.areas.each( - [&](Data::Area& area) - { - if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) - { - logs.error() << area.id << ": Leeway lower bound greater than leeway upper bound."; - } - }); + if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) + { + logs.error() << area.name + << " : use water value = no conflicts with use heuristic target = no"; + ret = false; + } - if ((section = ini.find("pumping efficiency"))) - { - if ((property = section->firstProperty)) + if (area.hydro.intraDailyModulation < 1.) { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.pumpingEfficiency) && ret; - if (area->hydro.pumpingEfficiency < 0) - { - logs.error() << area->id << ": Invalid pumping efficiency"; - area->hydro.pumpingEfficiency = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } + logs.error() + << area.id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " + << area.hydro.intraDailyModulation << " (truncated to 1)"; + area.hydro.intraDailyModulation = 1.; } - } - study.areas.each( - [&](Data::Area& area) - { - if (not area.hydro.useHeuristicTarget && not area.hydro.useWaterValue) - { - logs.error() << area.name - << " : use water value = no conflicts with use heuristic target = no"; - ret = false && ret; - } - }); + if (area.hydro.reservoirCapacity < 0) + { + logs.error() << area.id << ": Invalid reservoir capacity."; + area.hydro.reservoirCapacity = 0.; + } + + if (area.hydro.intermonthlyBreakdown < 0) + { + logs.error() << area.id << ": Invalid intermonthly breakdown"; + area.hydro.intermonthlyBreakdown = 0.; + } + + if (area.hydro.initializeReservoirLevelDate < 0) + { + logs.error() << area.id << ": Invalid initialize reservoir date"; + area.hydro.initializeReservoirLevelDate = 0; + } + + if (area.hydro.leewayLowerBound < 0.) + { + logs.error() + << area.id << ": Invalid leeway lower bound. It must be >= 0.0, Got " + << area.hydro.leewayLowerBound; + area.hydro.leewayLowerBound = 0.; + } + + if (area.hydro.leewayUpperBound < 0.) + { + logs.error() + << area.id << ": Invalid leeway upper bound. It must be >= 0.0, Got " + << area.hydro.leewayUpperBound; + area.hydro.leewayUpperBound = 0.; + } + + if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) + { + logs.error() << area.id << ": Leeway lower bound greater than leeway upper bound."; + } + + if (area.hydro.pumpingEfficiency < 0) + { + logs.error() << area.id << ": Invalid pumping efficiency"; + area.hydro.pumpingEfficiency = 0.; + } + }); return ret; } +bool PartHydro::validate(Study& study) +{ + bool ret = checkReservoirLevels(study); + return checkProperties(study) && ret; +} + bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) { if (!folder) diff --git a/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp b/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp index b7864e5b31..fa2827fc88 100644 --- a/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp +++ b/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp @@ -47,6 +47,24 @@ HydroMaxTimeSeriesReader::HydroMaxTimeSeriesReader(PartHydro& hydro, dailyMaxPumpAndGen.reset(4U, DAYS_PER_YEAR, true); } +static bool checkPower(const Matrix<>& dailyMaxPumpAndGen, const std::string& areaName) +{ + for (uint i = 0; i < 4U; ++i) + { + auto& col = dailyMaxPumpAndGen[i]; + for (uint day = 0; day < DAYS_PER_YEAR; ++day) + { + if (col[day] < 0. || (i % 2U /*column hours*/ && col[day] > 24.)) + { + logs.error() << areaName << ": invalid power or energy value"; + return false; + } + } + } + + return true; +} + bool HydroMaxTimeSeriesReader::loadDailyMaxPowersAndEnergies(const AnyString& folder, bool usedBySolver) { @@ -90,21 +108,6 @@ bool HydroMaxTimeSeriesReader::loadDailyMaxPowersAndEnergies(const AnyString& fo Matrix<>::optFixedSize, &fileContent) && ret; - - bool errorPowers = false; - for (uint i = 0; i < 4U; ++i) - { - auto& col = dailyMaxPumpAndGen[i]; - for (uint day = 0; day < DAYS_PER_YEAR; ++day) - { - if (!errorPowers && (col[day] < 0. || (i % 2U /*column hours*/ && col[day] > 24.))) - { - logs.error() << areaName_ << ": invalid power or energy value"; - errorPowers = true; - ret = false; - } - } - } } return ret; } @@ -138,6 +141,7 @@ void HydroMaxTimeSeriesReader::copyDailyMaxPumpingEnergy() const bool HydroMaxTimeSeriesReader::read(const AnyString& folder, bool usedBySolver) { bool ret = loadDailyMaxPowersAndEnergies(folder, usedBySolver); + ret = checkPower(dailyMaxPumpAndGen, areaName_) && ret; copyDailyMaxEnergy(); hydro_.series->buildHourlyMaxPowerFromDailyTS(dailyMaxPumpAndGen[genMaxP], dailyMaxPumpAndGen[pumpMaxP]); diff --git a/src/libs/antares/study/parts/hydro/prepro.cpp b/src/libs/antares/study/parts/hydro/prepro.cpp index d8ddb72352..9370c562fa 100644 --- a/src/libs/antares/study/parts/hydro/prepro.cpp +++ b/src/libs/antares/study/parts/hydro/prepro.cpp @@ -145,22 +145,30 @@ bool PreproHydro::saveToFolder(const AreaName& areaID, const char* folder) return false; } -bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const char* folder) +bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::string& folder) { - /* Asserts */ - assert(folder); - assert('\0' != *folder); - enum { mtrxOption = Matrix<>::optFixedSize | Matrix<>::optImmediate, }; + constexpr int maxNbOfLineToLoad = 12; data.resize(hydroPreproMax, 12, true); String& buffer = s.bufferLoadingTS; buffer.clear() << folder << SEP << areaID << SEP << "prepro.ini"; bool ret = PreproHydroLoadSettings(this, buffer); + + buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; + ret = data.loadFromCSVFile(buffer, hydroPreproMax, maxNbOfLineToLoad, mtrxOption, &s.dataBuffer) && ret; + + return ret; +} + +bool PreproHydro::validate(const std::string& areaID) +{ + bool ret = true; + if (intermonthlyCorrelation < 0. || intermonthlyCorrelation > 1.) { logs.error() << "Hydro: Prepro: `" << areaID @@ -175,77 +183,58 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const char* f } } - buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; - ret = data.loadFromCSVFile(buffer, hydroPreproMax, 12, mtrxOption, &s.dataBuffer) && ret; - - if (JIT::enabled) - { - return ret; - } - - // Checks + const auto& col = data[powerOverWater]; + for (unsigned i = 0; i != data.height; ++i) { - auto& col = data[powerOverWater]; - for (uint i = 0; i != data.height; ++i) + const double d = col[i]; + if (d < 0. || d > 1.) { - const double d = col[i]; - if (d < 0. || d > 1.) - { - logs.error() << "Hydro: Prepro: " << areaID - << ": invalid value for ROR (line: " << (i + 1) << ")"; - } + logs.error() << "Hydro: Prepro: " << areaID + << ": invalid value for ROR (line: " << (i + 1) << ")"; } } - { - auto& colMin = data[minimumEnergy]; - auto& colMax = data[maximumEnergy]; + const auto& colMin = data[minimumEnergy]; + const auto& colMax = data[maximumEnergy]; - for (uint i = 0; i != data.height; ++i) + for (unsigned i = 0; i != data.height; ++i) + { + if (colMin[i] < 0.) { - if (colMin[i] < 0.) - { - ret = false; - logs.error() << "Hydro: Prepro: `" << areaID - << "`: minimum energy: At least one value is negative (line: " - << (i + 1) << ')'; - continue; - } - if (colMin[i] > colMax[i]) - { - ret = false; - logs.error() << "Hydro: Prepro: `" << areaID - << "`: the minimum energy must be less than the maximum energy (line: " - << (i + 1) << ')'; - } + ret = false; + logs.error() << "Hydro: Prepro: `" << areaID + << "`: minimum energy: At least one value is negative (line: " + << (i + 1) << ')'; + continue; + } + if (colMin[i] > colMax[i]) + { + ret = false; + logs.error() << "Hydro: Prepro: `" << areaID + << "`: the minimum energy must be less than the maximum energy (line: " + << (i + 1) << ')'; } } + const auto& colExp = data[expectation]; + for (unsigned i = 0; i != data.height; i++) { - auto& colExp = data[expectation]; - - for (uint i = 0; i != data.height; i++) + if (colExp[i] < 0.) { - if (colExp[i] < 0.) - { - ret = false; - logs.error() << "Hydro: Prepro: `" << areaID - << "`: invalid value for expectation (line: " << (i + 1) << ")"; - } + ret = false; + logs.error() << "Hydro: Prepro: `" << areaID + << "`: invalid value for expectation (line: " << (i + 1) << ")"; } } + const auto& colStdDev = data[stdDeviation]; + for (unsigned i = 0; i != data.height; i++) { - auto& colStdDev = data[stdDeviation]; - - for (uint i = 0; i != data.height; i++) + if (colStdDev[i] < 0.) { - if (colStdDev[i] < 0.) - { - ret = false; - logs.error() << "Hydro: Prepro: `" << areaID - << "`: invalid value for standard deviation (line: " << (i + 1) << ")"; - } + ret = false; + logs.error() << "Hydro: Prepro: `" << areaID + << "`: invalid value for standard deviation (line: " << (i + 1) << ")"; } } From 708128c633bcc9645e3b855290f6756126f083c0 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:57:27 +0200 Subject: [PATCH 021/127] Capture explicit var for lambdas (#2170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #2169 --------- Co-authored-by: Florian Omnès --- src/libs/antares/inifile/inifile.cpp | 12 +- src/libs/antares/study/area/list.cpp | 27 ++-- .../BindingConstraintGroupRepository.cpp | 22 +-- .../antares/study/cleaner/cleaner-v20.cpp | 10 +- src/libs/antares/study/filter.cpp | 2 +- .../study/include/antares/study/parameters.h | 19 +-- src/libs/antares/study/load.cpp | 4 +- src/libs/antares/study/parameters.cpp | 15 +- .../study/parts/common/cluster_list.cpp | 4 +- .../antares/study/parts/hydro/allocation.cpp | 41 +++-- .../antares/study/parts/hydro/container.cpp | 88 +++++++---- .../parts/short-term-storage/container.cpp | 36 ++--- src/libs/antares/study/runtime/runtime.cpp | 13 +- .../BindingConstraintsTSNumbersData.cpp | 5 +- .../antares/study/scenario-builder/sets.cpp | 2 +- src/libs/antares/study/study.cpp | 50 +++--- src/libs/antares/study/study.importprepro.cpp | 79 +++++----- src/libs/antares/study/xcast/xcast.cpp | 10 +- src/libs/antares/sys/policy.cpp | 12 +- src/solver/application/application.cpp | 2 +- src/solver/hydro/management/daily.cpp | 6 +- src/solver/hydro/management/management.cpp | 6 +- src/solver/hydro/management/monthly.cpp | 2 +- .../optimisation/post_process_commands.cpp | 2 +- src/solver/simulation/common-eco-adq.cpp | 2 +- src/solver/simulation/common-hydro-levels.cpp | 148 +++++++++--------- src/solver/simulation/common-hydro-remix.cpp | 3 +- .../antares/solver/simulation/solver.hxx | 9 +- .../simulation/sim_calcul_economique.cpp | 2 +- src/solver/ts-generator/generator.cpp | 2 +- src/solver/ts-generator/hydro.cpp | 9 +- src/solver/ts-generator/xcast/xcast.cpp | 4 +- .../include/antares/solver/variable/area.hxx | 6 +- .../variable/surveyresults/surveyresults.cpp | 2 +- 34 files changed, 303 insertions(+), 353 deletions(-) diff --git a/src/libs/antares/inifile/inifile.cpp b/src/libs/antares/inifile/inifile.cpp index e6524920ee..67190a0654 100644 --- a/src/libs/antares/inifile/inifile.cpp +++ b/src/libs/antares/inifile/inifile.cpp @@ -65,7 +65,9 @@ void IniFile::Section::saveToStream(std::ostream& stream_out, uint64_t& written) stream_out << '[' << name << "]\n"; written += 4 /* []\n\n */ + name.size(); - each([&](const IniFile::Property& p) { p.saveToStream(stream_out, written); }); + each([&stream_out, &written](const IniFile::Property& p) { + p.saveToStream(stream_out, written); + }); stream_out << '\n'; } @@ -168,9 +170,9 @@ static std::string getSectionName(const std::string& line) return splitLine[1]; } -static bool isProperty(const std::string& line) +static bool isProperty(std::string_view line) { - return std::ranges::count(line.begin(), line.end(), '=') == 1; + return std::ranges::count(line, '=') == 1; } static IniFile::Property getProperty(std::string line) @@ -264,7 +266,9 @@ bool IniFile::open(const fs::path& filename, bool warnings) void IniFile::saveToStream(std::ostream& stream_out, uint64_t& written) const { - each([&](const IniFile::Section& s) {s.saveToStream(stream_out, written); }); + each([&stream_out, &written](const IniFile::Section& s) { + s.saveToStream(stream_out, written); + }); if (written != 0) { diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index 417e60bae4..219f7ee8aa 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -1275,13 +1275,10 @@ Area* AreaList::findFromPosition(const int x, const int y) const for (auto i = this->areas.rbegin(); i != end; ++i) { auto lastArea = i->second; - if (lastArea->ui) + if (lastArea->ui && std::abs(lastArea->ui->x - x) < nearestDistance + && std::abs(lastArea->ui->y - y) < nearestDistance) { - if (std::abs(lastArea->ui->x - x) < nearestDistance - && std::abs(lastArea->ui->y - y) < nearestDistance) - { - nearestItem = lastArea; - } + nearestItem = lastArea; } } return nearestItem; @@ -1327,14 +1324,12 @@ void AreaListEnsureDataLoadPrepro(AreaList* l) /* Asserts */ assert(l); - l->each( - [&](Data::Area& area) - { - if (!area.load.prepro) - { - area.load.prepro = new Antares::Data::Load::Prepro(); - } - }); + l->each([](Data::Area& area) { + if (!area.load.prepro) + { + area.load.prepro = new Antares::Data::Load::Prepro(); + } + }); } void AreaListEnsureDataSolarPrepro(AreaList* l) @@ -1700,9 +1695,9 @@ void AreaList::removeWindTimeseries() void AreaList::removeThermalTimeseries() { each( - [](Data::Area& area) + [](const Data::Area& area) { - for (auto& c: area.thermal.list.all()) + for (const auto& c: area.thermal.list.all()) { c->series.reset(); } diff --git a/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp b/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp index ce168c7eef..ff181e7ed8 100644 --- a/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp +++ b/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp @@ -60,10 +60,7 @@ bool BindingConstraintGroupRepository::buildFrom(const BindingConstraintsReposit bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const { - bool allConsistent = !std::any_of( - groups_.begin(), - groups_.end(), - [](const auto& group) + bool allConsistent = !std::ranges::any_of(groups_, [](const auto& group) { const auto& constraints = group->constraints(); if (constraints.empty()) @@ -71,9 +68,7 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const return false; } auto width = (*constraints.begin())->RHSTimeSeries().width; - bool isConsistent = std::all_of( - constraints.begin(), - constraints.end(), + bool isConsistent = std::ranges::all_of(constraints, [&width](const std::shared_ptr& bc) { bool sameWidth = bc->RHSTimeSeries().width == width; @@ -94,18 +89,15 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const void BindingConstraintGroupRepository::resizeAllTimeseriesNumbers(unsigned int nb_years) { - std::for_each(groups_.begin(), - groups_.end(), - [&](auto& group) { group->timeseriesNumbers.reset(nb_years); }); + std::ranges::for_each(groups_, [&nb_years](auto& group) + { group->timeseriesNumbers.reset(nb_years); }); } BindingConstraintGroup* BindingConstraintGroupRepository::operator[](const std::string& name) const { - if (auto group = std::find_if(groups_.begin(), - groups_.end(), - [&name](auto& group_of_constraint) - { return group_of_constraint->name() == name; }); - group != groups_.end()) + if (auto group = std::ranges::find_if(groups_, [&name](auto& group_of_constraint) + { return group_of_constraint->name() == name; }); + group != groups_.end()) { return group->get(); } diff --git a/src/libs/antares/study/cleaner/cleaner-v20.cpp b/src/libs/antares/study/cleaner/cleaner-v20.cpp index b3dc2ed6f6..3c8f183be4 100644 --- a/src/libs/antares/study/cleaner/cleaner-v20.cpp +++ b/src/libs/antares/study/cleaner/cleaner-v20.cpp @@ -391,20 +391,20 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) buffer.clear() << infos->folder << "/input/bindingconstraints/bindingconstraints.ini"; if (ini.open(buffer)) { - String v; ini.each( - [&](const IniFile::Section& section) + [&e](const IniFile::Section& section) { auto* property = section.firstProperty; for (; property; property = property->next) { if (property->key == "id") { - v = property->value; + String v = property->value; v.toLower(); - buffer.clear() << "input/bindingconstraints/" << v << ".txt"; - e.add(buffer); + String tmp; + tmp << "input/bindingconstraints/" << v << ".txt"; + e.add(tmp); // Go to the next binding constraint break; } diff --git a/src/libs/antares/study/filter.cpp b/src/libs/antares/study/filter.cpp index aa8916c26c..cb94bf5d30 100644 --- a/src/libs/antares/study/filter.cpp +++ b/src/libs/antares/study/filter.cpp @@ -82,7 +82,7 @@ uint stringIntoDatePrecision(const AnyString& string) uint flag = 0; string.words(",; \r\n\t", - [&](const AnyString& word) -> bool + [&flag](const AnyString& word) -> bool { ShortString16 s = word; s.toLower(); diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index d9a1d467f0..c66cf9757f 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -50,21 +50,6 @@ namespace Antares::Data class Parameters final { public: - //! \name Constructor - //@{ - /*! - ** \brief Default Constructor - ** - ** \warning None of the variables are initialized. You must explicitly use - ** the method `reset()` or the method `loadFromFile()` - ** \see reset() - ** \see loadFromFile() - */ - Parameters(); - //! Destructor - ~Parameters(); - //@} - //! \name Simulation mode //@{ //! Get if the simulation is in economy mode @@ -91,7 +76,7 @@ class Parameters final ** \return True if the settings have been loaded, false if at least one error has occured */ bool loadFromFile(const AnyString& filename, - StudyVersion& version, + const StudyVersion& version, const StudyLoadOptions& options); /*! @@ -493,7 +478,7 @@ class Parameters final //@{ //! No output // This variable is not stored within the study but only used by the solver - bool noOutput; + bool noOutput = false; //@} bool hydroDebug; diff --git a/src/libs/antares/study/load.cpp b/src/libs/antares/study/load.cpp index dca1b1eb15..00214717e8 100644 --- a/src/libs/antares/study/load.cpp +++ b/src/libs/antares/study/load.cpp @@ -286,7 +286,7 @@ bool Study::internalLoadBindingConstraints(const StudyLoadOptions& options) class SetHandlerAreas { public: - SetHandlerAreas(Study& study): + explicit SetHandlerAreas(Study& study): pStudy(study) { } @@ -411,7 +411,7 @@ bool Study::reloadXCastData() // if changes are required, please update AreaListLoadFromFolderSingleArea() bool ret = true; areas.each( - [&](Data::Area& area) + [this, &ret](Data::Area& area) { assert(area.load.prepro); assert(area.solar.prepro); diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index 3517b09d21..a598ee1566 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -54,7 +54,7 @@ static bool ConvertCStrToListTimeSeries(const String& value, uint& v) } value.words(" ,;\t\r\n", - [&](const AnyString& element) -> bool + [&v](const AnyString& element) { ShortString16 word(element); word.toLower(); @@ -208,13 +208,6 @@ const char* SimulationModeToCString(SimulationMode mode) } } -Parameters::Parameters(): - noOutput(false) -{ -} - -Parameters::~Parameters() = default; - bool Parameters::economy() const { return mode == SimulationMode::Economy; @@ -231,8 +224,8 @@ void Parameters::resetSeeds() // For retro-compatibility, the wind ts-generator should produce the // same results than before 3.8. // It must have the same seed than before - auto increment = (unsigned)antaresSeedIncrement; - auto s = (unsigned)antaresSeedDefaultValue; + auto increment = antaresSeedIncrement; + auto s = antaresSeedDefaultValue; seed[seedTsGenWind] = s; // The same way for all others @@ -1981,7 +1974,7 @@ void Parameters::saveToINI(IniFile& ini) const } bool Parameters::loadFromFile(const AnyString& filename, - StudyVersion& version, + const StudyVersion& version, const StudyLoadOptions& options) { // Loading the INI file diff --git a/src/libs/antares/study/parts/common/cluster_list.cpp b/src/libs/antares/study/parts/common/cluster_list.cpp index e00934dfe7..9be5c2ca57 100644 --- a/src/libs/antares/study/parts/common/cluster_list.cpp +++ b/src/libs/antares/study/parts/common/cluster_list.cpp @@ -263,8 +263,8 @@ bool ClusterList::saveDataSeriesToFolder(const AnyString& folder) cons template bool ClusterList::loadDataSeriesFromFolder(Study& s, const AnyString& folder) { - return std::ranges::all_of(allClusters_, - [&](auto c) { return c->loadDataSeriesFromFolder(s, folder); }); + return std::ranges::all_of(allClusters_, [&s, &folder](auto c) + { return c->loadDataSeriesFromFolder(s, folder); }); } template diff --git a/src/libs/antares/study/parts/hydro/allocation.cpp b/src/libs/antares/study/parts/hydro/allocation.cpp index 93ee0ef5d0..597264cf20 100644 --- a/src/libs/antares/study/parts/hydro/allocation.cpp +++ b/src/libs/antares/study/parts/hydro/allocation.cpp @@ -170,31 +170,28 @@ bool HydroAllocation::loadFromFile(const AreaName& referencearea, clear(); IniFile ini; - if (fs::exists(filename) && ini.open(filename)) - { - if (!ini.empty()) - { - AreaName areaname; - ini.each( - [&](const IniFile::Section& section) - { - for (auto* p = section.firstProperty; p; p = p->next) - { - double coeff = p->value.to(); - if (!Utils::isZero(coeff)) - { - areaname = p->key; - areaname.toLower(); - pValues[areaname] = coeff; - } - } - }); - } - } - else + if (!fs::exists(filename) || !ini.open(filename)) { pValues[referencearea] = 1.0; + return true; } + + if (ini.empty()) + return true; + + ini.each([this](const IniFile::Section& section) + { + for (auto* p = section.firstProperty; p; p = p->next) + { + double coeff = p->value.to(); + if (!Utils::isZero(coeff)) + { + AreaName areaname = p->key; + areaname.toLower(); + pValues[areaname] = coeff; + } + } + }); return true; } diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 0343c2878f..d955da1c81 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -144,7 +144,7 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) // Initialize all alpha values to 0 study.areas.each( - [&](Data::Area& area) + [&ret, &buffer, &study, &folder](Data::Area& area) { area.hydro.interDailyBreakdown = 1.; area.hydro.intraDailyModulation = 24.; @@ -462,69 +462,93 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) String buffer; buffer.clear() << folder << SEP << "common" << SEP << "capacity"; + struct AllSections + { + IniFile::Section* s; + IniFile::Section* smod; + IniFile::Section* sIMB; + IniFile::Section* sreservoir; + IniFile::Section* sreservoirCapacity; + IniFile::Section* sFollowLoad; + IniFile::Section* sUseWater; + IniFile::Section* sHardBounds; + IniFile::Section* sInitializeReservoirDate; + IniFile::Section* sUseHeuristic; + IniFile::Section* sUseLeeway; + IniFile::Section* sPowerToLevel; + IniFile::Section* sLeewayLow; + IniFile::Section* sLeewayUp; + IniFile::Section* spumpingEfficiency; + + AllSections(IniFile& ini) : + s(ini.addSection("inter-daily-breakdown")), + smod(ini.addSection("intra-daily-modulation")), + sIMB(ini.addSection("inter-monthly-breakdown")), + sreservoir(ini.addSection("reservoir")), + sreservoirCapacity(ini.addSection("reservoir capacity")), + sFollowLoad(ini.addSection("follow load")), + sUseWater(ini.addSection("use water")), + sHardBounds(ini.addSection("hard bounds")), + sInitializeReservoirDate(ini.addSection("initialize reservoir date")), + sUseHeuristic(ini.addSection("use heuristic")), + sUseLeeway(ini.addSection("use leeway")), + sPowerToLevel(ini.addSection("power to level")), + sLeewayLow(ini.addSection("leeway low")), + sLeewayUp(ini.addSection("leeway up")), + spumpingEfficiency(ini.addSection("pumping efficiency")) + { + } + }; + // Init IniFile ini; - auto* s = ini.addSection("inter-daily-breakdown"); - auto* smod = ini.addSection("intra-daily-modulation"); - auto* sIMB = ini.addSection("inter-monthly-breakdown"); - auto* sreservoir = ini.addSection("reservoir"); - auto* sreservoirCapacity = ini.addSection("reservoir capacity"); - auto* sFollowLoad = ini.addSection("follow load"); - auto* sUseWater = ini.addSection("use water"); - auto* sHardBounds = ini.addSection("hard bounds"); - auto* sInitializeReservoirDate = ini.addSection("initialize reservoir date"); - auto* sUseHeuristic = ini.addSection("use heuristic"); - auto* sUseLeeway = ini.addSection("use leeway"); - auto* sPowerToLevel = ini.addSection("power to level"); - auto* sLeewayLow = ini.addSection("leeway low"); - auto* sLeewayUp = ini.addSection("leeway up"); - auto* spumpingEfficiency = ini.addSection("pumping efficiency"); + AllSections allSections(ini); // return status bool ret = true; // Add all alpha values for each area areas.each( - [&](const Data::Area& area) + [&allSections, &buffer, &folder, &ret](const Data::Area& area) { - s->add(area.id, area.hydro.interDailyBreakdown); - smod->add(area.id, area.hydro.intraDailyModulation); - sIMB->add(area.id, area.hydro.intermonthlyBreakdown); - sInitializeReservoirDate->add(area.id, area.hydro.initializeReservoirLevelDate); - sLeewayLow->add(area.id, area.hydro.leewayLowerBound); - sLeewayUp->add(area.id, area.hydro.leewayUpperBound); - spumpingEfficiency->add(area.id, area.hydro.pumpingEfficiency); + allSections.s->add(area.id, area.hydro.interDailyBreakdown); + allSections.smod->add(area.id, area.hydro.intraDailyModulation); + allSections.sIMB->add(area.id, area.hydro.intermonthlyBreakdown); + allSections.sInitializeReservoirDate->add(area.id, area.hydro.initializeReservoirLevelDate); + allSections.sLeewayLow->add(area.id, area.hydro.leewayLowerBound); + allSections.sLeewayUp->add(area.id, area.hydro.leewayUpperBound); + allSections.spumpingEfficiency->add(area.id, area.hydro.pumpingEfficiency); if (area.hydro.reservoirCapacity > 1e-6) { - sreservoirCapacity->add(area.id, area.hydro.reservoirCapacity); + allSections.sreservoirCapacity->add(area.id, area.hydro.reservoirCapacity); } if (area.hydro.reservoirManagement) { - sreservoir->add(area.id, true); + allSections.sreservoir->add(area.id, true); } if (!area.hydro.followLoadModulations) { - sFollowLoad->add(area.id, false); + allSections.sFollowLoad->add(area.id, false); } if (area.hydro.useWaterValue) { - sUseWater->add(area.id, true); + allSections.sUseWater->add(area.id, true); } if (area.hydro.hardBoundsOnRuleCurves) { - sHardBounds->add(area.id, true); + allSections.sHardBounds->add(area.id, true); } if (!area.hydro.useHeuristicTarget) { - sUseHeuristic->add(area.id, false); + allSections.sUseHeuristic->add(area.id, false); } if (area.hydro.useLeeway) { - sUseLeeway->add(area.id, true); + allSections.sUseLeeway->add(area.id, true); } if (area.hydro.powerToLevel) { - sPowerToLevel->add(area.id, true); + allSections.sPowerToLevel->add(area.id, true); } // max hours gen diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 1c9ca78bf7..749613a14b 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -37,9 +37,8 @@ namespace Antares::Data::ShortTermStorage { bool STStorageInput::validate() const { - return std::all_of(storagesByIndex.cbegin(), - storagesByIndex.cend(), - [](auto& cluster) { return cluster.validate(); }); + return std::ranges::all_of(storagesByIndex, [](auto& cluster) + { return cluster.validate(); }); } bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) @@ -69,9 +68,8 @@ bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) storagesByIndex.push_back(cluster); } - std::sort(storagesByIndex.begin(), - storagesByIndex.end(), - [&](const auto& a, const auto& b) { return a.properties.name < b.properties.name; }); + std::ranges::sort(storagesByIndex, [](const auto& a, const auto& b) + { return a.properties.name < b.properties.name; }); return true; } @@ -102,9 +100,8 @@ bool STStorageInput::saveToFolder(const std::string& folder) const IniFile ini; logs.debug() << "saving file " << pathIni; - std::for_each(storagesByIndex.cbegin(), - storagesByIndex.cend(), - [&ini](auto& storage) { return storage.saveProperties(ini); }); + std::ranges::for_each(storagesByIndex, [&ini](auto& storage) + { return storage.saveProperties(ini); }); return ini.save(pathIni); } @@ -112,29 +109,20 @@ bool STStorageInput::saveToFolder(const std::string& folder) const bool STStorageInput::saveDataSeriesToFolder(const std::string& folder) const { Yuni::IO::Directory::Create(folder); - return std::all_of(storagesByIndex.cbegin(), - storagesByIndex.cend(), - [&folder](auto& storage) - { return storage.saveSeries(folder + SEP + storage.id); }); + return std::ranges::all_of(storagesByIndex, [&folder](auto& storage) + { return storage.saveSeries(folder + SEP + storage.id); }); } std::size_t STStorageInput::count() const { - return std::count_if(storagesByIndex.begin(), - storagesByIndex.end(), - [](const STStorageCluster& st) { return st.properties.enabled; }); + return std::ranges::count_if(storagesByIndex, [](const STStorageCluster& st) + { return st.properties.enabled; }); } uint STStorageInput::removeDisabledClusters() { - const auto& it = std::remove_if(storagesByIndex.begin(), - storagesByIndex.end(), - [](const auto& c) { return !c.enabled(); }); - - uint disabledCount = std::distance(it, storagesByIndex.end()); - storagesByIndex.erase(it, storagesByIndex.end()); - - return disabledCount; + return std::erase_if(storagesByIndex, [](const auto& c) + { return !c.enabled(); }); } } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index f10da99345..035faf86ac 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -103,7 +103,7 @@ static void StudyRuntimeInfosInitializeAreaLinks(Study& study, StudyRuntimeInfos uint indx = 0; study.areas.each( - [&](Data::Area& area) + [&indx, &r](Data::Area& area) { area.buildLinksIndexes(); @@ -213,9 +213,9 @@ void StudyRuntimeInfos::initializeRangeLimits(const Study& study, StudyRangeLimi } else { - simulationDaysPerMonth[(uint)ca.month] = study.calendar.months[(uint)ca.month].days + simulationDaysPerMonth[ca.month] = study.calendar.months[ca.month].days - ca.dayMonth; - simulationDaysPerMonth[(uint)cb.month] = cb.dayMonth + 1; + simulationDaysPerMonth[cb.month] = cb.dayMonth + 1; for (uint i = ca.month + 1; i < cb.month; ++i) { simulationDaysPerMonth[i] = study.calendar.months[i].days; @@ -270,9 +270,9 @@ void StudyRuntimeInfos::checkThermalTSGeneration(Study& study) thermalTSRefresh = globalThermalTSgeneration; study.areas.each( - [this, globalThermalTSgeneration](Data::Area& area) + [this, globalThermalTSgeneration](const Data::Area& area) { - for (auto& c: area.thermal.list.each_enabled_and_not_mustrun()) + for (const auto& c: area.thermal.list.each_enabled_and_not_mustrun()) { thermalTSRefresh = thermalTSRefresh || c->doWeGenerateTS(globalThermalTSgeneration); } @@ -441,8 +441,7 @@ void StudyRangeLimits::checkIntegrity() const void StudyRuntimeInfos::disableAllFilters(Study& study) { - study.areas.each( - [&](Data::Area& area) + study.areas.each([](Data::Area& area) { area.filterSynthesis = filterAll; area.filterYearByYear = filterAll; diff --git a/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp b/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp index 24b5b8cb6b..46a0694a58 100644 --- a/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp +++ b/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp @@ -80,9 +80,8 @@ bool BindingConstraintsTSNumberData::apply(Study& study) bool BindingConstraintsTSNumberData::reset(const Study& study) { const uint nbYears = study.parameters.nbYears; - std::for_each(study.bindingConstraintsGroups.begin(), - study.bindingConstraintsGroups.end(), - [&](const auto& group) + std::ranges::for_each(study.bindingConstraintsGroups, + [this, &nbYears](const auto& group) { auto& ts_numbers = rules_[group->name()]; ts_numbers.reset(1, nbYears); diff --git a/src/libs/antares/study/scenario-builder/sets.cpp b/src/libs/antares/study/scenario-builder/sets.cpp index 962f7c122d..76dbcb9166 100644 --- a/src/libs/antares/study/scenario-builder/sets.cpp +++ b/src/libs/antares/study/scenario-builder/sets.cpp @@ -195,7 +195,7 @@ bool Sets::internalLoadFromINIFile(const AnyString& filename) } ini.each( - [&](const IniFile::Section& section) + [this](const IniFile::Section& section) { if (section.name.empty()) { diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 23f547783d..511e61a592 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -520,7 +520,7 @@ void Study::performTransformationsBeforeLaunchingSimulation() // ForEach area areas.each( - [&](Data::Area& area) + [this](Data::Area& area) { if (not parameters.geographicTrimming) { @@ -698,7 +698,7 @@ void Study::saveAboutTheStudy(Solver::IResultWriter& resultWriter) buffer << "@ " << i->first << "\r\n"; } } - areas.each([&](const Data::Area& area) { buffer << area.name << "\r\n"; }); + areas.each([&buffer](const Data::Area& area) { buffer << area.name << "\r\n"; }); resultWriter.addEntryFromBuffer(path.c_str(), buffer); } @@ -789,7 +789,7 @@ bool Study::areaDelete(Area* area) // and the scenario builder data *before* reloading uiinfo. { // Updating all hydro allocation - areas.each([&](Data::Area& areait) { areait.hydro.allocation.remove(area->id); }); + areas.each([&area](Data::Area& areait) { areait.hydro.allocation.remove(area->id); }); // We __must__ update the scenario builder data // We may delete an area and re-create a new one with the same @@ -856,7 +856,7 @@ void Study::areaDelete(Area::Vector& arealist) << area.name; // Updating all hydro allocation - areas.each([&](Data::Area& areait) { areait.hydro.allocation.remove(area.id); }); + areas.each([&area](Data::Area& areait) { areait.hydro.allocation.remove(area.id); }); // Remove all binding constraints attached to the area bindingConstraints.remove(*i); @@ -955,7 +955,8 @@ bool Study::areaRename(Area* area, AreaName newName) logs.info() << "renaming area " << area->name << " into " << newName; // Updating all hydro allocation - areas.each([&](Data::Area& areait) { areait.hydro.allocation.rename(oldid, newid); }); + areas.each([&oldid, &newid](Data::Area& areait) + { areait.hydro.allocation.rename(oldid, newid); }); ScenarioBuilderUpdater updaterSB(*this); bool ret = true; @@ -1088,34 +1089,33 @@ bool Study::clusterRename(Cluster* cluster, ClusterName newName) void Study::destroyAllLoadTSGeneratorData() { - areas.each([&](Data::Area& area) { FreeAndNil(area.load.prepro); }); + areas.each([](Data::Area& area) { FreeAndNil(area.load.prepro); }); } void Study::destroyAllSolarTSGeneratorData() { - areas.each([&](Data::Area& area) { FreeAndNil(area.solar.prepro); }); + areas.each([](Data::Area& area) { FreeAndNil(area.solar.prepro); }); } void Study::destroyAllHydroTSGeneratorData() { - areas.each([&](Data::Area& area) { FreeAndNil(area.hydro.prepro); }); + areas.each([](Data::Area& area) { FreeAndNil(area.hydro.prepro); }); } void Study::destroyAllWindTSGeneratorData() { - areas.each([&](Data::Area& area) { FreeAndNil(area.wind.prepro); }); + areas.each([](Data::Area& area) { FreeAndNil(area.wind.prepro); }); } void Study::destroyAllThermalTSGeneratorData() { - areas.each( - [&](Data::Area& area) - { - for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) - { - FreeAndNil(cluster->prepro); - } - }); + areas.each([](const Data::Area& area) + { + for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) + { + FreeAndNil(cluster->prepro); + } + }); } void Study::ensureDataAreLoadedForAllBindingConstraints() @@ -1356,8 +1356,9 @@ bool Study::checkForFilenameLimits(bool output, const String& chfolder) const String areaname; areas.each( - [&](const Area& area) + [&output, &linkname, &areaname](const Area& area) { + if (areaname.size() < area.id.size()) { areaname = area.id; @@ -1368,19 +1369,12 @@ bool Study::checkForFilenameLimits(bool output, const String& chfolder) const { auto& link = *(i->second); uint len = link.from->id.size() + link.with->id.size(); - len += output ? 3 : 1; + len += 3; if (len > linkname.size()) { linkname.clear(); linkname << i->second->from->id; - if (output) - { - linkname << " - "; // 3 - } - else - { - linkname << SEP; - } + linkname << " - "; // 3 linkname << i->second->with->id; } } @@ -1436,7 +1430,7 @@ bool Study::checkForFilenameLimits(bool output, const String& chfolder) const // or even constraints areas.each( - [&](const Area& area) + [&areaname, &clustername](const Area& area) { if (areaname.size() < area.id.size()) { diff --git a/src/libs/antares/study/study.importprepro.cpp b/src/libs/antares/study/study.importprepro.cpp index 837f37a485..3b8263eadf 100644 --- a/src/libs/antares/study/study.importprepro.cpp +++ b/src/libs/antares/study/study.importprepro.cpp @@ -50,56 +50,52 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesLoad)) { logs.info() << "Importing load timeseries..."; - areas.each( - [&](const Data::Area& area) - { - logs.info() << "Importing load timeseries : " << area.name; - buffer.clear() << folderInput << SEP << "load" << SEP << "series"; - ret = area.load.series.saveToFolder(area.id, buffer.c_str(), "load_") && ret; - ++progression; - }); + for (const auto& [areaName, area] : areas) + { + logs.info() << "Importing load timeseries : " << areaName; + buffer.clear() << folderInput << SEP << "load" << SEP << "series"; + ret = area->load.series.saveToFolder(area->id, buffer.c_str(), "load_") && ret; + ++progression; + } } // Solar if (parameters.haveToImport(timeSeriesSolar)) { logs.info() << "Importing solar timeseries..."; - areas.each( - [&](const Data::Area& area) - { - logs.info() << "Importing solar timeseries : " << area.name; - buffer.clear() << folderInput << SEP << "solar" << SEP << "series"; - ret = area.solar.series.saveToFolder(area.id, buffer.c_str(), "solar_") && ret; - ++progression; - }); + for (const auto& [areaName, area] : areas) + { + logs.info() << "Importing solar timeseries : " << areaName; + buffer.clear() << folderInput << SEP << "solar" << SEP << "series"; + ret = area->solar.series.saveToFolder(area->id, buffer.c_str(), "solar_") && ret; + ++progression; + } } // Hydro if (parameters.haveToImport(timeSeriesHydro)) { logs.info() << "Importing hydro timeseries..."; - areas.each( - [&](const Data::Area& area) - { - logs.info() << "Importing hydro timeseries : " << area.name; - buffer.clear() << folderInput << SEP << "hydro" << SEP << "series"; - ret = area.hydro.series->saveToFolder(area.id, buffer) && ret; - ++progression; - }); + for (const auto& [areaName, area] : areas) + { + logs.info() << "Importing hydro timeseries : " << areaName; + buffer.clear() << folderInput << SEP << "hydro" << SEP << "series"; + ret = area->hydro.series->saveToFolder(area->id, buffer) && ret; + ++progression; + } } // Wind if (parameters.haveToImport(timeSeriesWind)) { logs.info() << "Importing wind timeseries..."; - areas.each( - [&](const Data::Area& area) - { - logs.info() << "Importing wind timeseries : " << area.name; - buffer.clear() << folderInput << SEP << "wind" << SEP << "series"; - area.wind.series.saveToFolder(area.id, buffer.c_str(), "wind_") && ret; - ++progression; - }); + for (const auto& [areaName, area] : areas) + { + logs.info() << "Importing wind timeseries : " << areaName; + buffer.clear() << folderInput << SEP << "wind" << SEP << "series"; + area->wind.series.saveToFolder(area->id, buffer.c_str(), "wind_") && ret; + ++progression; + } } // Thermal @@ -108,18 +104,17 @@ bool Study::importTimeseriesIntoInput() logs.info() << "Importing thermal timeseries..."; String msg; - areas.each( - [&](Data::Area& area) - { - msg.clear() << "Importing thermal timeseries : " << area.name; + for (const auto& [areaName, area] : areas) + { + msg.clear() << "Importing thermal timeseries : " << areaName; - // Spinning - area.thermal.list.reverseCalculationOfSpinning(); + // Spinning + area->thermal.list.reverseCalculationOfSpinning(); - buffer.clear() << folderInput << SEP << "thermal" << SEP << "series"; - ret = area.thermal.list.saveDataSeriesToFolder(buffer.c_str()) && ret; - ++progression; - }); + buffer.clear() << folderInput << SEP << "thermal" << SEP << "series"; + ret = area->thermal.list.saveDataSeriesToFolder(buffer.c_str()) && ret; + ++progression; + } } return ret; diff --git a/src/libs/antares/study/xcast/xcast.cpp b/src/libs/antares/study/xcast/xcast.cpp index 4233784088..51ed1624b0 100644 --- a/src/libs/antares/study/xcast/xcast.cpp +++ b/src/libs/antares/study/xcast/xcast.cpp @@ -201,19 +201,15 @@ bool XCast::loadFromFolder(const AnyString& folder) IniFile ini; if (ini.open(buffer)) { - // For each section - const IniFile::Property* p; - CString<30, false> key; - ini.each( - [&](const IniFile::Section& section) + [this, &buffer](const IniFile::Section& section) { // For each property if (section.name == "general") { - for (p = section.firstProperty; p != nullptr; p = p->next) + for (const IniFile::Property* p = section.firstProperty; p != nullptr; p = p->next) { - key = p->key; + CString<30, false> key = p->key; key.toLower(); if (key == "distribution") { diff --git a/src/libs/antares/sys/policy.cpp b/src/libs/antares/sys/policy.cpp index b9a60ea4af..0427c7441c 100644 --- a/src/libs/antares/sys/policy.cpp +++ b/src/libs/antares/sys/policy.cpp @@ -65,22 +65,20 @@ static void OpenFromINIFileWL(const String& filename, const StringT& hostname) return; } - PolicyKey key; - ShortString128 hostnameVersion; - ShortString128 hostnameAll; - hostnameVersion << hostname << ':' << ANTARES_VERSION; - hostnameAll << hostname << ":*"; + std::string hostnameVersion = hostname + ':' + ANTARES_VERSION; + std::string hostnameAll = hostname + ":*"; ini.each( - [&](const IniFile::Section& section) + [&hostnameVersion, &hostnameAll](const IniFile::Section& section) { // This section is dedicated to another host if (section.name == "*:*" or section.name == "*:" ANTARES_VERSION or section.name.equals(hostnameAll) or section.name.equals(hostnameVersion)) { section.each( - [&](const IniFile::Property& property) + [](const IniFile::Property& property) { + PolicyKey key; key = property.key; key.trim(" \t"); (*entries)[key] = property.value; diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index d221d19eb6..d222ad88c0 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -118,7 +118,7 @@ void Application::readDataForTheStudy(Data::StudyLoadOptions& options) std::exception_ptr loadingException; try { - pDurationCollector("study_loading") << [&] + pDurationCollector("study_loading") << [this, &study, &options] { if (study.loadFromFolder(pSettings.studyFolder, options)) { diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index 8391b523d0..5c6bcab897 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -414,10 +414,8 @@ inline void HydroManagement::prepareDailyOptimalGenerations( break; case NON: throw solutionNotFound(area.name.c_str(), y); - break; case EMERGENCY_SHUT_DOWN: throw fatalError(area.name.c_str(), y); - break; } H2O_J_Free(problem); @@ -535,10 +533,8 @@ inline void HydroManagement::prepareDailyOptimalGenerations( break; case NON: throw solutionNotFound(area.name.c_str(), y); - break; case EMERGENCY_SHUT_DOWN: throw fatalError(area.name.c_str(), y); - break; } H2O2_J_Free(problem); @@ -554,7 +550,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( void HydroManagement::prepareDailyOptimalGenerations(uint y, Antares::Data::Area::ScratchMap& scratchmap) { - areas_.each([&](Data::Area& area) + areas_.each([this, &scratchmap, &y](Data::Area& area) { prepareDailyOptimalGenerations(area, y, scratchmap); }); } } // namespace Antares diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index b20be5e375..6cea703442 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -143,7 +143,7 @@ HydroManagement::HydroManagement(const Data::AreaList& areas, void HydroManagement::prepareInflowsScaling(uint year) { areas_.each( - [&](const Data::Area& area) + [this, &year](const Data::Area& area) { const auto& srcinflows = area.hydro.series->storage.getColumn(year); @@ -440,7 +440,7 @@ void HydroManagement::prepareNetDemand(uint year, void HydroManagement::prepareEffectiveDemand() { areas_.each( - [&](Data::Area& area) + [this](Data::Area& area) { auto& data = tmpDataByArea_[&area]; @@ -453,7 +453,7 @@ void HydroManagement::prepareEffectiveDemand() double effectiveDemand = 0; // area.hydro.allocation is indexed by area index area.hydro.allocation.eachNonNull( - [&](unsigned areaIndex, double value) + [this, &effectiveDemand, &day](unsigned areaIndex, double value) { const auto* area = areas_.byIndex[areaIndex]; effectiveDemand += tmpDataByArea_[area].DLN[day] * value; diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index 2cb868da72..62ce897eb8 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -151,7 +151,7 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ { uint indexArea = 0; areas_.each( - [&](Data::Area& area) + [this, &random_reservoir_level, &y, &indexArea](Data::Area& area) { auto& data = tmpDataByArea_[&area]; diff --git a/src/solver/optimisation/post_process_commands.cpp b/src/solver/optimisation/post_process_commands.cpp index c90c8b4809..1b170ae353 100644 --- a/src/solver/optimisation/post_process_commands.cpp +++ b/src/solver/optimisation/post_process_commands.cpp @@ -47,7 +47,7 @@ void DispatchableMarginPostProcessCmd::execute(const optRuntimeData& opt_runtime unsigned int hourInYear = opt_runtime_data.hourInTheYear; unsigned int year = opt_runtime_data.year; area_list_.each( - [&](Data::Area& area) + [this, &hourInYear, &year](Data::Area& area) { double* dtgmrg = area.scratchpad[thread_number_].dispatchableGenerationMargin; for (uint h = 0; h != nbHoursInWeek; ++h) diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index b413b632d5..1f56235499 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -401,7 +401,7 @@ void SetInitialHydroLevel(Data::Study& study, const HYDRO_VENTILATION_RESULTS& hydroVentilationResults) { uint firstDaySimu = study.parameters.simulationDays.first; - study.areas.each([&](Data::Area& area) + study.areas.each([&problem, &firstDaySimu, &hydroVentilationResults](const Data::Area& area) { if (area.hydro.reservoirManagement) { diff --git a/src/solver/simulation/common-hydro-levels.cpp b/src/solver/simulation/common-hydro-levels.cpp index b322d62dec..81602073a1 100644 --- a/src/solver/simulation/common-hydro-levels.cpp +++ b/src/solver/simulation/common-hydro-levels.cpp @@ -33,54 +33,50 @@ void computingHydroLevels(const Data::AreaList& areas, bool remixWasRun, bool computeAnyway) { - areas.each( - [&](const Data::Area& area) - { - if (!area.hydro.reservoirManagement) - { - return; - } + for (const auto& [_, area] : areas) + { + if (!area->hydro.reservoirManagement) + { + continue; + } - if (not computeAnyway) - { - if (area.hydro.useHeuristicTarget != remixWasRun) - { - return; - } - } + if (!computeAnyway && area->hydro.useHeuristicTarget != remixWasRun) + { + continue; + } - uint index = area.index; + uint index = area->index; - double reservoirCapacity = area.hydro.reservoirCapacity; + double reservoirCapacity = area->hydro.reservoirCapacity; - std::vector& inflows = problem.CaracteristiquesHydrauliques[index] - .ApportNaturelHoraire; + std::vector& inflows = problem.CaracteristiquesHydrauliques[index] + .ApportNaturelHoraire; - RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; + RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; - std::vector& turb = weeklyResults.TurbinageHoraire; + std::vector& turb = weeklyResults.TurbinageHoraire; - std::vector& pump = weeklyResults.PompageHoraire; - double pumpingRatio = area.hydro.pumpingEfficiency; + std::vector& pump = weeklyResults.PompageHoraire; + double pumpingRatio = area->hydro.pumpingEfficiency; - double nivInit = problem.CaracteristiquesHydrauliques[index].NiveauInitialReservoir; - std::vector& niv = weeklyResults.niveauxHoraires; + double nivInit = problem.CaracteristiquesHydrauliques[index].NiveauInitialReservoir; + std::vector& niv = weeklyResults.niveauxHoraires; - std::vector& ovf = weeklyResults.debordementsHoraires; + std::vector& ovf = weeklyResults.debordementsHoraires; - computeTimeStepLevel + computeTimeStepLevel computeLvlObj(nivInit, inflows, ovf, turb, pumpingRatio, pump, reservoirCapacity); - for (uint h = 0; h < nbHoursInAWeek - 1; h++) - { - computeLvlObj.run(); - niv[h] = computeLvlObj.getLevel() * 100 / reservoirCapacity; - computeLvlObj.prepareNextStep(); - } + for (uint h = 0; h < nbHoursInAWeek - 1; h++) + { + computeLvlObj.run(); + niv[h] = computeLvlObj.getLevel() * 100 / reservoirCapacity; + computeLvlObj.prepareNextStep(); + } - computeLvlObj.run(); - niv[nbHoursInAWeek - 1] = computeLvlObj.getLevel() * 100 / reservoirCapacity; - }); + computeLvlObj.run(); + niv[nbHoursInAWeek - 1] = computeLvlObj.getLevel() * 100 / reservoirCapacity; + } } void interpolateWaterValue(const Data::AreaList& areas, @@ -98,65 +94,63 @@ void interpolateWaterValue(const Data::AreaList& areas, daysOfWeek[d] = weekFirstDay + d; } - areas.each( - [&](const Data::Area& area) - { - uint index = area.index; + for (const auto& [_, area] : areas) + { + uint index = area->index; - RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; + RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; - auto& waterVal = weeklyResults.valeurH2oHoraire; - std::fill(waterVal.begin(), waterVal.end(), 0.); + auto& waterVal = weeklyResults.valeurH2oHoraire; + std::fill(waterVal.begin(), waterVal.end(), 0.); - if (!area.hydro.reservoirManagement || !area.hydro.useWaterValue) - { - return; - } + if (!area->hydro.reservoirManagement || !area->hydro.useWaterValue) + { + return; + } - if (!area.hydro.useWaterValue) - { - return; - } + if (!area->hydro.useWaterValue) + { + return; + } - double reservoirCapacity = area.hydro.reservoirCapacity; + double reservoirCapacity = area->hydro.reservoirCapacity; - std::vector& niv = weeklyResults.niveauxHoraires; + std::vector& niv = weeklyResults.niveauxHoraires; - waterVal[0] = Data::getWaterValue(problem.previousSimulationFinalLevel[index] * 100 - / reservoirCapacity, - area.hydro.waterValues, - weekFirstDay); + waterVal[0] = Data::getWaterValue(problem.previousSimulationFinalLevel[index] * 100 + / reservoirCapacity, + area->hydro.waterValues, + weekFirstDay); - for (uint h = 1; h < nbHoursInAWeek; h++) - { - waterVal[h] = Data::getWaterValue(niv[h - 1], - area.hydro.waterValues, - daysOfWeek[h / 24]); - } - }); + for (uint h = 1; h < nbHoursInAWeek; h++) + { + waterVal[h] = Data::getWaterValue(niv[h - 1], + area->hydro.waterValues, + daysOfWeek[h / 24]); + } + } } void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& problem) { - areas.each( - [&](const Data::Area& area) - { - if (!area.hydro.reservoirManagement) - { - return; - } + for (const auto& [_, area] : areas) + { + if (!area->hydro.reservoirManagement) + { + continue; + } - uint index = area.index; + uint index = area->index; - double reservoirCapacity = area.hydro.reservoirCapacity; + double reservoirCapacity = area->hydro.reservoirCapacity; - RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; + RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; - std::vector& niv = weeklyResults.niveauxHoraires; + std::vector& niv = weeklyResults.niveauxHoraires; - problem.previousSimulationFinalLevel[index] = niv[nbHoursInAWeek - 1] * reservoirCapacity - / 100; - }); + problem.previousSimulationFinalLevel[index] = niv[nbHoursInAWeek - 1] * reservoirCapacity + / 100; + } } } // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/common-hydro-remix.cpp b/src/solver/simulation/common-hydro-remix.cpp index a94b8f1dfe..dcf39052ce 100644 --- a/src/solver/simulation/common-hydro-remix.cpp +++ b/src/solver/simulation/common-hydro-remix.cpp @@ -51,7 +51,8 @@ static bool Remix(const Data::AreaList& areas, bool status = true; areas.each( - [&](const Data::Area& area) + [&HE, &DE, &remix, &G, &status, &problem, &numSpace, &hourInYear] + (const Data::Area& area) { auto index = area.index; diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index adf8c23c4d..8084130e9f 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -159,7 +159,7 @@ public: simulation_->prepareClustersInMustRunMode(scratchmap, y); // 4 - Hydraulic ventilation - pDurationCollector("hydro_ventilation") << [&] { + pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] { hydroManagement.makeVentilation(randomReservoirLevel, y, scratchmap); @@ -205,7 +205,7 @@ public: // 9 - Write results for the current year if (yearByYear) { - pDurationCollector("yby_export") << [&] + pDurationCollector("yby_export") << [this] { // Before writing, some variable may require minor modifications simulation_->variables.beforeYearByYearExport(y, numSpace); @@ -776,7 +776,8 @@ void ISimulation::computeRandomNumbers( bool SpilledEnergySeedIsDefault = (currentSpilledEnergySeed == defaultSpilledEnergySeed); areaIndex = 0; study.areas.each( - [&](Data::Area& area) + [&isPerformed, &areaIndex, &randomUnsupplied, &randomSpilled, &randomForYears, &indexYear, + &SpilledEnergySeedIsDefault](Data::Area& area) { (void)area; // Avoiding warnings at compilation (unused variable) on linux if (isPerformed) @@ -938,7 +939,7 @@ static inline void logPerformedYearsInAset(setOfParallelYears& set) std::string performedYearsToLog = ""; std::ranges::for_each(set.yearsIndices, - [&](const uint& y) + [&set, &performedYearsToLog](const uint& y) { if (set.isYearPerformed[y]) { diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 155cb6b3bc..ed13d54fe1 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -198,7 +198,7 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, problem.CaracteristiquesHydrauliques[i].TailleReservoir = area.hydro.reservoirCapacity; - for (int pdt = 0; pdt < NombreDePasDeTemps; pdt++) + for (unsigned pdt = 0; pdt < NombreDePasDeTemps; pdt++) { problem.CaracteristiquesHydrauliques[i].NiveauHoraireInf[pdt] = 0; problem.CaracteristiquesHydrauliques[i].NiveauHoraireSup[pdt] diff --git a/src/solver/ts-generator/generator.cpp b/src/solver/ts-generator/generator.cpp index 2cb4227755..3423a9a8ad 100644 --- a/src/solver/ts-generator/generator.cpp +++ b/src/solver/ts-generator/generator.cpp @@ -27,7 +27,7 @@ namespace Antares::TSGenerator void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params) { areas.each( - [&](Data::Area& area) + [¶ms](Data::Area& area) { // Load if (params.timeSeriesToGenerate & Data::timeSeriesLoad) diff --git a/src/solver/ts-generator/hydro.cpp b/src/solver/ts-generator/hydro.cpp index 1b4ac3496d..29d0a29f42 100644 --- a/src/solver/ts-generator/hydro.cpp +++ b/src/solver/ts-generator/hydro.cpp @@ -42,7 +42,7 @@ static void PreproRoundAllEntriesPlusDerated(Data::Study& study) bool derated = study.parameters.derated; study.areas.each( - [&](Data::Area& area) + [&derated](Data::Area& area) { auto& hydroseries = *(area.hydro.series); @@ -180,7 +180,6 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu uint month = i % 12; uint realmonth = calendar.months[month].realmonth; - uint daysPerMonth = calendar.months[month].days; assert(l < series.ror.timeSeries.width); assert(not std::isnan(colPOW[realmonth])); @@ -283,11 +282,11 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu else { logs.info() << "Archiving the hydro time-series"; - const int precision = 0; - Yuni::String output; study.areas.each( - [&](const Data::Area& area) + [&study, ¤tYear, &writer, &progression](const Data::Area& area) { + const int precision = 0; + Yuni::String output; study.buffer.clear() << "ts-generator" << SEP << "hydro" << SEP << "mc-" << currentYear << SEP << area.id; diff --git a/src/solver/ts-generator/xcast/xcast.cpp b/src/solver/ts-generator/xcast/xcast.cpp index feb8412f49..ca0c96087a 100644 --- a/src/solver/ts-generator/xcast/xcast.cpp +++ b/src/solver/ts-generator/xcast/xcast.cpp @@ -86,7 +86,7 @@ void XCast::exportTimeSeriesToTheOutput(Progression::Task& progression, Predicat filename.reserve(output.size() + 80); study.areas.each( - [&](Data::Area& area) + [this, &filename, &progression, &predicate, &output](Data::Area& area) { filename.clear() << output << SEP << area.id << ".txt"; std::string buffer; @@ -593,7 +593,7 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi if (study.parameters.derated) { - study.areas.each([&](Data::Area& area) { predicate.matrix(area).averageTimeseries(); }); + study.areas.each([&predicate](Data::Area& area) { predicate.matrix(area).averageTimeseries(); }); } if (study.parameters.timeSeriesToArchive & timeSeriesType) diff --git a/src/solver/variable/include/antares/solver/variable/area.hxx b/src/solver/variable/include/antares/solver/variable/area.hxx index 4fdeb096c0..d3b34bb973 100644 --- a/src/solver/variable/include/antares/solver/variable/area.hxx +++ b/src/solver/variable/include/antares/solver/variable/area.hxx @@ -369,7 +369,7 @@ void Areas::hourForEachArea(State& state, uint numSpace) { // For each area... state.study.areas.each( - [&](Data::Area& area) + [this, &state, &numSpace](Data::Area& area) { state.area = &area; // the current area @@ -402,7 +402,7 @@ void Areas::weekForEachArea(State& state, uint numSpace) { // For each area... state.study.areas.each( - [&](Data::Area& area) + [this, &state, &numSpace](Data::Area& area) { state.area = &area; // the current area @@ -437,7 +437,7 @@ void Areas::yearEndBuild(State& state, uint year, uint numSpace) { // For each area... state.study.areas.each( - [&](Data::Area& area) + [this, &state, &year, &numSpace](Data::Area& area) { state.area = &area; // the current area diff --git a/src/solver/variable/surveyresults/surveyresults.cpp b/src/solver/variable/surveyresults/surveyresults.cpp index e05283ff5a..0402fb6c15 100644 --- a/src/solver/variable/surveyresults/surveyresults.cpp +++ b/src/solver/variable/surveyresults/surveyresults.cpp @@ -127,7 +127,7 @@ static void ExportGridInfosAreas(const Data::Study& study, "marginal cost\tfixed cost\tstartup cost\tmarket bid cost\tspread cost\n"; study.areas.each( - [&](const Data::Area& area) + [&out, &outLinks, &outThermal](const Data::Area& area) { out << area.id << '\t'; out << area.name << '\n'; From 9be866cf4aec0a3a8b4b415ef8e59508adedddda Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 19 Jun 2024 16:02:03 +0200 Subject: [PATCH 022/127] Thermal validation and loading (#2173) Modular loading: separating loading and validation functions --- src/libs/antares/study/area/list.cpp | 3 +- .../study/include/antares/study/area/area.h | 2 +- .../study/parts/thermal/cluster_list.h | 3 + .../antares/study/parts/thermal/cluster.cpp | 14 -- .../study/parts/thermal/cluster_list.cpp | 151 ++++++++---------- 5 files changed, 75 insertions(+), 98 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index 219f7ee8aa..b622b94af9 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -376,7 +376,6 @@ bool saveAreaAdequacyPatchIniFile(const Area& area, const Clob& buffer) } AreaList::AreaList(Study& study): - byIndex(nullptr), pStudy(study) { } @@ -994,6 +993,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, { buffer.clear() << study.folderInput << SEP << "thermal" << SEP << "prepro"; ret = area.thermal.list.loadPreproFromFolder(study, buffer) && ret; + ret = area.thermal.list.validatePrepro(study) && ret; buffer.clear() << study.folderInput << SEP << "thermal" << SEP << "series"; ret = area.thermal.list.loadDataSeriesFromFolder(study, buffer) && ret; ret = area.thermal.list.loadEconomicCosts(study, buffer) && ret; @@ -1182,6 +1182,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) Area& area = *(i->second); buffer.clear() << pStudy.folderInput << thermalPlant << area.id; ret = area.thermal.list.loadFromFolder(pStudy, buffer.c_str(), &area) && ret; + ret = area.thermal.list.validateClusters(pStudy.parameters) && ret; } } diff --git a/src/libs/antares/study/include/antares/study/area/area.h b/src/libs/antares/study/include/antares/study/area/area.h index ede65679a2..6661ab8556 100644 --- a/src/libs/antares/study/include/antares/study/area/area.h +++ b/src/libs/antares/study/include/antares/study/area/area.h @@ -689,7 +689,7 @@ class AreaList final: public Yuni::NonCopyable public: //! All areas by their index - Area** byIndex; + Area** byIndex = nullptr; //! All areas in the list Area::Map areas; diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/cluster_list.h b/src/libs/antares/study/include/antares/study/parts/thermal/cluster_list.h index ea1518750d..9f091defda 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/cluster_list.h +++ b/src/libs/antares/study/include/antares/study/parts/thermal/cluster_list.h @@ -113,6 +113,9 @@ class ThermalClusterList: public ClusterList ** \return A non-zero value if the operation succeeded, 0 otherwise */ bool loadPreproFromFolder(Study& s, const AnyString& folder); + bool validatePrepro(const Study& study); + + bool validateClusters(const Parameters& param) const; bool loadEconomicCosts(Study& s, const AnyString& folder); diff --git a/src/libs/antares/study/parts/thermal/cluster.cpp b/src/libs/antares/study/parts/thermal/cluster.cpp index 6a008f8929..da502ac29e 100644 --- a/src/libs/antares/study/parts/thermal/cluster.cpp +++ b/src/libs/antares/study/parts/thermal/cluster.cpp @@ -512,20 +512,6 @@ bool Data::ThermalCluster::integrityCheck() bool ret = true; - if (minUpTime > 168 or 0 == minUpTime) - { - logs.error() << "Thermal cluster " << parentArea->name << "/" << pName - << ": The min. up time must be between 1 and 168"; - minUpTime = 1; - ret = false; - } - if (minDownTime > 168 or 0 == minDownTime) - { - logs.error() << "Thermal cluster " << parentArea->name << "/" << pName - << ": The min. down time must be between 1 and 168"; - minDownTime = 1; - ret = false; - } if (nominalCapacity < 0.) { logs.error() << "Thermal cluster " << parentArea->name << "/" << pName diff --git a/src/libs/antares/study/parts/thermal/cluster_list.cpp b/src/libs/antares/study/parts/thermal/cluster_list.cpp index 2059cf9238..4bf2e042c2 100644 --- a/src/libs/antares/study/parts/thermal/cluster_list.cpp +++ b/src/libs/antares/study/parts/thermal/cluster_list.cpp @@ -159,52 +159,56 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A options = Matrix<>::optFixedSize, }; - bool r = cluster->modulation.loadFromCSVFile(modulationFile, - thermalModulationMax, - HOURS_PER_YEAR, - options); - if (!r && study.usedByTheSolver) + ret = cluster->modulation.loadFromCSVFile(modulationFile, + thermalModulationMax, + HOURS_PER_YEAR, + options) && ret; + + // Check the data integrity of the cluster + addToCompleteList(cluster); + } + + rebuildIndexes(); + rebuildIndex(); + + return ret; +} + + +bool ThermalClusterList::validateClusters(const Parameters& parameters) const +{ + bool ret = true; + + for (const auto& cluster : allClusters_) + { + cluster->minUpTime = std::clamp(cluster->minUpTime, 1u, 168u); + cluster->minDownTime = std::clamp(cluster->minDownTime, 1u, 168u); + + // update the minUpDownTime + cluster->minUpDownTime = std::max(cluster->minUpTime, cluster->minDownTime); + + if (!parameters.include.thermal.minStablePower) + { + cluster->minStablePower = 0.; + } + if (!parameters.include.thermal.minUPTime) { - cluster->modulation.reset(thermalModulationMax, HOURS_PER_YEAR); - cluster->modulation.fill(1.); - cluster->modulation.fillColumn(thermalMinGenModulation, 0.); + cluster->minUpDownTime = 1; + cluster->minUpTime = 1; + cluster->minDownTime = 1; } - ret = ret && r; - // Special operations when not ran from the interface (aka solver) - if (study.usedByTheSolver) + if (!parameters.include.reserve.spinning) { - if (!study.parameters.include.thermal.minStablePower) - { - cluster->minStablePower = 0.; - } - if (!study.parameters.include.thermal.minUPTime) - { - cluster->minUpDownTime = 1; - cluster->minUpTime = 1; - cluster->minDownTime = 1; - } - else - { - cluster->minUpDownTime = std::max(cluster->minUpTime, cluster->minDownTime); - } + cluster->spinning = 0; + } - if (!study.parameters.include.reserve.spinning) - { - cluster->spinning = 0; - } + cluster->nominalCapacityWithSpinning = cluster->nominalCapacity; - cluster->nominalCapacityWithSpinning = cluster->nominalCapacity; - } + ret = cluster->integrityCheck() && ret; - // Check the data integrity of the cluster - cluster->integrityCheck(); - addToCompleteList(cluster); } - rebuildIndexes(); - rebuildIndex(); - return ret; } @@ -268,35 +272,11 @@ static bool ThermalClusterLoadFromProperty(ThermalCluster& cluster, const IniFil if (p->key == "min-up-time") { - if (p->value.to(cluster.minUpTime)) - { - if (cluster.minUpTime < 1) - { - cluster.minUpTime = 1; - } - if (cluster.minUpTime > 168) - { - cluster.minUpTime = 168; - } - return true; - } - return false; + return p->value.to(cluster.minUpTime); } if (p->key == "min-down-time") { - if (p->value.to(cluster.minDownTime)) - { - if (cluster.minDownTime < 1) - { - cluster.minDownTime = 1; - } - if (cluster.minDownTime > 168) - { - cluster.minDownTime = 168; - } - return true; - } - return false; + return p->value.to(cluster.minDownTime); } if (p->key == "name") { @@ -375,8 +355,6 @@ bool ThermalClusterLoadFromSection(const AnyString& filename, << property->key << "`: The property is unknown and ignored"; } } - // update the minUpDownTime - cluster.minUpDownTime = std::max(cluster.minUpTime, cluster.minDownTime); } return true; } @@ -399,7 +377,7 @@ void ThermalClusterList::reverseCalculationOfSpinning() void ThermalClusterList::enableMustrunForEveryone() { - for (auto& c: allClusters_) + for (const auto& c : allClusters_) { c->mustrun = true; } @@ -606,32 +584,41 @@ bool ThermalClusterList::saveEconomicCosts(const AnyString& folder) const bool ThermalClusterList::loadPreproFromFolder(Study& study, const AnyString& folder) { - const bool globalThermalTSgeneration = study.parameters.timeSeriesToGenerate - & timeSeriesThermal; - Clob buffer; auto hasPrepro = [](auto c) { return (bool)c->prepro; }; - auto loadAndCheckPrepro = [&buffer, &folder, &study, &globalThermalTSgeneration](auto c) + auto loadPrepro = [&buffer, &folder, &study](auto& c) { assert(c->parentArea && "cluster: invalid parent area"); buffer.clear() << folder << SEP << c->parentArea->id << SEP << c->id(); - bool result = c->prepro->loadFromFolder(study, buffer); + return c->prepro->loadFromFolder(study, buffer); + }; - if (study.usedByTheSolver && globalThermalTSgeneration) - { - result = c->prepro->validate() && result; - } + return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), loadPrepro); +} - if (result && study.usedByTheSolver && c->doWeGenerateTS(globalThermalTSgeneration)) - { - result = c->prepro->normalizeAndCheckNPO(); - } - return result; - }; +bool ThermalClusterList::validatePrepro(const Study& study) { + auto hasPrepro = [](auto c) { return (bool)c->prepro; }; + + const bool globalThermalTSgeneration = + study.parameters.timeSeriesToGenerate & timeSeriesThermal; + + if (!study.usedByTheSolver) + return true; - return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), loadAndCheckPrepro); + return std::ranges::all_of( + allClusters_ | std::views::filter(hasPrepro), + [&globalThermalTSgeneration](auto& c) { + if (globalThermalTSgeneration && !c->prepro->validate()) { + return false; + } + + if (c->doWeGenerateTS(globalThermalTSgeneration)) { + return c->prepro->normalizeAndCheckNPO(); + } + return true; + }); } bool ThermalClusterList::loadEconomicCosts(Study& study, const AnyString& folder) From 7dbb39cf91dd3d63d49fe55222407af550668859 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:37:18 +0200 Subject: [PATCH 023/127] Separation of loading and validation for renewables clusters [ANT-1213] (#2175) --- src/libs/antares/study/area/list.cpp | 1 + .../study/parts/renewable/cluster_list.h | 10 +++++----- .../study/parts/renewable/cluster_list.cpp | 19 +++++++++++++------ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index b622b94af9..fd2b3bb5b7 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -1222,6 +1222,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) Area& area = *(i->second); buffer.clear() << pStudy.folderInput << renewablePlant << area.id; ret = area.renewable.list.loadFromFolder(buffer.c_str(), &area) && ret; + ret = area.renewable.list.validateClusters() && ret; } } diff --git a/src/libs/antares/study/include/antares/study/parts/renewable/cluster_list.h b/src/libs/antares/study/include/antares/study/parts/renewable/cluster_list.h index edec4d1468..275d495020 100644 --- a/src/libs/antares/study/include/antares/study/parts/renewable/cluster_list.h +++ b/src/libs/antares/study/include/antares/study/parts/renewable/cluster_list.h @@ -26,9 +26,7 @@ #include "../common/cluster_list.h" #include "cluster.h" -namespace Antares -{ -namespace Data +namespace Antares::Data { /*! ** \brief List of renewable clusters @@ -39,10 +37,12 @@ class RenewableClusterList: public ClusterList public: std::string typeID() const override; uint64_t memoryUsage() const override; + bool loadFromFolder(const AnyString& folder, Area* area); + bool validateClusters() const; + bool saveToFolder(const AnyString& folder) const override; }; // class RenewableClusterList -} // namespace Data -} // namespace Antares +} // namespace Antares::Data #endif /* __ANTARES_LIBS_STUDY_PARTS_RENEWABLE_CLUSTER_LIST_H__ */ diff --git a/src/libs/antares/study/parts/renewable/cluster_list.cpp b/src/libs/antares/study/parts/renewable/cluster_list.cpp index d42e9c8d89..62db61a900 100644 --- a/src/libs/antares/study/parts/renewable/cluster_list.cpp +++ b/src/libs/antares/study/parts/renewable/cluster_list.cpp @@ -28,9 +28,7 @@ using namespace Yuni; -namespace Antares -{ -namespace Data +namespace Antares::Data { #define SEP IO::Separator @@ -211,7 +209,6 @@ bool RenewableClusterList::loadFromFolder(const AnyString& folder, Area* area) continue; } - cluster->integrityCheck(); addToCompleteList(cluster); } } @@ -223,7 +220,17 @@ bool RenewableClusterList::loadFromFolder(const AnyString& folder, Area* area) return false; } +bool RenewableClusterList::validateClusters() const +{ + bool ret = true; + for (const auto& cluster : allClusters_) + { + ret = cluster->integrityCheck() && ret; + } + + return ret; +} + #undef SEP -} // namespace Data -} // namespace Antares +} // namespace Antares::Data From 9e6cdcc717a4fbdd2bc11c55a939d99a90b9428a Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:01:05 +0200 Subject: [PATCH 024/127] Add ts-generation for links [ANT-1084] (#1986) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Florian Omnès <26088210+flomnes@users.noreply.github.com> Co-authored-by: Florian OMNES Co-authored-by: guilpier-code <62292552+guilpier-code@users.noreply.github.com> --- .github/workflows/ubuntu.yml | 9 ++ .github/workflows/windows-vcpkg.yml | 11 +- docs/user-guide/04-migration-guides.md | 20 ++++ src/libs/antares/study/area/links.cpp | 106 +++++++++++++++++- src/libs/antares/study/area/list.cpp | 2 +- .../antares/study/cleaner/cleaner-v20.cpp | 2 +- src/libs/antares/study/fwd.cpp | 4 + .../study/include/antares/study/area/area.h | 3 +- .../study/include/antares/study/area/links.h | 5 + .../antares/study/include/antares/study/fwd.h | 2 + .../include/antares/study/load-options.h | 4 + .../study/include/antares/study/parameters.h | 2 + src/libs/antares/study/parameters.cpp | 9 ++ .../antares/solver/simulation/solver.hxx | 1 + src/solver/ts-generator/availability.cpp | 90 ++++++++++++++- .../antares/solver/ts-generator/generator.h | 13 +++ .../antares/solver/ts-generator/prepro.h | 21 ++++ src/tools/ts-generator/main.cpp | 70 +++++++++++- 18 files changed, 362 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index c774854d16..85713eeb70 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -229,6 +229,15 @@ jobs: os: ${{ env.os }} variant: "parallel" + - name: Run tests for time series generator tool + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: ts-generator + os: ${{ env.os }} + variant: "tsgenerator" + - name: Run medium-tests if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index ccc8794dcb..59e931e6a8 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -246,6 +246,15 @@ jobs: os: ${{ env.test-platform }} variant: "parallel" + - name: Run tests for time series generator tool + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: ts-generator + os: ${{ env.test-platform }} + variant: "tsgenerator" + - name: Run medium-tests if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests @@ -304,7 +313,7 @@ jobs: run: | cd _build cpack -G ZIP - + - name: Installer upload uses: actions/upload-artifact@v4 with: diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 0e5f50726c..5dbc3f8885 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -1,5 +1,25 @@ # Migration guides This is a list of all recent changes that came with new Antares Simulator features. The main goal of this document is to lower the costs of changing existing interfaces, both GUI and scripts. + +## v9.2.0 +### (TS-generator only) TS generation for link capacities +In files input/links//properties.ini, add the following properties +- tsgen_direct_XXX, +- tsgen_indirect_XXX +with XXX in +- unitcount (unsigned int, default 1) +- nominalcapacity (float) +- law.planned (string "uniform"/"geometric") +- law.forced (same) +- volatility.planned (double in [0,1]) +- volatility.forced (same) + +- "prepro" timeseries => input/links//prepro/_{direct, indirect}.txt, 365x6 values, respectively "forced outage duration", "planned outage duration", "forced outage rate", "planned outage rate", "minimum of groups in maintenance", "maximum of groups in maintenance". +- "modulation" timeseries => input/links//prepro/_mod_{direct, indirect}.txt, 8760x1 values each in [0, 1] +- number of TS to generate => generaldata.ini/General/nbtimeserieslinks (unsigned int, default value 1) + + + ## v9.1.0 ### Input #### Hydro Maximum Generation/Pumping Power diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 4d4b6af140..40da9df149 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -21,8 +21,11 @@ #include "antares/study/area/links.h" +#include #include +#include + #include #include @@ -134,6 +137,58 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol return success; } +// This function is "lazy", it only loads files if they exist +// and set a `valid` flag +bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) +{ + const std::string idprepro = std::string(from->id) + "/" + std::string(with->id); + tsGeneration.prepro = + std::make_unique(idprepro, tsGeneration.unitCount); + + bool anyFileWasLoaded = false; + + // file name without suffix, .txt for general infos and mod_direct/indirect.txt + fs::path preproFile = folder / "prepro" / with->id.c_str(); + + // Prepro + fs::path filepath = preproFile; + filepath += ".txt"; + if (fs::exists(filepath)) + { + anyFileWasLoaded = true; + tsGeneration.valid = tsGeneration.prepro->data.loadFromCSVFile( + filepath.string(), + Antares::Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && tsGeneration.prepro->validate(); + } + + // Modulation + filepath = preproFile; + filepath += "_mod_direct.txt"; + if (fs::exists(filepath)) + { + anyFileWasLoaded = true; + tsGeneration.valid &= tsGeneration.modulationCapacityDirect + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); + } + + filepath = preproFile; + filepath += "_mod_indirect.txt"; + if (fs::exists(filepath)) + { + anyFileWasLoaded = true; + tsGeneration.valid &= tsGeneration.modulationCapacityIndirect + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); + } + + if (anyFileWasLoaded) + { + return tsGeneration.valid; + } + return true; +} + bool AreaLink::isLinkPhysical() const { // All link types are physical, except arVirt @@ -448,13 +503,55 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) link.filterYearByYear = stringIntoDatePrecision(value); return true; } + return false; +} + +bool handleTSGenKey(Data::LinkTsGeneration& out, + const std::string& key, + const String& value) +{ + + if (key == "unitcount") + { + return value.to(out.unitCount); + } + + if (key == "nominalcapacity") + { + return value.to(out.nominalCapacity); + } + + if (key == "law.planned") + { + return value.to(out.plannedLaw); + } + + if (key == "law.forced") + { + return value.to(out.forcedLaw); + } + + if (key == "volatility.planned") + { + return value.to(out.plannedVolatility); + } + + if (key == "volatility.forced") + { + return value.to(out.forcedVolatility); + } + + if (key == "force-no-generation") + { + return value.to(out.forceNoGeneration); + } return false; } bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const String& value) { - return handleKey(link, key, value); + return handleKey(link, key, value) || handleTSGenKey(link.tsGeneration, key, value); } [[noreturn]] void logLinkDataCheckError(const AreaLink& link, const String& msg, int hour) @@ -475,7 +572,7 @@ bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const } } // anonymous namespace -bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::path& folder) +bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::path& folder, bool loadTSGen) { // Assert assert(area); @@ -601,6 +698,11 @@ bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::pa } } + if (loadTSGen) + { + ret = link.loadTSGenTimeSeries(folder) && ret; + } + // From the solver only if (study.usedByTheSolver) { diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index fd2b3bb5b7..f76afb5686 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -881,7 +881,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, // Links { fs::path folder = fs::path(study.folderInput.c_str()) / "links" / area.id.c_str(); - ret = AreaLinksLoadFromFolder(study, list, &area, folder) && ret; + ret = AreaLinksLoadFromFolder(study, list, &area, folder, options.linksLoadTSGen) && ret; } // UI diff --git a/src/libs/antares/study/cleaner/cleaner-v20.cpp b/src/libs/antares/study/cleaner/cleaner-v20.cpp index 3c8f183be4..7d1aadf58e 100644 --- a/src/libs/antares/study/cleaner/cleaner-v20.cpp +++ b/src/libs/antares/study/cleaner/cleaner-v20.cpp @@ -362,7 +362,7 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) logs.verbosityLevel = Logs::Verbosity::Warning::level; // load all links buffer.clear() << infos->folder << "/input/links/" << area->id; - if (not AreaLinksLoadFromFolder(*study, arealist, area, buffer.c_str())) + if (not AreaLinksLoadFromFolder(*study, arealist, area, buffer.c_str(), false)) { delete arealist; delete study; diff --git a/src/libs/antares/study/fwd.cpp b/src/libs/antares/study/fwd.cpp index 100a4b127e..f45f093aaf 100644 --- a/src/libs/antares/study/fwd.cpp +++ b/src/libs/antares/study/fwd.cpp @@ -53,6 +53,8 @@ const char* SeedToCString(SeedIndex seed) return "Noise on virtual Hydro costs"; case seedHydroManagement: return "Initial reservoir levels"; + case seedTsGenLinks: + return "Links time-series generation"; case seedMax: return ""; } @@ -85,6 +87,8 @@ const char* SeedToID(SeedIndex seed) return "seed-hydro-costs"; case seedHydroManagement: return "seed-initial-reservoir-levels"; + case seedTsGenLinks: + return "seed-tsgen-links"; case seedMax: return ""; } diff --git a/src/libs/antares/study/include/antares/study/area/area.h b/src/libs/antares/study/include/antares/study/area/area.h index 6661ab8556..6fbb69dde4 100644 --- a/src/libs/antares/study/include/antares/study/area/area.h +++ b/src/libs/antares/study/include/antares/study/area/area.h @@ -727,7 +727,8 @@ AreaLink* AreaAddLinkBetweenAreas(Area* area, Area* with, bool warning = true); bool AreaLinksLoadFromFolder(Study& s, AreaList* l, Area* area, - const std::filesystem::path& folder); + const std::filesystem::path& folder, + bool loadTSGen); /*! ** \brief Save interconnections of a given area into a folder (`input/areas/[area]/ntc`) diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index fd4b8e69d8..5b01ba3efd 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -71,6 +71,8 @@ class AreaLink final: public Yuni::NonCopyable bool loadTimeSeries(const StudyVersion& version, const AnyString& folder); + bool loadTSGenTimeSeries(const std::filesystem::path& folder); + void storeTimeseriesNumbers(Solver::IResultWriter& writer) const; //! \name Area @@ -206,6 +208,9 @@ class AreaLink final: public Yuni::NonCopyable int linkWidth; friend struct CompareLinkName; + + LinkTsGeneration tsGeneration; + }; // class AreaLink struct CompareLinkName final diff --git a/src/libs/antares/study/include/antares/study/fwd.h b/src/libs/antares/study/include/antares/study/fwd.h index 6fa2819aca..7256eda4a2 100644 --- a/src/libs/antares/study/include/antares/study/fwd.h +++ b/src/libs/antares/study/include/antares/study/fwd.h @@ -361,6 +361,8 @@ enum SeedIndex seedHydroCosts, //! Seed - Hydro management seedHydroManagement, + //! The seed for links + seedTsGenLinks, //! The number of seeds seedMax, }; diff --git a/src/libs/antares/study/include/antares/study/load-options.h b/src/libs/antares/study/include/antares/study/load-options.h index 898b641653..1ecd34b968 100644 --- a/src/libs/antares/study/include/antares/study/load-options.h +++ b/src/libs/antares/study/include/antares/study/load-options.h @@ -52,6 +52,10 @@ class StudyLoadOptions bool loadOnlyNeeded; //! Force the year-by-year flag bool forceYearByYear; + + //! Load data associated to link TS generation + bool linksLoadTSGen = false; + //! Force the derated mode bool forceDerated; diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index c66cf9757f..cb69fb4326 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -256,6 +256,8 @@ class Parameters final uint nbTimeSeriesThermal; //! Nb of timeSeries : Solar uint nbTimeSeriesSolar; + //! Nb of timeSeries : Links + uint nbLinkTStoGenerate = 1; //@} //! \name Time-series refresh diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index a598ee1566..5c0cdac583 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -528,6 +528,10 @@ static bool SGDIntLoadFamily_General(Parameters& d, { return value.to(d.nbTimeSeriesSolar); } + if (key == "nbtimeserieslinks") + { + return value.to(d.nbLinkTStoGenerate); + } // Interval values if (key == "refreshintervalload") { @@ -1054,6 +1058,10 @@ static bool SGDIntLoadFamily_SeedsMersenneTwister(Parameters& d, { return value.to(d.seed[seedTsGenSolar]); } + if (key == "seed_links") + { + return value.to(d.seed[seedTsGenLinks]); + } if (key == "seed_timeseriesnumbers") { return value.to(d.seed[seedTimeseriesNumbers]); @@ -1783,6 +1791,7 @@ void Parameters::saveToINI(IniFile& ini) const section->add("nbTimeSeriesWind", nbTimeSeriesWind); section->add("nbTimeSeriesThermal", nbTimeSeriesThermal); section->add("nbTimeSeriesSolar", nbTimeSeriesSolar); + section->add("nbtimeserieslinks", nbLinkTStoGenerate); // Refresh ParametersSaveTimeSeries(section, "refreshTimeSeries", timeSeriesToRefresh); diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 8084130e9f..5e36fcaca8 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -938,6 +938,7 @@ static inline void logPerformedYearsInAset(setOfParallelYears& set) << " perfomed)"; std::string performedYearsToLog = ""; + std::ranges::for_each(set.yearsIndices, [&set, &performedYearsToLog](const uint& y) { diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index f9b50696df..69f62a10a1 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -50,12 +50,29 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* s { } +AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::LinkTsGeneration& source, + Data::TimeSeries& capacity, + Matrix<>& modulation, + const std::string& areaDestName): + unitCount(source.unitCount), + nominalCapacity(source.nominalCapacity), + forcedVolatility(source.forcedVolatility), + plannedVolatility(source.plannedVolatility), + forcedLaw(source.forcedLaw), + plannedLaw(source.plannedLaw), + prepro(source.prepro.get()), + series(capacity.timeSeries), + modulationCapacity(modulation[0]), + name(areaDestName) +{ +} + namespace { class GeneratorTempData final { public: - explicit GeneratorTempData(Data::Study&, unsigned); + explicit GeneratorTempData(Data::Study&, unsigned, MersenneTwister&); void generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) const; @@ -82,10 +99,10 @@ class GeneratorTempData final const T& duration) const; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen): +GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen, MersenneTwister& rndGenerator): derated(study.parameters.derated), nbOfSeriesToGen_(nbOfSeriesToGen), - rndgenerator(study.runtime->random[Data::seedTsGenThermal]) + rndgenerator(rndGenerator) { } @@ -592,6 +609,23 @@ std::vector getAllClustersToGen(const Data::AreaList& are return clusters; } +listOfLinks getAllLinksToGen(Data::AreaList& areas) +{ + listOfLinks links; + + areas.each( + [&links](const Data::Area& area) + { + std::ranges::for_each(area.links, [&links](auto& l) + { + if (!l.second->tsGeneration.forceNoGeneration) + links.push_back(l.second); + }); + }); + + return links; +} + void writeResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, const Matrix<>& series, @@ -617,7 +651,9 @@ bool generateThermalTimeSeries(Data::Study& study, bool archive = study.parameters.timeSeriesToArchive & Data::timeSeriesThermal; - auto generator = GeneratorTempData(study, study.parameters.nbTimeSeriesThermal); + auto generator = GeneratorTempData(study, + study.parameters.nbTimeSeriesThermal, + study.runtime->random[Data::seedTsGenThermal]); // TODO VP: parallel for (auto* cluster: clusters) @@ -636,4 +672,50 @@ bool generateThermalTimeSeries(Data::Study& study, return true; } +bool generateLinkTimeSeries(Data::Study& study, + const listOfLinks& links, + Solver::IResultWriter& writer, + const std::string& savePath) +{ + logs.info(); + logs.info() << "Generating the links time-series"; + + auto generator = GeneratorTempData(study, + study.parameters.nbLinkTStoGenerate, + study.runtime->random[Data::seedTsGenLinks]); + + for (const auto& link: links) + { + Data::TimeSeries ts(link->timeseriesNumbers); + ts.resize(study.parameters.nbLinkTStoGenerate, HOURS_PER_YEAR); + + auto& tsGenStruct = link->tsGeneration; + + if (!tsGenStruct.valid) + { + logs.error() << "Missing data for link " << link->from->id << "/" << link->with->id; + return false; + } + + // DIRECT + AvailabilityTSGeneratorData tsConfigDataDirect(tsGenStruct, ts, tsGenStruct.modulationCapacityDirect, link->with->name); + + generator.generateTS(*link->from, tsConfigDataDirect); + + std::string filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + + "_direct.txt"; + writeResultsToDisk(study, writer, ts.timeSeries, filePath); + + // INDIRECT + AvailabilityTSGeneratorData tsConfigDataIndirect(tsGenStruct, ts, tsGenStruct.modulationCapacityIndirect, link->with->name); + + generator.generateTS(*link->from, tsConfigDataIndirect); + + filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + + "_indirect.txt"; + writeResultsToDisk(study, writer, ts.timeSeries, filePath); + } + + return true; +} } // namespace Antares::TSGenerator diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 77e09b9b79..1c32e67bdd 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -39,6 +39,10 @@ class AvailabilityTSGeneratorData { public: explicit AvailabilityTSGeneratorData(Data::ThermalCluster*); + AvailabilityTSGeneratorData(Data::LinkTsGeneration&, + Data::TimeSeries&, + Matrix<>& modulation, + const std::string& name); const unsigned& unitCount; const double& nominalCapacity; @@ -58,6 +62,8 @@ class AvailabilityTSGeneratorData const std::string& name; }; +using listOfLinks = std::vector; + void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); /*! @@ -71,9 +77,16 @@ bool generateThermalTimeSeries(Data::Study& study, Solver::IResultWriter& writer, const std::string& savePath); +bool generateLinkTimeSeries(Data::Study& study, + const listOfLinks& links, + Solver::IResultWriter& writer, + const std::string& savePath); + std::vector getAllClustersToGen(const Data::AreaList& areas, bool globalThermalTSgeneration); +listOfLinks getAllLinksToGen(Data::AreaList& areas); + /*! ** \brief Destroy all TS Generators */ diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index cc02a50619..ac36a826ea 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -115,6 +115,27 @@ class PreproAvailability unsigned int unitCount; }; // class PreproAvailability +struct LinkTsGeneration +{ + unsigned unitCount = 0; + double nominalCapacity = 0; + + double forcedVolatility = 0.; + double plannedVolatility = 0.; + + Data::StatisticalLaw forcedLaw = LawUniform; + Data::StatisticalLaw plannedLaw = LawUniform; + + std::unique_ptr prepro; + + Matrix<> modulationCapacityDirect; + Matrix<> modulationCapacityIndirect; + + bool valid = false; + + bool forceNoGeneration = false; +}; + } // namespace Antares::Data #endif // __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_HXX__ diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index f59a5dc614..8f23f60619 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -35,6 +35,10 @@ #include #include +using namespace Antares; + +namespace fs = std::filesystem; + struct Settings { std::string studyFolder; @@ -43,6 +47,11 @@ struct Settings bool allThermal = false; /// generate TS for a list "area.cluster;area2.cluster2;" std::string thermalListToGen = ""; + + /// generate TS for all links if activated + bool allLinks = false; + /// generate TS for a list "area.link;area2.link2;" + std::string linksListToGen = ""; }; std::unique_ptr createTsGeneratorParser(Settings& settings) @@ -58,7 +67,14 @@ std::unique_ptr createTsGeneratorParser(Settings& settings ' ', "thermal", "Generate TS for a list of area IDs and thermal clusters IDs, " - "usage:\n\t--thermal=\"areaID.clusterID;area2ID.clusterID\""); + "\nusage: --thermal=\"areaID.clusterID;area2ID.clusterID\""); + + parser->addFlag(settings.allLinks, ' ', "all-links", "Generate TS capacities for all links"); + parser->addFlag(settings.linksListToGen, + ' ', + "links", + "Generate TS capacities for a list of 2 area IDs, " + "usage: --links=\"areaID.area2ID;area3ID.area1ID\""); parser->remainingArguments(settings.studyFolder); @@ -95,8 +111,32 @@ std::vector getClustersToGen(Data::AreaList& areas, return clusters; } +TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, const std::string& linksToGen) +{ + TSGenerator::listOfLinks links; + const auto ids = splitStringIntoPairs(linksToGen, ';', '.'); + + for (const auto& [areaFromID, areaWithID]: ids) + { + logs.info() << "Searching for link: " << areaFromID << "/" << areaWithID; + + auto* link = areas.findLink(areaFromID, areaWithID); + if (!link) + { + logs.warning() << "Link not found: " << areaFromID << "/" << areaWithID; + continue; + } + + links.emplace_back(link); + } + + return links; +} + int main(int argc, char* argv[]) { + logs.applicationName("ts-generator"); + Settings settings; auto parser = createTsGeneratorParser(settings); @@ -119,9 +159,16 @@ int main(int argc, char* argv[]) return 1; } + if (settings.allLinks && !settings.linksListToGen.empty()) + { + logs.error() << "Conflicting options, either choose all links or a list"; + return 1; + } + auto study = std::make_shared(true); Data::StudyLoadOptions studyOptions; studyOptions.prepareOutput = true; + studyOptions.linksLoadTSGen = true; if (!study->loadFromFolder(settings.studyFolder, studyOptions)) { @@ -149,7 +196,8 @@ int main(int argc, char* argv[]) nullptr, durationCollector); - const auto thermalSavePath = std::filesystem::path("ts-generator") / "thermal"; + const auto thermalSavePath = fs::path("ts-generator") / "thermal"; + const auto linksSavePath = fs::path("ts-generator") / "links"; // THERMAL std::vector clusters; @@ -167,10 +215,28 @@ int main(int argc, char* argv[]) logs.debug() << c->id(); } + // LINKS + TSGenerator::listOfLinks links; + if (settings.allLinks) + { + links = TSGenerator::getAllLinksToGen(study->areas); + } + else if (!settings.linksListToGen.empty()) + { + links = getLinksToGen(study->areas, settings.linksListToGen); + } + + for (auto& l: links) + { + logs.debug() << l->getName(); + } + bool ret = TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath.string()); + ret = TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath.string()) + && ret; return !ret; // return 0 for success } From d23369185ef4851a2b9c63345aab73f2b0cddea1 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:36:38 +0200 Subject: [PATCH 025/127] Separation of loading and validation for parameters [ANT-1213] (#2177) --- .../study/include/antares/study/parameters.h | 5 +- src/libs/antares/study/load.cpp | 8 +- src/libs/antares/study/parameters.cpp | 153 ++++++++---------- .../study/parameters/parameters-tests.cpp | 4 + 4 files changed, 78 insertions(+), 92 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index cb69fb4326..791e20f865 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -137,6 +137,8 @@ class Parameters final */ void fixBadValues(); + void validateOptions(const StudyLoadOptions&); + /*! ** \brief Try to detect then fix refresh intervals */ @@ -503,8 +505,7 @@ class Parameters final private: //! Load data from an INI file bool loadFromINI(const IniFile& ini, - const StudyVersion& version, - const StudyLoadOptions& options); + const StudyVersion& version); void resetPlayedYears(uint nbOfYears); diff --git a/src/libs/antares/study/load.cpp b/src/libs/antares/study/load.cpp index 00214717e8..4555e106bd 100644 --- a/src/libs/antares/study/load.cpp +++ b/src/libs/antares/study/load.cpp @@ -83,7 +83,13 @@ bool Study::internalLoadIni(const String& path, const StudyLoadOptions& options) } // Load the general data buffer.clear() << folderSettings << SEP << "generaldata.ini"; - if (!parameters.loadFromFile(buffer, header.version, options)) + bool errorWhileLoading = !parameters.loadFromFile(buffer, header.version, options); + + parameters.validateOptions(options); + + parameters.fixBadValues(); + + if (errorWhileLoading) { if (options.loadOnlyNeeded) { diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index 5c0cdac583..7337b9c8b0 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -566,43 +566,11 @@ static bool SGDIntLoadFamily_General(Parameters& d, if (key == "simulation.start") { - uint day; - if (not value.to(day)) - { - return false; - } - if (day == 0) - { - day = 1; - } - else - { - if (day > 365) - { - day = 365; - } - --day; - } - d.simulationDays.first = day; - return true; + return value.to(d.simulationDays.first); } if (key == "simulation.end") { - uint day; - if (not value.to(day)) - { - return false; - } - if (day == 0) - { - day = 1; - } - else if (day > 365) - { - day = 365; - } - d.simulationDays.end = day; // not included - return true; + return value.to(d.simulationDays.end); } if (key == "thematic-trimming") @@ -1158,8 +1126,7 @@ bool firstKeyLetterIsValid(const String& name) } bool Parameters::loadFromINI(const IniFile& ini, - const StudyVersion& version, - const StudyLoadOptions& options) + const StudyVersion& version) { // Reset inner data reset(); @@ -1229,62 +1196,10 @@ bool Parameters::loadFromINI(const IniFile& ini, } } - // forcing value - if (options.nbYears != 0) - { - if (options.nbYears > nbYears) - { - // The variable `yearsFilter` must be enlarged - yearsFilter.resize(options.nbYears, false); - } - nbYears = options.nbYears; - - // Resize years weight (add or remove item) - if (yearsWeight.size() != nbYears) - { - yearsWeight.resize(nbYears, 1.f); - } - } - - // Simulation mode - // ... Enforcing simulation mode - if (options.forceMode != SimulationMode::Unknown) - { - mode = options.forceMode; - logs.info() << " forcing the simulation mode " << SimulationModeToCString(mode); - } - else - { - logs.info() << " simulation mode: " << SimulationModeToCString(mode); - } - - if (options.forceDerated) - { - derated = true; - } - - namedProblems = options.namedProblems; - - handleOptimizationOptions(options); - - // Attempt to fix bad values if any - fixBadValues(); - fixRefreshIntervals(); fixGenRefreshForNTC(); - // Specific action before launching a simulation - if (options.usedByTheSolver) - { - prepareForSimulation(options); - } - - if (options.mpsToExport || options.namedProblems) - { - this->include.exportMPS = mpsExportStatus::EXPORT_BOTH_OPTIMS; - } - // We currently always returns true to not block any loading process // Anyway we already have reported all problems return true; @@ -1375,6 +1290,66 @@ void Parameters::fixBadValues() { nbTimeSeriesSolar = 1; } + + if (simulationDays.first == 0) + simulationDays.first = 1; + else + { + simulationDays.first = std::clamp(simulationDays.first, 1u, 365u); + --simulationDays.first; // value between 0 and 364 for edge cases + } + + simulationDays.end = std::clamp(simulationDays.end, 1u, 365u); +} + +void Parameters::validateOptions(const StudyLoadOptions& options) +{ + if (options.forceDerated) + { + derated = true; + } + // forcing value + if (options.nbYears != 0) + { + if (options.nbYears > nbYears) + { + // The variable `yearsFilter` must be enlarged + yearsFilter.resize(options.nbYears, false); + } + nbYears = options.nbYears; + + // Resize years weight (add or remove item) + if (yearsWeight.size() != nbYears) + { + yearsWeight.resize(nbYears, 1.f); + } + } + + // Simulation mode + // ... Enforcing simulation mode + if (options.forceMode != SimulationMode::Unknown) + { + mode = options.forceMode; + logs.info() << " forcing the simulation mode " << SimulationModeToCString(mode); + } + else + { + logs.info() << " simulation mode: " << SimulationModeToCString(mode); + } + // Specific action before launching a simulation + if (options.usedByTheSolver) + { + prepareForSimulation(options); + } + + if (options.mpsToExport || options.namedProblems) + { + this->include.exportMPS = mpsExportStatus::EXPORT_BOTH_OPTIMS; + } + + namedProblems = options.namedProblems; + + handleOptimizationOptions(options); } uint64_t Parameters::memoryUsage() const @@ -1990,7 +1965,7 @@ bool Parameters::loadFromFile(const AnyString& filename, IniFile ini; if (ini.open(filename)) { - return loadFromINI(ini, version, options); + return loadFromINI(ini, version); } // Error otherwise diff --git a/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp b/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp index 14ee6a4435..07c8e7fa1d 100644 --- a/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp +++ b/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp @@ -70,6 +70,8 @@ BOOST_FIXTURE_TEST_CASE(loadValid, Fixture) writeValidFile(); p.loadFromFile(path.string(), version, options); + p.validateOptions(options); + p.fixBadValues(); BOOST_CHECK_EQUAL(p.nbYears, 5); BOOST_CHECK_EQUAL(p.seed[seedTsGenThermal], 5489); @@ -93,6 +95,8 @@ BOOST_FIXTURE_TEST_CASE(invalidValues, Fixture) { writeInvalidFile(); BOOST_CHECK(p.loadFromFile(path.string(), version, options)); + p.validateOptions(options); + p.fixBadValues(); BOOST_CHECK_EQUAL(p.nbYears, 1); BOOST_CHECK_EQUAL(p.useCustomScenario, 0); From b3f3fc0b9147816adf22f9f29d17b83be4e5125c Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:42:07 +0200 Subject: [PATCH 026/127] Hydro final lvl (CR 25) to merge in develop [ANT-1084] (#1521) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR attempts some code enhancements on branch **feature/final-reservoir-level-cr25**. Therefore, this PR's associated branch (**fix/hydro-final-levels-cr25--try-fixes**) is based on **feature/final-reservoir-level-cr25**. - [x] in class **FinalLevelInflowsModifier**, - try to reduce the number of data members, - making data members **private** whenever it's possible, - define a clear interface with a smallest number of public functions - and so make the more methods private as possible - [x] **Unit tests** : clarify their intention and reduce their size - [ ] **caution** : could not remove yet the **initialize** method. This method should be merged with the constructor, but when we call the constructor, all input pieces of data are not available. that's why **initialize** exists. We should try to make these pieces of data available, for instance by changing the order of data loading For any purpose, here are doc resources : - specs [here](https://rteinternational.sharepoint.com/:w:/r/sites/AntaresUser'sClub-Interne/_layouts/15/Doc.aspx?sourcedoc=%7B7774488E-7E4C-4AEC-B11F-1C9728B96AC0%7D&file=Functional_Specifications-Final_reservoir_level_V0.1-MA.docx&action=default&mobileredirect=true) - a discussion on that matter [here](https://github.com/AntaresSimulatorTeam/Antares_Simulator/discussions/1145) --- ### CAUTION : **Some cleaning and corrections were introduced in a new pull request** (see [this PR](https://github.com/AntaresSimulatorTeam/Antares_Simulator/pull/2040)). This new PR was merged into this one. **This PR contains a test under the form of a study. This study should be downloaded and added to the right test repo.** --- ### Left to to - [ ] Merge from branch develop and remove conflicts - [ ] Check that all tests exist (unit test for raising failures and study case for fine working) - [ ] what else ? --------- Co-authored-by: Milos A Co-authored-by: Milos <97689304+Milos-RTEi@users.noreply.github.com> Co-authored-by: Florian Omnès Co-authored-by: NikolaIlic --- docs/user-guide/04-migration-guides.md | 4 + src/CMakeLists.txt | 1 + src/antares-deps | 1 + src/libs/antares/study/CMakeLists.txt | 2 + src/libs/antares/study/area/area.cpp | 3 + .../antares/study/parts/hydro/container.h | 5 +- .../study/parts/hydro/finalLevelValidator.h | 73 +++++ .../study/scenario-builder/hydroLevelsData.h | 24 +- .../antares/study/scenario-builder/rules.h | 9 +- .../study/include/antares/study/study.h | 5 +- .../antares/study/parts/hydro/container.cpp | 3 +- .../study/parts/hydro/finalLevelValidator.cpp | 157 ++++++++++ .../scenario-builder/hydroLevelsData.cpp | 15 +- .../antares/study/scenario-builder/rules.cpp | 129 ++++---- .../solver/hydro/management/management.h | 2 + src/solver/hydro/management/daily.cpp | 2 + src/solver/hydro/management/management.cpp | 22 +- src/solver/hydro/management/monthly.cpp | 32 +- src/solver/simulation/CMakeLists.txt | 59 ++-- .../hydro-final-reservoir-level-functions.cpp | 68 +++++ .../hydro-final-reservoir-level-functions.h | 37 +++ .../antares/solver/simulation/solver.hxx | 22 +- .../end-to-end/simple_study/simple-study.cpp | 3 +- src/tests/end-to-end/utils/utils.cpp | 1 + .../test-sc-builder-file-read-line.cpp | 70 ++++- .../test-sc-builder-file-save.cpp | 31 +- .../src/solver/simulation/CMakeLists.txt | 29 ++ ...-hydro-final-reservoir-level-functions.cpp | 275 ++++++++++++++++++ .../main/build/scenario-builder.cpp | 30 +- src/ui/simulator/application/main/main.h | 3 +- src/ui/simulator/cmake/components.cmake | 2 + ...io-builder-hydro-final-levels-renderer.cpp | 82 ++++++ ...ario-builder-hydro-final-levels-renderer.h | 56 ++++ ...scenario-builder-hydro-levels-renderer.cpp | 30 +- 34 files changed, 1120 insertions(+), 167 deletions(-) create mode 160000 src/antares-deps create mode 100644 src/libs/antares/study/include/antares/study/parts/hydro/finalLevelValidator.h create mode 100644 src/libs/antares/study/parts/hydro/finalLevelValidator.cpp create mode 100644 src/solver/simulation/hydro-final-reservoir-level-functions.cpp create mode 100644 src/solver/simulation/include/antares/solver/simulation/hydro-final-reservoir-level-functions.h create mode 100644 src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp create mode 100644 src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.cpp create mode 100644 src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.h diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 5dbc3f8885..c423bc5346 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -129,6 +129,10 @@ For each thermal cluster, in existing file **input/thermal/clusters/<area> For each thermal cluster, new files added **input/thermal/series/<area>/<cluster>/CO2Cost.txt** and **input/thermal/series/<area>/<cluster>/fuelCost.txt**. **fuelCost.txt** and **CO2Cost.txt** must either have one column, or the same number of columns as existing file **series.txt** (availability). The number of rows for these new matrices is 8760. +#### Hydro Final Reservoir Level +In the existing file **settings/scenariobuilder.dat**, under **<ruleset>** section following properties added (if final reservoir level specified, different from `init`): +* **hfl,<area>,<year> = <hfl-value>** + ### Output #### Scenarized RHS for binding constraints Add directory **bindingconstraints** to output directory **ts-numbers**. For every binding constraint group, add a file **ts-numbers/bindingconstraints/<group>.txt** containing the TS numbers used for that group. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 51fdc67271..862c7fdbc8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ set(ANTARES_VERSION_HI 9) set(ANTARES_VERSION_LO 1) set(ANTARES_VERSION_REVISION 0) + # Beta release set(ANTARES_BETA 0) set(ANTARES_RC 0) diff --git a/src/antares-deps b/src/antares-deps new file mode 160000 index 0000000000..0d6bebfb90 --- /dev/null +++ b/src/antares-deps @@ -0,0 +1 @@ +Subproject commit 0d6bebfb901e47ec6ac1c73cb61a522803c81b98 diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index c0b5b84c56..c90d543fff 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -122,6 +122,8 @@ set(SRC_STUDY_PART_HYDRO include/antares/study/parts/hydro/allocation.h include/antares/study/parts/hydro/allocation.hxx parts/hydro/allocation.cpp + include/antares/study/parts/hydro/finalLevelValidator.h + parts/hydro/finalLevelValidator.cpp include/antares/study/parts/hydro/hydromaxtimeseriesreader.h parts/hydro/hydromaxtimeseriesreader.cpp ) diff --git a/src/libs/antares/study/area/area.cpp b/src/libs/antares/study/area/area.cpp index 77f0fe6dd9..2984704716 100644 --- a/src/libs/antares/study/area/area.cpp +++ b/src/libs/antares/study/area/area.cpp @@ -45,6 +45,7 @@ void Area::internalInitialize() } Area::Area(): + hydro(*this), reserves(fhrMax, HOURS_PER_YEAR), miscGen(fhhMax, HOURS_PER_YEAR) { @@ -52,6 +53,7 @@ Area::Area(): } Area::Area(const AnyString& name): + hydro(*this), reserves(fhrMax, HOURS_PER_YEAR), miscGen(fhhMax, HOURS_PER_YEAR) { @@ -62,6 +64,7 @@ Area::Area(const AnyString& name): Area::Area(const AnyString& name, const AnyString& id): + hydro(*this), reserves(fhrMax, HOURS_PER_YEAR), miscGen(fhhMax, HOURS_PER_YEAR) { diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index 0297540a4d..e09970b79c 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -21,6 +21,7 @@ #ifndef __ANTARES_LIBS_STUDY_PARTS_HYDRO_CONTAINER_H__ #define __ANTARES_LIBS_STUDY_PARTS_HYDRO_CONTAINER_H__ +#include #include "../../fwd.h" #include "allocation.h" #include "prepro.h" @@ -80,7 +81,7 @@ class PartHydro /*! ** \brief Default Constructor */ - PartHydro(); + PartHydro(const Data::Area& area); //! Destructor ~PartHydro(); @@ -165,6 +166,8 @@ class PartHydro Matrix dailyNbHoursAtGenPmax; Matrix dailyNbHoursAtPumpPmax; + std::vector> deltaBetweenFinalAndInitialLevels; + private: static bool checkReservoirLevels(const Study& study); static bool checkProperties(Study& study); diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/finalLevelValidator.h b/src/libs/antares/study/include/antares/study/parts/hydro/finalLevelValidator.h new file mode 100644 index 0000000000..518e29d40b --- /dev/null +++ b/src/libs/antares/study/include/antares/study/parts/hydro/finalLevelValidator.h @@ -0,0 +1,73 @@ +/* +** Copyright 2007-2023 RTE +** Authors: Antares_Simulator Team +** +** This file is part of Antares_Simulator. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** There are special exceptions to the terms and conditions of the +** license as they are applied to this software. View the full text of +** the exceptions in file COPYING.txt in the directory of this software +** distribution +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Antares_Simulator. If not, see . +** +** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions +*/ +#pragma once + +#include "antares/study/parts/hydro/container.h" + +namespace Antares::Data +{ +class PartHydro; + +class FinalLevelValidator +{ +public: + FinalLevelValidator(PartHydro& hydro, + unsigned int areaIndex, + const AreaName areaName, + double initialLevel, + double finalLevel, + const unsigned int year, + const unsigned int lastSimulationDay, + const unsigned int firstMonthOfSimulation); + bool check(); + bool finalLevelFineForUse(); + +private: + bool wasSetInScenarioBuilder(); + bool compatibleWithReservoirProperties(); + bool skippingFinalLevelUse(); + bool checkForInfeasibility(); + bool hydroAllocationStartMatchesSimulation() const; + bool isFinalLevelReachable() const; + double calculateTotalInflows() const; + bool isBetweenRuleCurves() const; + + // Data from simulation + unsigned int year_ = 0; + unsigned int lastSimulationDay_ = 0; + unsigned int firstMonthOfSimulation_ = 0; + + // Data from area + PartHydro& hydro_; + unsigned int areaIndex_; + const AreaName areaName_; + double initialLevel_; + double finalLevel_; + + bool finalLevelFineForUse_ = false; +}; +} // namespace Antares::Data diff --git a/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h index 0f01fb9c32..42aff6336a 100644 --- a/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h +++ b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h @@ -22,6 +22,7 @@ #define __LIBS_STUDY_SCENARIO_BUILDER_DATA_HYDRO_LEVELS_H__ #include "scBuilderDataInterface.h" +#include namespace Antares { @@ -39,7 +40,10 @@ class hydroLevelsData final: public dataInterface using MatrixType = Matrix; public: - // We use default constructor and destructor + // Constructor + + hydroLevelsData(const std::string& iniFilePrefix, + std::function applyToTarget); //! \name Data manupulation //@{ @@ -51,7 +55,7 @@ class hydroLevelsData final: public dataInterface /*! ** \brief Export the data into a mere INI file */ - void saveToINIFile(const Study& study, Yuni::IO::File::Stream& file) const; + void saveToINIFile(const Study& study, Yuni::IO::File::Stream& file) const override; /*! ** \brief Assign a single value @@ -71,11 +75,15 @@ class hydroLevelsData final: public dataInterface void set_value(uint x, uint y, double value); - bool apply(Study& study); + bool apply(Study& study) override; private: //! Hydro levels overlay (0 if auto) MatrixType pHydroLevelsRules; + // prefix to be added when calling saveToINIFileHydroLevel + const std::string addToPrefix_; + + std::function applyToTarget_; }; // class hydroLevelsData @@ -105,6 +113,16 @@ inline double hydroLevelsData::get_value(uint x, uint y) const return pHydroLevelsRules.entry[y][x]; } +inline void initLevelApply(Study& study, Matrix& matrix) +{ + study.scenarioInitialHydroLevels.copyFrom(matrix); +} + +inline void finalLevelApply(Study& study, Matrix& matrix) +{ + study.scenarioFinalHydroLevels.copyFrom(matrix); +} + } // namespace ScenarioBuilder } // namespace Data } // namespace Antares diff --git a/src/libs/antares/study/include/antares/study/scenario-builder/rules.h b/src/libs/antares/study/include/antares/study/scenario-builder/rules.h index b79d92be86..ff5261d64a 100644 --- a/src/libs/antares/study/include/antares/study/scenario-builder/rules.h +++ b/src/libs/antares/study/include/antares/study/scenario-builder/rules.h @@ -119,8 +119,10 @@ class Rules final: private Yuni::NonCopyable //! Renewable (array [0..pAreaCount - 1]) std::vector renewable; - //! hydro levels - hydroLevelsData hydroLevels; + //! hydro initial levels + hydroLevelsData hydroInitialLevels = {"hl,", initLevelApply}; + //! hydro final levels + hydroLevelsData hydroFinalLevels = {"hfl,", finalLevelApply}; // Links NTC std::vector linksNTC; @@ -135,7 +137,8 @@ class Rules final: private Yuni::NonCopyable bool readWind(const AreaName::Vector& instrs, String value, bool updaterMode); bool readHydro(const AreaName::Vector& instrs, String value, bool updaterMode); bool readSolar(const AreaName::Vector& instrs, String value, bool updaterMode); - bool readHydroLevels(const AreaName::Vector& instrs, String value, bool updaterMode); + bool readInitialHydroLevels(const AreaName::Vector& instrs, String value, bool updaterMode); + bool readFinalHydroLevels(const AreaName::Vector& instrs, String value, bool updaterMode); bool readLink(const AreaName::Vector& instrs, String value, bool updaterMode); bool readBindingConstraints(const AreaName::Vector& splitKey, String value); diff --git a/src/libs/antares/study/include/antares/study/study.h b/src/libs/antares/study/include/antares/study/study.h index 709bab62fe..03e2df8bed 100644 --- a/src/libs/antares/study/include/antares/study/study.h +++ b/src/libs/antares/study/include/antares/study/study.h @@ -588,8 +588,9 @@ class Study: public Yuni::NonCopyable, public LayerData ScenarioBuilder::Sets* scenarioRules = nullptr; //@} - TimeSeries::TS scenarioHydroLevels; - + TimeSeries::TS scenarioInitialHydroLevels; + // Hydro Final Levels + TimeSeries::TS scenarioFinalHydroLevels; /*! ** \brief Runtime informations ** diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index d955da1c81..c9dc476de5 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -32,7 +32,7 @@ using namespace Yuni; namespace Antares::Data { -PartHydro::PartHydro(): +PartHydro::PartHydro(const Data::Area& area) : interDailyBreakdown(0.), intraDailyModulation(2.), intermonthlyBreakdown(0), @@ -161,6 +161,7 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) area.hydro.initializeReservoirLevelDate = 0; area.hydro.reservoirCapacity = 0.; area.hydro.pumpingEfficiency = 1.; + area.hydro.deltaBetweenFinalAndInitialLevels.resize(study.parameters.nbYears); if (study.header.version >= StudyVersion(9, 1)) { diff --git a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp new file mode 100644 index 0000000000..2229f75f97 --- /dev/null +++ b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp @@ -0,0 +1,157 @@ +/* +** Copyright 2007-2023 RTE +** Authors: Antares_Simulator Team +** +** This file is part of Antares_Simulator. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** There are special exceptions to the terms and conditions of the +** license as they are applied to this software. View the full text of +** the exceptions in file COPYING.txt in the directory of this software +** distribution +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Antares_Simulator. If not, see . +** +** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions +*/ + +#include "antares/study/parts/hydro/finalLevelValidator.h" + +namespace Antares::Data +{ + +FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, + unsigned int areaIndex, + const AreaName areaName, // gp : to std::string + double initialLevel, + double finalLevel, + const unsigned int year, + const unsigned int lastSimulationDay, + const unsigned int firstMonthOfSimulation) + : hydro_(hydro), + areaName_(areaName), + areaIndex_(areaIndex), + initialLevel_(initialLevel), + finalLevel_(finalLevel), + year_(year), + lastSimulationDay_(lastSimulationDay), + firstMonthOfSimulation_(firstMonthOfSimulation) +{ +} + +bool FinalLevelValidator::check() +{ + if (skippingFinalLevelUse()) + return true; + if (! checkForInfeasibility()) + return false; + finalLevelFineForUse_ = true; + return true; +} + +bool FinalLevelValidator::skippingFinalLevelUse() +{ + if(! wasSetInScenarioBuilder()) + return true; + if (! compatibleWithReservoirProperties()) + return true; + return false; +} + +bool FinalLevelValidator::wasSetInScenarioBuilder() +{ + return ! isnan(finalLevel_); +} + +bool FinalLevelValidator::compatibleWithReservoirProperties() +{ + if (hydro_.reservoirManagement && !hydro_.useWaterValue) + return true; + + logs.warning() << "Final reservoir level not applicable! Year:" << year_ + 1 + << ", Area:" << areaName_ + << ". Check: Reservoir management = Yes, Use water values = No and proper initial " + "reservoir level is provided "; + return false; +} + +bool FinalLevelValidator::checkForInfeasibility() +{ + bool checksOk = hydroAllocationStartMatchesSimulation(); + checksOk = isFinalLevelReachable() && checksOk; + checksOk = isBetweenRuleCurves() && checksOk; + + return checksOk; +} + +bool FinalLevelValidator::hydroAllocationStartMatchesSimulation() const +{ + int initReservoirLvlMonth = hydro_.initializeReservoirLevelDate; // month [0-11] + if (lastSimulationDay_ == DAYS_PER_YEAR && initReservoirLvlMonth == firstMonthOfSimulation_) + return true; + + logs.error() << "Year " << year_ + 1 << ", area '" << areaName_ << "' : " + << "Hydro allocation must start on the 1st simulation month and " + << "simulation last a whole year"; + return false; +} + +bool FinalLevelValidator::isFinalLevelReachable() const +{ + double reservoirCapacity = hydro_.reservoirCapacity; + double totalYearInflows = calculateTotalInflows(); + + if ((finalLevel_ - initialLevel_) * reservoirCapacity > totalYearInflows) + { + logs.error() << "Year: " << year_ + 1 << ". Area: " << areaName_ + << ". Incompatible total inflows: " << totalYearInflows + << " with initial: " << initialLevel_ + << " and final: " << finalLevel_ << " reservoir levels."; + return false; + } + return true; +} + +double FinalLevelValidator::calculateTotalInflows() const +{ + // calculate yearly inflows + auto const& srcinflows = hydro_.series->storage.getColumn(year_); + + double totalYearInflows = 0.0; + for (unsigned int day = 0; day < DAYS_PER_YEAR; ++day) + totalYearInflows += srcinflows[day]; + return totalYearInflows; +} + +bool FinalLevelValidator::isBetweenRuleCurves() const +{ + double lowLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::minimum][DAYS_PER_YEAR - 1]; + double highLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::maximum][DAYS_PER_YEAR - 1]; + + if (finalLevel_ < lowLevelLastDay || finalLevel_ > highLevelLastDay) + { + logs.error() << "Year: " << year_ + 1 << ". Area: " << areaName_ + << ". Specifed final reservoir level: " << finalLevel_ + << " is incompatible with reservoir level rule curve [" << lowLevelLastDay + << " , " << highLevelLastDay << "]"; + return false; + } + return true; +} + +bool FinalLevelValidator::finalLevelFineForUse() +{ + return finalLevelFineForUse_; +} + +} // namespace Antares::Data diff --git a/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp b/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp index 8abb019366..3295df4503 100644 --- a/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp +++ b/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp @@ -28,6 +28,13 @@ namespace Antares::Data::ScenarioBuilder { +hydroLevelsData::hydroLevelsData(const std::string& iniFilePrefix, + std::function applyToTarget) : + addToPrefix_(iniFilePrefix), + applyToTarget_(applyToTarget) +{ +} + bool hydroLevelsData::reset(const Study& study) { const uint nbYears = study.parameters.nbYears; @@ -40,10 +47,6 @@ bool hydroLevelsData::reset(const Study& study) void hydroLevelsData::saveToINIFile(const Study& study, Yuni::IO::File::Stream& file) const { - // Prefix - CString<512, false> prefix; - prefix += "hl,"; - // Turning values into strings (precision 4) std::ostringstream value_into_string; value_into_string << std::setprecision(4); @@ -65,7 +68,7 @@ void hydroLevelsData::saveToINIFile(const Study& study, Yuni::IO::File::Stream& } assert(index < study.areas.size()); value_into_string << value; - file << prefix << study.areas.byIndex[index]->id << ',' << y << " = " + file << addToPrefix_ << study.areas.byIndex[index]->id << ',' << y << " = " << value_into_string.str() << '\n'; value_into_string.str(std::string()); // Clearing converter } @@ -79,7 +82,7 @@ void hydroLevelsData::set_value(uint x, uint y, double value) bool hydroLevelsData::apply(Study& study) { - study.scenarioHydroLevels.copyFrom(pHydroLevelsRules); + applyToTarget_(study, pHydroLevelsRules); return true; } diff --git a/src/libs/antares/study/scenario-builder/rules.cpp b/src/libs/antares/study/scenario-builder/rules.cpp index fb39a275fd..fd79f07f7c 100644 --- a/src/libs/antares/study/scenario-builder/rules.cpp +++ b/src/libs/antares/study/scenario-builder/rules.cpp @@ -59,7 +59,8 @@ void Rules::saveToINIFile(Yuni::IO::File::Stream& file) const linksNTC[i].saveToINIFile(study_, file); } // hydro levels - hydroLevels.saveToINIFile(study_, file); + hydroInitialLevels.saveToINIFile(study_, file); + hydroFinalLevels.saveToINIFile(study_, file); } binding_constraints.saveToINIFile(study_, file); file << '\n'; @@ -95,7 +96,8 @@ bool Rules::reset() renewable[i].reset(study_); } - hydroLevels.reset(study_); + hydroInitialLevels.reset(study_); + hydroFinalLevels.reset(study_); // links NTC linksNTC.clear(); @@ -263,7 +265,7 @@ bool Rules::readSolar(const AreaName::Vector& splitKey, String value, bool updat return true; } -bool Rules::readHydroLevels(const AreaName::Vector& splitKey, String value, bool updaterMode) +bool Rules::readInitialHydroLevels(const AreaName::Vector& splitKey, String value, bool updaterMode) { const uint year = splitKey[2].to(); const AreaName& areaname = splitKey[1]; @@ -275,7 +277,21 @@ bool Rules::readHydroLevels(const AreaName::Vector& splitKey, String value, bool } double val = fromStringToHydroLevel(value, 1.); - hydroLevels.setTSnumber(area->index, year, val); + hydroInitialLevels.setTSnumber(area->index, year, val); + return true; +} + +bool Rules::readFinalHydroLevels(const AreaName::Vector& splitKey, String value, bool updaterMode) +{ + const uint year = splitKey[2].to(); + const AreaName& areaname = splitKey[1]; + + const Data::Area* area = getArea(areaname, updaterMode); + if (!area) + return false; + + double finalLevel = fromStringToHydroLevel(value, 1.); + hydroFinalLevels.setTSnumber(area->index, year, finalLevel); return true; } @@ -389,7 +405,11 @@ bool Rules::readLine(const AreaName::Vector& splitKey, String value, bool update } else if (kind_of_scenario == "hl") { - return readHydroLevels(splitKey, value, updaterMode); + return readInitialHydroLevels(splitKey, value, updaterMode); + } + else if (kind_of_scenario == "hfl") + { + return readFinalHydroLevels(splitKey, value, updaterMode); } else if (kind_of_scenario == "ntc") { @@ -402,63 +422,64 @@ bool Rules::readLine(const AreaName::Vector& splitKey, String value, bool update return false; } - bool Rules::apply() +bool Rules::apply() +{ + bool returned_status = true; + if (pAreaCount) { - bool returned_status = true; - if (pAreaCount) + returned_status = load.apply(study_) && returned_status; + returned_status = solar.apply(study_) && returned_status; + returned_status = hydro.apply(study_) && returned_status; + returned_status = wind.apply(study_) && returned_status; + for (uint i = 0; i != pAreaCount; ++i) { - returned_status = load.apply(study_) && returned_status; - returned_status = solar.apply(study_) && returned_status; - returned_status = hydro.apply(study_) && returned_status; - returned_status = wind.apply(study_) && returned_status; - for (uint i = 0; i != pAreaCount; ++i) - { - returned_status = thermal[i].apply(study_) && returned_status; - returned_status = renewable[i].apply(study_) && returned_status; - returned_status = linksNTC[i].apply(study_) && returned_status; - } - returned_status = hydroLevels.apply(study_) && returned_status; - returned_status = binding_constraints.apply(study_) && returned_status; + returned_status = thermal[i].apply(study_) && returned_status; + returned_status = renewable[i].apply(study_) && returned_status; + returned_status = linksNTC[i].apply(study_) && returned_status; } - else + returned_status = hydroInitialLevels.apply(study_) && returned_status; + returned_status = hydroFinalLevels.apply(study_) && returned_status; + returned_status = binding_constraints.apply(study_) && returned_status; + } + else + { + returned_status = false; + } + return returned_status; +} + +void Rules::sendWarningsForDisabledClusters() +{ + for (auto it = disabledClustersOnRuleActive.begin(); + it != disabledClustersOnRuleActive.end(); + it++) + { + std::vector& scenariiForCurrentCluster = it->second; + int nbScenariiForCluster = (int)scenariiForCurrentCluster.size(); + std::vector::iterator itv = scenariiForCurrentCluster.begin(); + + // Listing the 10 first years for which the current cluster was given a specific TS + // number in the scenario builder. Note that this list of years size could be less then + // 10, but are at least 1. + std::string listYears = std::to_string(*itv); + itv++; + for (int year_count = 1; itv != scenariiForCurrentCluster.end() && year_count < 10; + itv++, year_count++) { - returned_status = false; + listYears += ", " + std::to_string(*itv); } - return returned_status; - } - void Rules::sendWarningsForDisabledClusters() - { - for (auto it = disabledClustersOnRuleActive.begin(); - it != disabledClustersOnRuleActive.end(); - it++) + // Adding last scenario to the list + if (nbScenariiForCluster > 10) { - std::vector& scenariiForCurrentCluster = it->second; - int nbScenariiForCluster = (int)scenariiForCurrentCluster.size(); - std::vector::iterator itv = scenariiForCurrentCluster.begin(); - - // Listing the 10 first years for which the current cluster was given a specific TS - // number in the scenario builder. Note that this list of years size could be less then - // 10, but are at least 1. - std::string listYears = std::to_string(*itv); - itv++; - for (int year_count = 1; itv != scenariiForCurrentCluster.end() && year_count < 10; - itv++, year_count++) - { - listYears += ", " + std::to_string(*itv); - } - - // Adding last scenario to the list - if (nbScenariiForCluster > 10) - { - listYears += ", ..., " + std::to_string(scenariiForCurrentCluster.back()); - } - - logs.warning() << "Cluster " << it->first - << " not found: it may be disabled, though given TS numbers in sc " - "builder for year(s) :"; - logs.warning() << listYears; + listYears += ", ..., " + std::to_string(scenariiForCurrentCluster.back()); } + + logs.warning() << "Cluster " << it->first + << " not found: it may be disabled, though given TS numbers in sc " + "builder for year(s) :"; + logs.warning() << listYears; } +} } // namespace Antares::Data::ScenarioBuilder diff --git a/src/solver/hydro/include/antares/solver/hydro/management/management.h b/src/solver/hydro/include/antares/solver/hydro/management/management.h index 3050515ca5..b642e441c2 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -122,6 +122,8 @@ class HydroManagement final private: //! Prepare inflows scaling for each area void prepareInflowsScaling(uint year); + //! prepare data for Final reservoir level + void changeInflowsToAccommodateFinalLevels(uint yearIndex); //! Prepare minimum generation scaling for each area void minGenerationScaling(uint year); //! check Monthly minimum generation is lower than available inflows diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index 5c6bcab897..f7e4665159 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -362,6 +362,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( if (debugData) { + dayYear = 0; for (uint month = 0; month != 12; ++month) { auto daysPerMonth = calendar_.months[month].days; @@ -371,6 +372,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( auto dYear = day + dayYear; debugData->DailyTargetGen[dYear] = dailyTargetGen[dYear]; } + dayYear += daysPerMonth; } } diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 6cea703442..703235fc61 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -383,8 +383,25 @@ bool HydroManagement::checkMinGeneration(uint year) const return ret; } -void HydroManagement::prepareNetDemand(uint year, - Data::SimulationMode mode, +void HydroManagement::changeInflowsToAccommodateFinalLevels(uint year) +{ + areas_.each([this, &year](Data::Area& area) + { + auto& data = tmpDataByArea_[&area]; + + if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) + return; + + // Must be done before prepareMonthlyTargetGenerations + double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); + if (delta < 0) + data.inflows[0] -= delta; + else if (delta > 0) + data.inflows[11] -= delta; + }); +} + +void HydroManagement::prepareNetDemand(uint year, Data::SimulationMode mode, const Antares::Data::Area::ScratchMap& scratchmap) { areas_.each( @@ -527,6 +544,7 @@ void HydroManagement::makeVentilation(double* randomReservoirLevel, throw FatalError("hydro management: invalid minimum generation"); } + changeInflowsToAccommodateFinalLevels(y); prepareNetDemand(y, parameters_.mode, scratchmap); prepareEffectiveDemand(); diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index 62ce897eb8..aa10b7c10e 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -166,8 +166,6 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ lvi = random_reservoir_level[indexArea]; } - indexArea++; - double solutionCost = 0.; double solutionCostNoised = 0.; @@ -292,20 +290,22 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ auto monthName = calendar_.text.months[simulationMonth].name; - buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; - buffer << '\t'; - buffer << data.inflows[realmonth] << '\t'; - buffer << data.MTG[realmonth] << '\t'; - buffer << data.MOG[realmonth] / area.hydro.reservoirCapacity << '\t'; - buffer << data.MOL[realmonth] << '\t'; - buffer << minLvl[firstDay] << '\t'; - buffer << maxLvl[firstDay] << '\t'; - buffer << '\n'; - } - auto content = buffer.str(); - resultWriter_.addEntryFromBuffer(path.str(), content); - } - }); + buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; + buffer << '\t'; + buffer << data.inflows[realmonth] << '\t'; + buffer << data.MTG[realmonth] << '\t'; + buffer << data.MOG[realmonth] / area.hydro.reservoirCapacity << '\t'; + buffer << data.MOL[realmonth] << '\t'; + buffer << minLvl[firstDay] << '\t'; + buffer << maxLvl[firstDay] << '\t'; + buffer << '\n'; + } + auto content = buffer.str(); + resultWriter_.addEntryFromBuffer(path.str(), content); + } + + indexArea++; + }); } } // namespace Antares diff --git a/src/solver/simulation/CMakeLists.txt b/src/solver/simulation/CMakeLists.txt index 3c59c59d55..0d2bc666eb 100644 --- a/src/solver/simulation/CMakeLists.txt +++ b/src/solver/simulation/CMakeLists.txt @@ -22,35 +22,36 @@ set(SRC_SIMULATION apply-scenario.cpp - # Solver - include/antares/solver/simulation/solver_utils.h - solver_utils.cpp - include/antares/solver/simulation/solver.h - include/antares/solver/simulation/solver.hxx - include/antares/solver/simulation/solver.data.h - solver.data.cpp - include/antares/solver/simulation/common-eco-adq.h - common-eco-adq.cpp - common-hydro-remix.cpp - common-hydro-levels.cpp - include/antares/solver/simulation/adequacy.h - adequacy.cpp - include/antares/solver/simulation/economy.h - economy.cpp - include/antares/solver/simulation/base_post_process.h - base_post_process.cpp - include/antares/solver/simulation/opt_time_writer.h - opt_time_writer.cpp - include/antares/solver/simulation/adequacy_patch_runtime_data.h - adequacy_patch_runtime_data.cpp - include/antares/solver/simulation/ITimeSeriesNumbersWriter.h - TimeSeriesNumbersWriter.cpp - include/antares/solver/simulation/BindingConstraintsTimeSeriesNumbersWriter.h - - economy_mode.cpp - adequacy_mode.cpp - include/antares/solver/simulation/economy_mode.h - include/antares/solver/simulation/adequacy_mode.h + # Solver + include/antares/solver/simulation/solver_utils.h + solver_utils.cpp + include/antares/solver/simulation/solver.h + include/antares/solver/simulation/solver.hxx + include/antares/solver/simulation/solver.data.h + solver.data.cpp + include/antares/solver/simulation/common-eco-adq.h + common-eco-adq.cpp + common-hydro-remix.cpp + common-hydro-levels.cpp + include/antares/solver/simulation/adequacy.h + adequacy.cpp + include/antares/solver/simulation/economy.h + economy.cpp + include/antares/solver/simulation/base_post_process.h + base_post_process.cpp + include/antares/solver/simulation/opt_time_writer.h + opt_time_writer.cpp + include/antares/solver/simulation/adequacy_patch_runtime_data.h + adequacy_patch_runtime_data.cpp + include/antares/solver/simulation/ITimeSeriesNumbersWriter.h + include/antares/solver/simulation/hydro-final-reservoir-level-functions.h + hydro-final-reservoir-level-functions.cpp + TimeSeriesNumbersWriter.cpp + include/antares/solver/simulation/BindingConstraintsTimeSeriesNumbersWriter.h + economy_mode.cpp + adequacy_mode.cpp + include/antares/solver/simulation/economy_mode.h + include/antares/solver/simulation/adequacy_mode.h ) source_group("simulation" FILES ${SRC_SIMULATION}) diff --git a/src/solver/simulation/hydro-final-reservoir-level-functions.cpp b/src/solver/simulation/hydro-final-reservoir-level-functions.cpp new file mode 100644 index 0000000000..32f2d4dfa2 --- /dev/null +++ b/src/solver/simulation/hydro-final-reservoir-level-functions.cpp @@ -0,0 +1,68 @@ +/* +** Copyright 2007-2023 RTE +** Authors: RTE-international / Redstork / Antares_Simulator Team +** +** This file is part of Antares_Simulator. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** There are special exceptions to the terms and conditions of the +** license as they are applied to this software. View the full text of +** the exceptions in file COPYING.txt in the directory of this software +** distribution +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Antares_Simulator. If not, see . +** +** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions +*/ + +#include "antares/solver/simulation/hydro-final-reservoir-level-functions.h" +#include "antares/study/parts/hydro/finalLevelValidator.h" +#include + +namespace Antares::Solver +{ + +void CheckFinalReservoirLevelsConfiguration(const Data::Study& study) +{ + study.areas.each([&study](Data::Area &area) + { + uint nbYears = study.parameters.nbYears; + for (uint year = 0; year != nbYears; ++year) + { + if (! study.parameters.yearsFilter.at(year)) + continue; + + double initialLevel = study.scenarioInitialHydroLevels.entry[area.index][year]; + double finalLevel = study.scenarioFinalHydroLevels.entry[area.index][year]; + + Data::FinalLevelValidator validator(area.hydro, + area.index, + area.name, + initialLevel, + finalLevel, + year, + study.parameters.simulationDays.end, + study.parameters.firstMonthInYear); + if (! validator.check()) + { + throw FatalError("hydro final level : infeasibility"); + } + if (validator.finalLevelFineForUse()) + { + area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; + } + } + }); +} // End function CheckFinalReservoirLevelsConfiguration + +} // namespace Antares::Solver \ No newline at end of file diff --git a/src/solver/simulation/include/antares/solver/simulation/hydro-final-reservoir-level-functions.h b/src/solver/simulation/include/antares/solver/simulation/hydro-final-reservoir-level-functions.h new file mode 100644 index 0000000000..4b60c4cc8f --- /dev/null +++ b/src/solver/simulation/include/antares/solver/simulation/hydro-final-reservoir-level-functions.h @@ -0,0 +1,37 @@ +/* +** Copyright 2007-2023 RTE +** Authors: RTE-international / Redstork / Antares_Simulator Team +** +** This file is part of Antares_Simulator. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** There are special exceptions to the terms and conditions of the +** license as they are applied to this software. View the full text of +** the exceptions in file COPYING.txt in the directory of this software +** distribution +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Antares_Simulator. If not, see . +** +** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions +*/ +#ifndef __SOLVER_SIMULATION_HYDRO_FINAL_RESERVOIR_PRE_CHECKS_H__ +#define __SOLVER_SIMULATION_HYDRO_FINAL_RESERVOIR_PRE_CHECKS_H__ + +#include "antares/study/study.h" + +namespace Antares::Solver +{ +void CheckFinalReservoirLevelsConfiguration(const Data::Study& study); +} // namespace Antares::Solver + +#endif // __SOLVER_SIMULATION_HYDRO_FINAL_RESERVOIR_PRE_CHECKS_H__ diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 5e36fcaca8..232fa520fc 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -39,6 +39,9 @@ #include "antares/solver/simulation/timeseries-numbers.h" #include "antares/solver/ts-generator/generator.h" + +#include "hydro-final-reservoir-level-functions.h" + namespace Antares::Solver::Simulation { @@ -349,6 +352,7 @@ void ISimulation::run() if (study.parameters.useCustomScenario) { ApplyCustomScenario(study); + CheckFinalReservoirLevelsConfiguration(study); } // Launching the simulation for all years @@ -744,15 +748,15 @@ void ISimulation::computeRandomNumbers( max[firstDayOfMonth], randomHydroGenerator); - // Possibly update the intial level from scenario builder - if (study.parameters.useCustomScenario) - { - double levelFromScenarioBuilder = study.scenarioHydroLevels[areaIndex][y]; - if (levelFromScenarioBuilder >= 0.) - { - randomLevel = levelFromScenarioBuilder; - } - } + // Possibly update the intial level from scenario builder + if (study.parameters.useCustomScenario) + { + double levelFromScenarioBuilder = study.scenarioInitialHydroLevels[areaIndex][y]; + if (levelFromScenarioBuilder >= 0.) + { + randomLevel = levelFromScenarioBuilder; + } + } // Current area's hydro starting (or initial) level computation // (no matter if the year is performed or not, we always draw a random initial diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index e5813befd8..bfad50326f 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -78,11 +78,12 @@ struct HydroMaxPowerStudy: public StudyBuilder HydroMaxPowerStudy::HydroMaxPowerStudy() { simulationBetweenDays(0, 14); - setNumberMCyears(1); area = addAreaToStudy("Area"); area->thermal.unsuppliedEnergyCost = 1; + setNumberMCyears(1); + TimeSeriesConfigurer loadTSconfig(area->load.series.timeSeries); loadTSconfig.setColumnCount(1).fillColumnWith(0, loadInArea); diff --git a/src/tests/end-to-end/utils/utils.cpp b/src/tests/end-to-end/utils/utils.cpp index 769683412d..a42891ea45 100644 --- a/src/tests/end-to-end/utils/utils.cpp +++ b/src/tests/end-to-end/utils/utils.cpp @@ -219,6 +219,7 @@ void StudyBuilder::setNumberMCyears(unsigned int nbYears) { study->parameters.resetPlaylist(nbYears); study->areas.resizeAllTimeseriesNumbers(nbYears); + study->areas.each([&](Data::Area& area) { area.hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); }); } void StudyBuilder::playOnlyYear(unsigned int year) diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp index 36346b2014..7879559fb0 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp @@ -346,7 +346,7 @@ BOOST_FIXTURE_TEST_CASE( } // ======================== -// Tests on Hydro levels +// Tests on Hydro initial levels // ======================== BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_17__hydro_level_0_123_is_chosen__reading_OK, Fixture) { @@ -355,12 +355,10 @@ BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_17__hydro_level_0_123_is_chosen__re AreaName::Vector splitKey = {"hl", "area 1", yearNumber}; my_rule.readLine(splitKey, level); - BOOST_CHECK_EQUAL(my_rule.hydroLevels.get_value(yearNumber.to(), area_1->index), - level.to()); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_1->index), level.to()); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioHydroLevels[area_1->index][yearNumber.to()], - level.to()); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_1->index][yearNumber.to()], level.to()); } BOOST_FIXTURE_TEST_CASE( @@ -372,10 +370,10 @@ BOOST_FIXTURE_TEST_CASE( AreaName::Vector splitKey = {"hl", "area 2", yearNumber}; BOOST_CHECK(my_rule.readLine(splitKey, level)); - BOOST_CHECK_EQUAL(my_rule.hydroLevels.get_value(yearNumber.to(), area_2->index), 1.); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_2->index), 1.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioHydroLevels[area_2->index][yearNumber.to()], 1.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_2->index][yearNumber.to()], 1.); } BOOST_FIXTURE_TEST_CASE( @@ -387,10 +385,58 @@ BOOST_FIXTURE_TEST_CASE( AreaName::Vector splitKey = {"hl", "area 3", yearNumber}; BOOST_CHECK(my_rule.readLine(splitKey, level)); - BOOST_CHECK_EQUAL(my_rule.hydroLevels.get_value(yearNumber.to(), area_3->index), 0.); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_3->index), 0.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioHydroLevels[area_3->index][yearNumber.to()], 0.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_3->index][yearNumber.to()], 0.); +} + +// ======================== +// Tests on Hydro final levels +// ======================== +BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_8__hydro_level_0_342_is_chosen__reading_OK, Fixture) +{ + AreaName yearNumber = "8"; + String level = "0.342"; + AreaName::Vector splitKey = {"hfl", "area 1", yearNumber}; + my_rule.readLine(splitKey, level, false); + + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_1->index), + level.to()); + + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_1->index][yearNumber.to()], + level.to()); +} + +BOOST_FIXTURE_TEST_CASE(on_area2_and_on_year_1__hydro_level_2_4_is_chosen_level_lowered_to_1__reading_OK, Fixture) +{ + AreaName yearNumber = "1"; + String level = "2.4"; + AreaName::Vector splitKey = {"hfl", "area 2", yearNumber}; + BOOST_CHECK(my_rule.readLine(splitKey, level, false)); + + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_2->index), + 1.); + + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_2->index][yearNumber.to()], + 1.); +} + +BOOST_FIXTURE_TEST_CASE(on_area3_and_on_year_3__hydro_level_neg_5_2_is_chosen__level_raised_to_0__reading_OK, Fixture) +{ + AreaName yearNumber = "3"; + String level = "-5.2"; + AreaName::Vector splitKey = {"hfl", "area 3", yearNumber}; + BOOST_CHECK(my_rule.readLine(splitKey, level, false)); + + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_3->index), + 0.); + + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_3->index][yearNumber.to()], + 0.); } // ====================== diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp index e1b0666b7d..13d5a38b48 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp @@ -411,15 +411,15 @@ BOOST_FIXTURE_TEST_CASE( } // ======================== -// Tests on Hydro levels +// Tests on Hydro initial levels // ======================== BOOST_FIXTURE_TEST_CASE( HYDRO_LEVEL__TS_number_for_many_areas_and_years__generated_and_ref_sc_buider_files_are_identical, saveFixture) { - my_rule->hydroLevels.setTSnumber(area_1->index, 9, 9); - my_rule->hydroLevels.setTSnumber(area_3->index, 18, 7); - my_rule->hydroLevels.setTSnumber(area_1->index, 5, 8); + my_rule->hydroInitialLevels.setTSnumber(area_1->index, 9, 9); + my_rule->hydroInitialLevels.setTSnumber(area_3->index, 18, 7); + my_rule->hydroInitialLevels.setTSnumber(area_1->index, 5, 8); saveScenarioBuilder(); @@ -433,6 +433,27 @@ BOOST_FIXTURE_TEST_CASE( BOOST_CHECK(files_identical(path_to_generated_file, referenceFile.path())); } +// ======================== +// Tests on Hydro final levels +// ======================== +BOOST_FIXTURE_TEST_CASE(HYDRO_FINAL_LEVEL__TS_number_for_many_areas_and_years__generated_and_ref_sc_buider_files_are_identical, saveFixture) +{ + my_rule->hydroFinalLevels.setTSnumber(area_1->index, 4, 8); + my_rule->hydroFinalLevels.setTSnumber(area_2->index, 11, 3); + my_rule->hydroFinalLevels.setTSnumber(area_3->index, 15, 2); + + saveScenarioBuilder(); + + // Build reference scenario builder file + referenceFile.append("[my rule name]"); + referenceFile.append("hfl,area 1,4 = 8"); + referenceFile.append("hfl,area 2,11 = 3"); + referenceFile.append("hfl,area 3,15 = 2"); + referenceFile.write(); + + BOOST_CHECK(files_identical(path_to_generated_file, referenceFile.path())); +} + // ====================== // Tests on Links NTC // ====================== @@ -496,7 +517,7 @@ BOOST_FIXTURE_TEST_CASE( my_rule->renewable[area_3->index].setTSnumber(rnCluster_32.get(), 5, 13); my_rule->linksNTC[area_1->index].setDataForLink(link_13, 19, 8); my_rule->linksNTC[area_2->index].setDataForLink(link_23, 2, 4); - my_rule->hydroLevels.setTSnumber(area_1->index, 5, 8); + my_rule->hydroInitialLevels.setTSnumber(area_1->index, 5, 8); my_rule->binding_constraints.setTSnumber("group3", 10, 6); saveScenarioBuilder(); diff --git a/src/tests/src/solver/simulation/CMakeLists.txt b/src/tests/src/solver/simulation/CMakeLists.txt index e056ac388d..3ba8f09755 100644 --- a/src/tests/src/solver/simulation/CMakeLists.txt +++ b/src/tests/src/solver/simulation/CMakeLists.txt @@ -89,3 +89,32 @@ add_test(NAME time_series COMMAND test-time_series) set_property(TEST time_series PROPERTY LABELS unit) +# =================================== +# Tests on hydro final reservoir level functions +# =================================== + +add_executable(test-hydro_final test-hydro-final-reservoir-level-functions.cpp) + +target_include_directories(test-hydro_final + PRIVATE + "${src_solver_simulation}" + "${src_libs_antares_study}" +) +target_link_libraries(test-hydro_final + PRIVATE + Boost::unit_test_framework + Antares::study + antares-solver-simulation + Antares::array +) + +# Linux +if(UNIX AND NOT APPLE) + target_link_libraries(test-hydro_final PRIVATE stdc++fs) +endif() + +set_target_properties(test-hydro_final PROPERTIES FOLDER Unit-tests) + +add_test(NAME hydro_final COMMAND test-hydro_final) + +set_property(TEST hydro_final PROPERTY LABELS unit) \ No newline at end of file diff --git a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp new file mode 100644 index 0000000000..d4a6c3512b --- /dev/null +++ b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp @@ -0,0 +1,275 @@ +// +// Created by Nikola Ilic on 23/06/23. +// + +#define BOOST_TEST_MODULE hydro - final - level +#define WIN32_LEAN_AND_MEAN +#include + +#include "include/antares/solver/simulation/hydro-final-reservoir-level-functions.h" +#include "include/antares/study/parts/hydro/finalLevelValidator.h" +#include + +using namespace Antares::Solver; +using namespace Antares::Data; + + +struct Fixture +{ + Fixture(const Fixture& f) = delete; + Fixture(const Fixture&& f) = delete; + Fixture& operator=(const Fixture& f) = delete; + Fixture& operator=(const Fixture&& f) = delete; + Fixture() + { + // Simulation last day must be 365 so that final level checks succeeds + study->parameters.simulationDays.end = 365; + study->parameters.firstMonthInYear = january; + uint nbYears = study->parameters.nbYears = 2; + + area_1 = study->areaAdd("Area1"); + area_2 = study->areaAdd("Area2"); + + area_1->hydro.reservoirManagement = true; + area_2->hydro.reservoirManagement = true; + + area_1->hydro.useWaterValue = false; + area_2->hydro.useWaterValue = false; + + // Level date must be 0, see hydroAllocationStartMatchesSimulation function + area_1->hydro.initializeReservoirLevelDate = 0; + area_2->hydro.initializeReservoirLevelDate = 0; + + area_1->hydro.reservoirCapacity = 340.; + area_2->hydro.reservoirCapacity = 300.; + + // Set reservoir max and min daily levels, but just for the last day in year + area_1->hydro.reservoirLevel.resize(3, DAYS_PER_YEAR); + area_1->hydro.reservoirLevel[PartHydro::minimum][DAYS_PER_YEAR - 1] = 2.4; + area_1->hydro.reservoirLevel[PartHydro::maximum][DAYS_PER_YEAR - 1] = 6.5; + + area_2->hydro.reservoirLevel.resize(3, DAYS_PER_YEAR); + area_2->hydro.reservoirLevel[PartHydro::minimum][DAYS_PER_YEAR - 1] = 2.7; + area_2->hydro.reservoirLevel[PartHydro::maximum][DAYS_PER_YEAR - 1] = 6.4; + + // Resize vector final levels delta with initial levels + area_1->hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); + area_2->hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); + + + // Scenario builder for initial and final reservoir levels + // ------------------------------------------------------- + uint areasCount = study->areas.size(); + + study->parameters.yearsFilter.assign(2, true); + + study->scenarioInitialHydroLevels.resize(nbYears, areasCount); + study->scenarioFinalHydroLevels.resize(nbYears, areasCount); + + study->scenarioInitialHydroLevels[0][0] = 2.3; + study->scenarioInitialHydroLevels[0][1] = 4.2; + study->scenarioInitialHydroLevels[1][0] = 1.5; + study->scenarioInitialHydroLevels[1][1] = 2.4; + + study->scenarioFinalHydroLevels[0][0] = 3.4; + study->scenarioFinalHydroLevels[0][1] = 5.1; + study->scenarioFinalHydroLevels[1][0] = 3.5; + study->scenarioFinalHydroLevels[1][1] = 4.3; + + // Inflows time series matrices + // ----------------------------- + uint nbInflowTS = 2; + // ... Area 1 : Inflows time series numbers for each year + area_1->hydro.series->timeseriesNumbers.reset(nbYears); + area_1->hydro.series->timeseriesNumbers[0] = 0; + area_1->hydro.series->timeseriesNumbers[1] = 1; + // ... Area 1 : Inflows time series + area_1->hydro.series->storage.resize(nbInflowTS, 365); + area_1->hydro.series->storage.timeSeries.fill(200.); + area_1->hydro.series->storage[0][0] = 200. + 1.; + area_1->hydro.series->storage[0][DAYS_PER_YEAR - 1] = 200. + 2.; + + // ... Area 2 : time series numbers for each year + area_2->hydro.series->timeseriesNumbers.reset(nbYears); + area_2->hydro.series->timeseriesNumbers[0] = 0; + area_2->hydro.series->timeseriesNumbers[1] = 1; + // ... Area 2 : Inflows time series + area_2->hydro.series->storage.resize(nbInflowTS, 365); + area_2->hydro.series->storage.timeSeries.fill(300.); + area_2->hydro.series->storage[0][0] = 300. + 1.; //DAYS_PER_YEAR + area_2->hydro.series->storage[0][DAYS_PER_YEAR - 1] = 300. + 2.; + } + + ~Fixture() = default; + + Study::Ptr study = std::make_shared(); + Area* area_1; + Area* area_2; +}; + +BOOST_FIXTURE_TEST_SUITE(final_level_validator, Fixture) + +BOOST_AUTO_TEST_CASE(all_parameters_good___check_succeeds_and_final_level_is_usable) +{ + uint year = 0; + FinalLevelValidator validator(area_1->hydro, + area_1->index, + area_1->name, + study->scenarioInitialHydroLevels[area_1->index][year], + study->scenarioFinalHydroLevels[area_1->index][year], + year, + study->parameters.simulationDays.end, + study->parameters.firstMonthInYear); + + BOOST_CHECK_EQUAL(validator.check(), true); + BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), true); +} + +BOOST_AUTO_TEST_CASE(no_reservoir_management___check_succeeds_but_final_level_not_usable) +{ + uint year = 0; + area_1->hydro.reservoirManagement = false; + FinalLevelValidator validator(area_1->hydro, + area_1->index, + area_1->name, + study->scenarioInitialHydroLevels[area_1->index][year], + study->scenarioFinalHydroLevels[area_1->index][year], + year, + study->parameters.simulationDays.end, + study->parameters.firstMonthInYear); + + BOOST_CHECK_EQUAL(validator.check(), true); + BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); +} + +BOOST_AUTO_TEST_CASE(use_water_value_is_true___check_succeeds_but_final_level_not_usable) +{ + area_1->hydro.useWaterValue = true; + uint year = 0; + + FinalLevelValidator validator(area_1->hydro, + area_1->index, + area_1->name, + study->scenarioInitialHydroLevels[area_1->index][year], + study->scenarioFinalHydroLevels[area_1->index][year], + year, + study->parameters.simulationDays.end, + study->parameters.firstMonthInYear); + + BOOST_CHECK_EQUAL(validator.check(), true); + BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); +} + +BOOST_AUTO_TEST_CASE(final_level_not_set_by_user____check_succeeds_but_final_level_not_usable) +{ + uint year = 0; + study->scenarioFinalHydroLevels[area_1->index][year] = std::numeric_limits::quiet_NaN(); + + FinalLevelValidator validator(area_1->hydro, + area_1->index, + area_1->name, + study->scenarioInitialHydroLevels[area_1->index][year], + study->scenarioFinalHydroLevels[area_1->index][year], + year, + study->parameters.simulationDays.end, + study->parameters.firstMonthInYear); + + BOOST_CHECK_EQUAL(validator.check(), true); + BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); +} + +BOOST_AUTO_TEST_CASE(initial_level_month_and_simulation_first_month_different___check_fails_and_final_level_not_usable) +{ + uint year = 0; + area_1->hydro.initializeReservoirLevelDate = 3; // initialize reservoir level != January + + FinalLevelValidator validator(area_1->hydro, + area_1->index, + area_1->name, + study->scenarioInitialHydroLevels[area_1->index][year], + study->scenarioFinalHydroLevels[area_1->index][year], + year, + study->parameters.simulationDays.end, + study->parameters.firstMonthInYear); + + BOOST_CHECK_EQUAL(validator.check(), false); + BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); +} + +BOOST_AUTO_TEST_CASE(simulation_does_last_a_whole_year___check_fails_and_final_level_not_usable) +{ + uint year = 0; + study->parameters.simulationDays.end = 300; + + FinalLevelValidator validator(area_1->hydro, + area_1->index, + area_1->name, + study->scenarioInitialHydroLevels[area_1->index][year], + study->scenarioFinalHydroLevels[area_1->index][year], + year, + study->parameters.simulationDays.end, + study->parameters.firstMonthInYear); + + BOOST_CHECK_EQUAL(validator.check(), false); + BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); +} + +BOOST_AUTO_TEST_CASE(final_level_out_of_rule_curves___check_fails_and_final_level_not_usable) +{ + uint year = 0; + // Rule Curves on last simulation day = [2.4 - 6.5] + study->scenarioFinalHydroLevels[area_1->index][year] = 6.6; + + FinalLevelValidator validator(area_1->hydro, + area_1->index, + area_1->name, + study->scenarioInitialHydroLevels[area_1->index][year], + study->scenarioFinalHydroLevels[area_1->index][year], + year, + study->parameters.simulationDays.end, + study->parameters.firstMonthInYear); + + BOOST_CHECK_EQUAL(validator.check(), false); + BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); +} + +BOOST_AUTO_TEST_CASE(final_level_unreachable_because_of_too_few_inflows___check_fails_and_final_level_not_usable) +{ + area_1->hydro.reservoirCapacity = 185000; + uint year = 0; + study->scenarioInitialHydroLevels[area_1->index][year] = 10; + study->scenarioFinalHydroLevels[area_1->index][year] = 50; + + // Inflows = 200 MWh/day = 73 000 MWh/year + // (50 - 10) x Reservoir capacity == 74 000 > 73 000. + FinalLevelValidator validator(area_1->hydro, + area_1->index, + area_1->name, + study->scenarioInitialHydroLevels[area_1->index][year], + study->scenarioFinalHydroLevels[area_1->index][year], + year, + study->parameters.simulationDays.end, + study->parameters.firstMonthInYear); + + BOOST_CHECK_EQUAL(validator.check(), false); + BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); +} + +BOOST_AUTO_TEST_CASE(check_all_areas_final_levels_when_config_is_ok___all_checks_succeed) +{ + CheckFinalReservoirLevelsConfiguration(*study); + + // Checks on Area 1 modifier + BOOST_CHECK_EQUAL(area_1->hydro.deltaBetweenFinalAndInitialLevels[0].has_value(), true); + BOOST_CHECK_EQUAL(area_1->hydro.deltaBetweenFinalAndInitialLevels[1].has_value(), true); + BOOST_CHECK_EQUAL(area_1->hydro.deltaBetweenFinalAndInitialLevels[0].value(), 3.4 - 2.3); + BOOST_CHECK_EQUAL(area_1->hydro.deltaBetweenFinalAndInitialLevels[1].value(), 5.1 - 4.2); + + // Checks on Area 2 modifier + BOOST_CHECK_EQUAL(area_2->hydro.deltaBetweenFinalAndInitialLevels[0].has_value(), true); + BOOST_CHECK_EQUAL(area_2->hydro.deltaBetweenFinalAndInitialLevels[1].has_value(), true); + BOOST_CHECK_EQUAL(area_2->hydro.deltaBetweenFinalAndInitialLevels[0].value(), 3.5 - 1.5); + BOOST_CHECK_EQUAL(area_2->hydro.deltaBetweenFinalAndInitialLevels[1].value(), 4.3 - 2.4); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/ui/simulator/application/main/build/scenario-builder.cpp b/src/ui/simulator/application/main/build/scenario-builder.cpp index 5d46aaf6c0..350c1633f7 100644 --- a/src/ui/simulator/application/main/build/scenario-builder.cpp +++ b/src/ui/simulator/application/main/build/scenario-builder.cpp @@ -35,6 +35,7 @@ #include "toolbox/components/datagrid/renderer/scenario-builder-wind-renderer.h" #include "toolbox/components/datagrid/renderer/scenario-builder-solar-renderer.h" #include "toolbox/components/datagrid/renderer/scenario-builder-hydro-levels-renderer.h" +#include "toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.h" #include "toolbox/components/datagrid/renderer/scenario-builder-ntc-renderer.h" using namespace Yuni; @@ -199,8 +200,8 @@ class solarScBuilderPageMaker final : public simpleScBuilderPageMaker } }; -// Hydro levels ... -class hydroLevelsScBuilderPageMaker final : public simpleScBuilderPageMaker +// Hydro Initial levels ... +class hydroInitialLevelsScBuilderPageMaker final : public simpleScBuilderPageMaker { using simpleScBuilderPageMaker::simpleScBuilderPageMaker; @@ -210,7 +211,22 @@ class hydroLevelsScBuilderPageMaker final : public simpleScBuilderPageMaker } Notebook::Page* addPageToNotebook() override { - return notebook()->add(grid(), wxT("hydro levels"), wxT("Hydro Levels")); + return notebook()->add(grid(), wxT("hydro initial levels"), wxT("Hydro Initial Levels")); + } +}; + +// Hydro Final levels ... +class hydroFinalLevelsScBuilderPageMaker final : public simpleScBuilderPageMaker +{ + using simpleScBuilderPageMaker::simpleScBuilderPageMaker; + + Renderer::ScBuilderRendererBase* getRenderer() override + { + return new_check_allocation(); + } + Notebook::Page* addPageToNotebook() override + { + return notebook()->add(grid(), wxT("hydro final levels"), wxT("Hydro Final Levels")); } }; @@ -366,9 +382,13 @@ void ApplWnd::createNBScenarioBuilder() pScenarioBuilderNotebook->addSeparator(); - hydroLevelsScBuilderPageMaker hydroLevelsSBpageMaker(scenarioBuilderPanel, + hydroInitialLevelsScBuilderPageMaker hydroInitialLevelsSBpageMaker(scenarioBuilderPanel, + pScenarioBuilderNotebook); + pageScBuilderHydroInitialLevels = hydroInitialLevelsSBpageMaker.createPage(); + + hydroFinalLevelsScBuilderPageMaker hydroFinalLevelsSBpageMaker(scenarioBuilderPanel, pScenarioBuilderNotebook); - pageScBuilderHydroLevels = hydroLevelsSBpageMaker.createPage(); + pageScBuilderHydroFinalLevels = hydroFinalLevelsSBpageMaker.createPage(); } void ApplWnd::createNBOutputViewer() diff --git a/src/ui/simulator/application/main/main.h b/src/ui/simulator/application/main/main.h index aa16c92f33..0b1f9dd8bb 100644 --- a/src/ui/simulator/application/main/main.h +++ b/src/ui/simulator/application/main/main.h @@ -693,7 +693,8 @@ class ApplWnd final : public Component::Frame::WxLocalFrame, public Yuni::IEvent Component::Notebook::Page* pageScBuilderSolar; Component::Notebook::Page* pageScBuilderNTC; Component::Notebook::Page* pageScBuilderRenewable; - Component::Notebook::Page* pageScBuilderHydroLevels; + Component::Notebook::Page* pageScBuilderHydroInitialLevels; + Component::Notebook::Page* pageScBuilderHydroFinalLevels; //! A context menu for the map wxMenu* pMapContextMenu; diff --git a/src/ui/simulator/cmake/components.cmake b/src/ui/simulator/cmake/components.cmake index ad9dfba7a7..0586928a48 100644 --- a/src/ui/simulator/cmake/components.cmake +++ b/src/ui/simulator/cmake/components.cmake @@ -92,6 +92,8 @@ SET(SRC_TOOLBOX_COM_DBGRID_RENDERERS toolbox/components/datagrid/renderer/scenario-builder-solar-renderer.h toolbox/components/datagrid/renderer/scenario-builder-hydro-levels-renderer.h toolbox/components/datagrid/renderer/scenario-builder-hydro-levels-renderer.cpp + toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.h + toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.cpp toolbox/components/datagrid/renderer/scenario-builder-ntc-renderer.h toolbox/components/datagrid/renderer/scenario-builder-ntc-renderer.cpp toolbox/components/datagrid/renderer/layers.cpp diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.cpp new file mode 100644 index 0000000000..809767e8e6 --- /dev/null +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.cpp @@ -0,0 +1,82 @@ +/* +** Copyright 2007-2023 RTE +** Authors: RTE-international / Redstork / Antares_Simulator Team +** +** This file is part of Antares_Simulator. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** There are special exceptions to the terms and conditions of the +** license as they are applied to this software. View the full text of +** the exceptions in file COPYING.txt in the directory of this software +** distribution +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Antares_Simulator. If not, see . +** +** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions +*/ + +#include "scenario-builder-hydro-final-levels-renderer.h" +#include "antares/study/scenario-builder/scBuilderUtils.h" + +using namespace Antares::Data::ScenarioBuilder; + +namespace Antares +{ +namespace Component +{ +namespace Datagrid +{ +namespace Renderer +{ +wxString hydroFinalLevelsScBuilderRenderer::cellValue(int x, int y) const +{ + const double d = cellNumericValue(x, y); + return (std::isnan(d)) ? wxString() << wxT("init") : wxString() << fromHydroLevelToString(d); +} + +bool hydroFinalLevelsScBuilderRenderer::cellValue(int x, int y, const Yuni::String& value) +{ + if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears + && (uint)y < study->areas.size()) + { + assert((uint)y < pRules->hydroFinalLevels.width()); + assert((uint)x < pRules->hydroFinalLevels.height()); + double val = fromStringToHydroLevel(value, 100.) / 100.; + pRules->hydroFinalLevels.set_value(x, y, val); + return true; + } + return false; +} + +double hydroFinalLevelsScBuilderRenderer::cellNumericValue(int x, int y) const +{ + if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears + && (uint)y < study->areas.size()) + { + assert((uint)y < pRules->hydroFinalLevels.width()); + assert((uint)x < pRules->hydroFinalLevels.height()); + return pRules->hydroFinalLevels.get_value(x, y) * 100.; + } + return 0.; +} + +IRenderer::CellStyle hydroFinalLevelsScBuilderRenderer::cellStyle(int x, int y) const +{ + bool valid = (!(!study) && !(!pRules) && std::isnan(cellNumericValue(x, y))); + return valid ? cellStyleDefaultCenterDisabled : cellStyleDefaultCenter; +} + +} // namespace Renderer +} // namespace Datagrid +} // namespace Component +} // namespace Antares diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.h b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.h new file mode 100644 index 0000000000..85a7c87e0f --- /dev/null +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-final-levels-renderer.h @@ -0,0 +1,56 @@ +/* +** Copyright 2007-2023 RTE +** Authors: RTE-international / Redstork / Antares_Simulator Team +** +** This file is part of Antares_Simulator. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** There are special exceptions to the terms and conditions of the +** license as they are applied to this software. View the full text of +** the exceptions in file COPYING.txt in the directory of this software +** distribution +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Antares_Simulator. If not, see . +** +** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions +*/ +#ifndef __ANTARES_TOOLBOX_COMPONENT_DATAGRID_RENDERER_HYDRO_FINAL_LEVELS_SCENARIO_BUILDER_H__ +#define __ANTARES_TOOLBOX_COMPONENT_DATAGRID_RENDERER_HYDRO_FINAL_LEVELS_SCENARIO_BUILDER_H__ + +#include "scenario-builder-renderer-base.h" + +namespace Antares +{ +namespace Component +{ +namespace Datagrid +{ +namespace Renderer +{ +class hydroFinalLevelsScBuilderRenderer : public ScBuilderRendererAreasAsRows +{ +public: + hydroFinalLevelsScBuilderRenderer() = default; + + wxString cellValue(int x, int y) const; + bool cellValue(int x, int y, const Yuni::String& value); + double cellNumericValue(int x, int y) const; + IRenderer::CellStyle cellStyle(int x, int y) const; +}; // class hydroLevelsScBuilderRenderer + +} // namespace Renderer +} // namespace Datagrid +} // namespace Component +} // namespace Antares + +#endif // __ANTARES_TOOLBOX_COMPONENT_DATAGRID_RENDERER_HYDRO_FINAL_LEVELS_SCENARIO_BUILDER_H__ diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-levels-renderer.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-levels-renderer.cpp index ae8e43076f..4dce437a7d 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-levels-renderer.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-hydro-levels-renderer.cpp @@ -40,30 +40,26 @@ wxString hydroLevelsScBuilderRenderer::cellValue(int x, int y) const bool hydroLevelsScBuilderRenderer::cellValue(int x, int y, const Yuni::String& value) { - if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears) + if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears + && (uint)y < study->areas.size()) { - if ((uint)y < study->areas.size()) - { - assert((uint)y < pRules->hydroLevels.width()); - assert((uint)x < pRules->hydroLevels.height()); - double val = fromStringToHydroLevel(value, 100.) / 100.; - pRules->hydroLevels.set_value(x, y, val); - return true; - } + assert((uint)y < pRules->hydroInitialLevels.width()); + assert((uint)x < pRules->hydroInitialLevels.height()); + double val = fromStringToHydroLevel(value, 100.) / 100.; + pRules->hydroInitialLevels.set_value(x, y, val); + return true; } return false; } double hydroLevelsScBuilderRenderer::cellNumericValue(int x, int y) const { - if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears) + if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears + && (uint)y < study->areas.size()) { - if ((uint)y < study->areas.size()) - { - assert((uint)y < pRules->hydroLevels.width()); - assert((uint)x < pRules->hydroLevels.height()); - return pRules->hydroLevels.get_value(x, y) * 100.; - } + assert((uint)y < pRules->hydroInitialLevels.width()); + assert((uint)x < pRules->hydroInitialLevels.height()); + return pRules->hydroInitialLevels.get_value(x, y) * 100.; } return 0.; } @@ -71,7 +67,7 @@ double hydroLevelsScBuilderRenderer::cellNumericValue(int x, int y) const IRenderer::CellStyle hydroLevelsScBuilderRenderer::cellStyle(int x, int y) const { bool valid = (!(!study) && !(!pRules) && std::isnan(cellNumericValue(x, y))); - return (valid) ? cellStyleDefaultCenterDisabled : cellStyleDefaultCenter; + return valid ? cellStyleDefaultCenterDisabled : cellStyleDefaultCenter; } } // namespace Renderer From 6ce594fcdcddfc2c5bb6b504c16f8cac9be3862a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 21 Jun 2024 15:31:11 +0200 Subject: [PATCH 027/127] Remove src/antares-deps (#2182) --- src/antares-deps | 1 - 1 file changed, 1 deletion(-) delete mode 160000 src/antares-deps diff --git a/src/antares-deps b/src/antares-deps deleted file mode 160000 index 0d6bebfb90..0000000000 --- a/src/antares-deps +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0d6bebfb901e47ec6ac1c73cb61a522803c81b98 From 249df286b073c9f90a3a0d0e75fc5fde00180f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 21 Jun 2024 15:52:41 +0200 Subject: [PATCH 028/127] Fix condition for disabling "store in input" (#2180) --- src/libs/antares/study/load.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/antares/study/load.cpp b/src/libs/antares/study/load.cpp index 4555e106bd..4175bc2305 100644 --- a/src/libs/antares/study/load.cpp +++ b/src/libs/antares/study/load.cpp @@ -126,11 +126,11 @@ void Study::parameterFiller(const StudyLoadOptions& options) if (usedByTheSolver) { // We have time-series to import - if (parameters.exportTimeSeriesInInput && header.version == StudyVersion::latest()) + if (parameters.exportTimeSeriesInInput && header.version != StudyVersion::latest()) { logs.info() << "Stochastic TS stored in input parametrized." - " Disabling Store in input because study is not at latest version" - "Prevents writing data in unsupported format at the study version"; + " Disabling Store in input because study is not at latest version." + " This prevents writing data in unsupported format at the study version"; parameters.exportTimeSeriesInInput = 0; } } From 48a97fab3767c532992e8b08334f27b5d1b290f2 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Fri, 21 Jun 2024 16:39:10 +0200 Subject: [PATCH 029/127] Fix initialization order warnings (#2183) --- src/libs/antares/study/area/area.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/libs/antares/study/area/area.cpp b/src/libs/antares/study/area/area.cpp index 2984704716..da99f973ae 100644 --- a/src/libs/antares/study/area/area.cpp +++ b/src/libs/antares/study/area/area.cpp @@ -45,28 +45,21 @@ void Area::internalInitialize() } Area::Area(): - hydro(*this), reserves(fhrMax, HOURS_PER_YEAR), - miscGen(fhhMax, HOURS_PER_YEAR) + miscGen(fhhMax, HOURS_PER_YEAR), + hydro(*this) { internalInitialize(); } -Area::Area(const AnyString& name): - hydro(*this), - reserves(fhrMax, HOURS_PER_YEAR), - miscGen(fhhMax, HOURS_PER_YEAR) +Area::Area(const AnyString& name) : Area() { internalInitialize(); this->name = name; this->id = Antares::transformNameIntoID(this->name); } -Area::Area(const AnyString& name, const AnyString& id): - - hydro(*this), - reserves(fhrMax, HOURS_PER_YEAR), - miscGen(fhhMax, HOURS_PER_YEAR) +Area::Area(const AnyString& name, const AnyString& id) : Area() { internalInitialize(); this->name = name; From b6d824fba89dd12250202779c80149509d5db772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 21 Jun 2024 18:09:32 +0200 Subject: [PATCH 030/127] Remove temporary MSVC flag used to mitigate runner issue (#2184) Revert "Add `/D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR` to fix segfault #2151 This reverts commit a121c7571a4b6e7fed2904b325aa8127dd25261e. https://github.com/actions/runner-images/issues/10004 --- src/cmake/common-settings.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmake/common-settings.cmake b/src/cmake/common-settings.cmake index 23326f6158..b659a5f46c 100644 --- a/src/cmake/common-settings.cmake +++ b/src/cmake/common-settings.cmake @@ -11,7 +11,7 @@ if (NOT WIN32) set(COMMON_GCC_FLAGS "${COMMON_GCC_FLAGS} -Werror=return-type") endif() set(COMMON_MSVC_FLAGS "/W3 /MP4") -set(COMMON_MSVC_FLAGS "${COMMON_MSVC_FLAGS} /we4715 /we4716 /D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR") #adding no return or no return for all code paths as errors +set(COMMON_MSVC_FLAGS "${COMMON_MSVC_FLAGS} /we4715 /we4716") #adding no return or no return for all code paths as errors set(ADDITIONAL_C_FLAGS " -Wconversion -Wmissing-prototypes -Wstrict-prototypes") set(ADDITIONAL_C_FLAGS "${ADDITIONAL_C_FLAGS} -Wmissing-noreturn -Wpacked -Wredundant-decls -Wbad-function-cast -W -Wcast-align -Wcast-qual -Wsign-compare -fno-exceptions -Wdeclaration-after-statement") From b6d824072be6c7b49d66e92565ff774864ce9f19 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:17:47 +0200 Subject: [PATCH 031/127] Remove 200ms wait necessary for the GUI (#2186) close #2164 --- src/solver/main.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/solver/main.cpp b/src/solver/main.cpp index 8d07e654b8..169b29321a 100644 --- a/src/solver/main.cpp +++ b/src/solver/main.cpp @@ -130,9 +130,6 @@ int main(int argc, char** argv) application.execute(); application.writeExectutionInfo(); - // to avoid a bug from wxExecute, we should wait a little before returning - SuspendMilliSeconds(200 /*ms*/); - return EXIT_SUCCESS; } catch (const std::bad_alloc& exc) From 29e115c7625bb6ff3ff1417174855e2f11bb12b2 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:53:01 +0200 Subject: [PATCH 032/127] clean code (#2190) --- src/solver/optimisation/CMakeLists.txt | 1 - .../solver/optimisation/opt_fonctions.h | 5 -- ...ruction_matrice_des_contraintes_outils.cpp | 53 ------------------- 3 files changed, 59 deletions(-) delete mode 100644 src/solver/optimisation/opt_construction_matrice_des_contraintes_outils.cpp diff --git a/src/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt index 2e3f257932..cbf8f33fc3 100644 --- a/src/solver/optimisation/CMakeLists.txt +++ b/src/solver/optimisation/CMakeLists.txt @@ -20,7 +20,6 @@ set(RTESOLVER_OPT opt_construction_variables_optimisees_quadratique.cpp opt_decompte_variables_et_contraintes.cpp opt_decompte_variables_et_contraintes.cpp - opt_construction_matrice_des_contraintes_outils.cpp opt_gestion_des_bornes_cas_lineaire.cpp opt_verification_presence_reserve_jmoins1.cpp opt_init_contraintes_hydrauliques.cpp diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h index 8aad20d799..9d13015286 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h @@ -94,11 +94,6 @@ void OPT_RestaurerLesDonnees(PROBLEME_HEBDO*); void OPT_CalculerLesPminThermiquesEnFonctionDeMUTetMDT(PROBLEME_HEBDO*); double OPT_CalculerAireMaxPminJour(int, int, int, int, std::vector&, std::vector&); -void OPT_ChargerLaContrainteDansLaMatriceDesContraintes(PROBLEME_ANTARES_A_RESOUDRE*, - std::vector&, - std::vector&, - int, - char); void OPT_ChainagesDesIntercoPartantDUnNoeud(PROBLEME_HEBDO*); void OPT_AllocateFromNumberOfVariableConstraints(PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre, diff --git a/src/solver/optimisation/opt_construction_matrice_des_contraintes_outils.cpp b/src/solver/optimisation/opt_construction_matrice_des_contraintes_outils.cpp deleted file mode 100644 index 80ef6f809c..0000000000 --- a/src/solver/optimisation/opt_construction_matrice_des_contraintes_outils.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ - -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" -#include "antares/solver/simulation/sim_structure_donnees.h" - -void OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre, - std::vector& Pi, - std::vector& Colonne, - int NombreDeTermesDeLaContrainte, - char SensContrainte) -{ - int& nombreDeTermes = ProblemeAResoudre->NombreDeTermesDansLaMatriceDesContraintes; - int& nombreDeContraintes = ProblemeAResoudre->NombreDeContraintes; - - ProblemeAResoudre->IndicesDebutDeLigne[nombreDeContraintes] = nombreDeTermes; - for (int i = 0; i < NombreDeTermesDeLaContrainte; i++) - { - ProblemeAResoudre->CoefficientsDeLaMatriceDesContraintes[nombreDeTermes] = Pi[i]; - ProblemeAResoudre->IndicesColonnes[nombreDeTermes] = Colonne[i]; - nombreDeTermes++; - if (nombreDeTermes == ProblemeAResoudre->NombreDeTermesAllouesDansLaMatriceDesContraintes) - { - OPT_AugmenterLaTailleDeLaMatriceDesContraintes(ProblemeAResoudre); - } - } - ProblemeAResoudre->NombreDeTermesDesLignes[nombreDeContraintes] = NombreDeTermesDeLaContrainte; - - ProblemeAResoudre->Sens[nombreDeContraintes] = SensContrainte; - nombreDeContraintes++; - - return; -} From 56d0f0aa8031e4b8f814eefab9f7ffbec3c102be Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:57:47 +0200 Subject: [PATCH 033/127] =?UTF-8?q?rm=20undefined=20OPT=5FFreeOptimization?= =?UTF-8?q?Data(PROBLEME=5FANTARES=5FA=5FRESOUDRE*=20Pr=E2=80=A6=20(#2191)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …oblemeAResoudre); --- .../include/antares/solver/optimisation/opt_fonctions.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h index 9d13015286..1a52f7e331 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h @@ -98,7 +98,6 @@ void OPT_ChainagesDesIntercoPartantDUnNoeud(PROBLEME_HEBDO*); void OPT_AllocateFromNumberOfVariableConstraints(PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre, int); -void OPT_FreeOptimizationData(PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre); void OPT_AllocDuProblemeAOptimiser(PROBLEME_HEBDO*); int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO*); void OPT_AugmenterLaTailleDeLaMatriceDesContraintes(PROBLEME_ANTARES_A_RESOUDRE*); From b6c0185be6d3ac78356ea29c8cbf918aff12b999 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Tue, 25 Jun 2024 11:45:45 +0200 Subject: [PATCH 034/127] Separation of loading and validation for header [ANT-1213] (#2179) --- src/libs/antares/study/header.cpp | 13 ++----------- .../antares/study/include/antares/study/header.h | 4 ++-- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/libs/antares/study/header.cpp b/src/libs/antares/study/header.cpp index 4b751d75c7..ae44e94ad5 100644 --- a/src/libs/antares/study/header.cpp +++ b/src/libs/antares/study/header.cpp @@ -166,18 +166,8 @@ bool StudyHeader::internalLoadFromINIFile(const IniFile& ini, bool warnings) } } - if (version >= StudyVersion(7, 0)) + if (version.isSupported(true)) { - if (version > Data::StudyVersion::latest()) - { - if (warnings) - { - logs.error() << "Header: This version is not supported (version found:" - << version.toString() - << ", expected: <=" << Data::StudyVersion::latest().toString() << ')'; - } - return false; - } return true; } @@ -185,6 +175,7 @@ bool StudyHeader::internalLoadFromINIFile(const IniFile& ini, bool warnings) { logs.error() << "Study header: Invalid format"; } + return false; } diff --git a/src/libs/antares/study/include/antares/study/header.h b/src/libs/antares/study/include/antares/study/header.h index ec513143ec..aea7e0f35c 100644 --- a/src/libs/antares/study/include/antares/study/header.h +++ b/src/libs/antares/study/include/antares/study/header.h @@ -55,7 +55,6 @@ class StudyHeader final */ static bool readVersionFromFile(const std::filesystem::path& filename, std::string& version); -public: //! \name Constructor & Destructor //@{ /*! @@ -109,7 +108,8 @@ class StudyHeader final */ static StudyVersion tryToFindTheVersion(const std::string& folder); -public: + bool validateVersion(); + //! Caption of the study Yuni::String caption; From 3ca9107d14a94f4d898c0df2acea9e049870bde0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 26 Jun 2024 11:19:28 +0200 Subject: [PATCH 035/127] Check formatting as part of the CI (#2193) Succeed if all source files are well formated. Fail otherwise, and display ill-formatted files. --------- Co-authored-by: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> --- .github/workflows/clang-format.yml | 36 + .../antlr-interface/ExprBaseVisitor.cpp | 3 - .../antares/antlr-interface/ExprBaseVisitor.h | 144 +- .../antares/antlr-interface/ExprLexer.cpp | 323 ++-- src/libs/antares/antlr-interface/ExprLexer.h | 67 +- .../antares/antlr-interface/ExprParser.cpp | 1590 ++++++++++------- src/libs/antares/antlr-interface/ExprParser.h | 392 ++-- .../antares/antlr-interface/ExprVisitor.cpp | 3 - .../antares/antlr-interface/ExprVisitor.h | 48 +- .../antares/checks/checkLoadedInputData.h | 1 - .../antares/exception/LoadingError.hpp | 7 +- .../FileTreeStudyLoader.h | 1 + .../include/antares/inifile/inifile.hxx | 3 +- src/libs/antares/inifile/inifile.cpp | 12 +- src/libs/antares/io/file.cpp | 2 +- src/libs/antares/io/include/antares/io/file.h | 4 +- .../antares/study-loader/IStudyLoader.h | 1 + src/libs/antares/study/area/area.cpp | 7 +- src/libs/antares/study/area/links.cpp | 27 +- src/libs/antares/study/area/list.cpp | 21 +- .../BindingConstraintGroupRepository.cpp | 18 +- .../antares/study/cleaner/cleaner-v20.cpp | 1 - .../study/include/antares/study/parameters.h | 3 +- .../antares/study/parts/hydro/container.h | 5 +- .../study/scenario-builder/hydroLevelsData.h | 3 +- .../study/include/antares/study/sets.hxx | 4 +- src/libs/antares/study/parameters.cpp | 17 +- .../study/parts/common/cluster_list.cpp | 5 +- .../antares/study/parts/hydro/allocation.cpp | 32 +- .../antares/study/parts/hydro/container.cpp | 256 +-- .../study/parts/hydro/finalLevelValidator.cpp | 46 +- src/libs/antares/study/parts/hydro/prepro.cpp | 8 +- src/libs/antares/study/parts/hydro/series.cpp | 2 +- .../study/parts/renewable/cluster_list.cpp | 2 +- .../parts/short-term-storage/container.cpp | 24 +- .../study/parts/thermal/cluster_list.cpp | 45 +- src/libs/antares/study/runtime/runtime.cpp | 6 +- .../BindingConstraintsTSNumbersData.cpp | 10 +- .../scenario-builder/hydroLevelsData.cpp | 6 +- .../antares/study/scenario-builder/rules.cpp | 5 +- src/libs/antares/study/study.cpp | 21 +- src/libs/antares/study/study.importprepro.cpp | 10 +- src/libs/antares/study/xcast/xcast.cpp | 3 +- src/libs/antares/writer/in_memory_writer.cpp | 2 +- src/libs/antares/writer/zip_writer.cpp | 1 - src/solver/application/application.cpp | 6 +- src/solver/constraints-builder/cbuilder.cpp | 3 +- .../solver/hydro/management/management.h | 3 +- src/solver/hydro/management/daily.cpp | 6 +- src/solver/hydro/management/management.cpp | 38 +- src/solver/hydro/management/monthly.cpp | 30 +- .../include/antares/solver/misc/options.h | 2 +- src/solver/misc/options.cpp | 2 +- src/solver/simulation/adequacy.cpp | 5 +- src/solver/simulation/common-eco-adq.cpp | 22 +- src/solver/simulation/common-hydro-levels.cpp | 22 +- src/solver/simulation/common-hydro-remix.cpp | 3 +- src/solver/simulation/economy.cpp | 5 +- .../hydro-final-reservoir-level-functions.cpp | 62 +- .../antares/solver/simulation/solver.hxx | 64 +- .../simulation/sim_calcul_economique.cpp | 10 +- src/solver/simulation/timeseries-numbers.cpp | 3 +- src/solver/ts-generator/availability.cpp | 22 +- src/solver/ts-generator/xcast/xcast.cpp | 3 +- src/solver/utils/ortools_utils.cpp | 8 +- .../antares/solver/variable/economy/all.h | 4 +- .../bindingConstraintsMarginalCost.h | 7 +- .../antares/solver/variable/endoflist.h | 1 - .../end-to-end/simple_study/simple-study.cpp | 2 +- src/tests/end-to-end/utils/utils.cpp | 3 +- src/tests/end-to-end/utils/utils.h | 3 + .../antlr4-interface/test_antlr_interface.cpp | 8 +- .../test-sc-builder-file-read-line.cpp | 80 +- .../test-sc-builder-file-save.cpp | 4 +- src/tests/src/libs/antares/test_utils.cpp | 9 +- .../antares/yaml-parser/test_yaml_parser.cpp | 16 +- ...-hydro-final-reservoir-level-functions.cpp | 18 +- 77 files changed, 2117 insertions(+), 1584 deletions(-) create mode 100644 .github/workflows/clang-format.yml diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 0000000000..9e00892851 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,36 @@ +name: Check cpp formatting + +on: + push: + branches: + - develop + - feature/* + - features/* + - fix/* + +jobs: + build: + name: clang-format + + runs-on: ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Print version + run: clang-format --version + + - name: clang-format + run: cd src && ./format-code.sh + + - name: git diff + run: | + DIFF=`git status --porcelain` + if [[ $DIFF ]]; then + echo "The following files are not well formatted" + echo "$DIFF" + exit 1 + else + echo "Code is well formatted, congrats !" + fi diff --git a/src/libs/antares/antlr-interface/ExprBaseVisitor.cpp b/src/libs/antares/antlr-interface/ExprBaseVisitor.cpp index 42d6fef5d3..ec45c3a47e 100644 --- a/src/libs/antares/antlr-interface/ExprBaseVisitor.cpp +++ b/src/libs/antares/antlr-interface/ExprBaseVisitor.cpp @@ -1,7 +1,4 @@ // Generated from Expr.g4 by ANTLR 4.13.1 - #include "ExprBaseVisitor.h" - - diff --git a/src/libs/antares/antlr-interface/ExprBaseVisitor.h b/src/libs/antares/antlr-interface/ExprBaseVisitor.h index a8af3c573f..7ff7be623d 100644 --- a/src/libs/antares/antlr-interface/ExprBaseVisitor.h +++ b/src/libs/antares/antlr-interface/ExprBaseVisitor.h @@ -3,78 +3,88 @@ #pragma once - -#include "antlr4-runtime.h" #include "ExprVisitor.h" - +#include "antlr4-runtime.h" /** * This class provides an empty implementation of ExprVisitor, which can be * extended to create a visitor which only needs to handle a subset of the available methods. */ -class ExprBaseVisitor : public ExprVisitor { +class ExprBaseVisitor: public ExprVisitor +{ public: - - virtual std::any visitFullexpr(ExprParser::FullexprContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitShift(ExprParser::ShiftContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitIdentifier(ExprParser::IdentifierContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitNegation(ExprParser::NegationContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitExpression(ExprParser::ExpressionContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitComparison(ExprParser::ComparisonContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitAddsub(ExprParser::AddsubContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitPortField(ExprParser::PortFieldContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitMuldiv(ExprParser::MuldivContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitNumber(ExprParser::NumberContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitTimeIndex(ExprParser::TimeIndexContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitTimeShift(ExprParser::TimeShiftContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitFunction(ExprParser::FunctionContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitTimeShiftRange(ExprParser::TimeShiftRangeContext *ctx) override { - return visitChildren(ctx); - } - - virtual std::any visitTimeRange(ExprParser::TimeRangeContext *ctx) override { - return visitChildren(ctx); - } - - + virtual std::any visitFullexpr(ExprParser::FullexprContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitShift(ExprParser::ShiftContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitIdentifier(ExprParser::IdentifierContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitNegation(ExprParser::NegationContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitExpression(ExprParser::ExpressionContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitComparison(ExprParser::ComparisonContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitAddsub(ExprParser::AddsubContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitPortField(ExprParser::PortFieldContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitMuldiv(ExprParser::MuldivContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitNumber(ExprParser::NumberContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitTimeIndex(ExprParser::TimeIndexContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitTimeShift(ExprParser::TimeShiftContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitFunction(ExprParser::FunctionContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitTimeShiftRange(ExprParser::TimeShiftRangeContext* ctx) override + { + return visitChildren(ctx); + } + + virtual std::any visitTimeRange(ExprParser::TimeRangeContext* ctx) override + { + return visitChildren(ctx); + } }; - diff --git a/src/libs/antares/antlr-interface/ExprLexer.cpp b/src/libs/antares/antlr-interface/ExprLexer.cpp index a645fcddd0..9250294cf8 100644 --- a/src/libs/antares/antlr-interface/ExprLexer.cpp +++ b/src/libs/antares/antlr-interface/ExprLexer.cpp @@ -1,177 +1,238 @@ // Generated from Expr.g4 by ANTLR 4.13.1 - #include "ExprLexer.h" - using namespace antlr4; - - using namespace antlr4; -namespace { - -struct ExprLexerStaticData final { - ExprLexerStaticData(std::vector ruleNames, - std::vector channelNames, - std::vector modeNames, - std::vector literalNames, - std::vector symbolicNames) - : ruleNames(std::move(ruleNames)), channelNames(std::move(channelNames)), - modeNames(std::move(modeNames)), literalNames(std::move(literalNames)), +namespace +{ + +struct ExprLexerStaticData final +{ + ExprLexerStaticData(std::vector ruleNames, + std::vector channelNames, + std::vector modeNames, + std::vector literalNames, + std::vector symbolicNames): + ruleNames(std::move(ruleNames)), + channelNames(std::move(channelNames)), + modeNames(std::move(modeNames)), + literalNames(std::move(literalNames)), symbolicNames(std::move(symbolicNames)), - vocabulary(this->literalNames, this->symbolicNames) {} - - ExprLexerStaticData(const ExprLexerStaticData&) = delete; - ExprLexerStaticData(ExprLexerStaticData&&) = delete; - ExprLexerStaticData& operator=(const ExprLexerStaticData&) = delete; - ExprLexerStaticData& operator=(ExprLexerStaticData&&) = delete; - - std::vector decisionToDFA; - antlr4::atn::PredictionContextCache sharedContextCache; - const std::vector ruleNames; - const std::vector channelNames; - const std::vector modeNames; - const std::vector literalNames; - const std::vector symbolicNames; - const antlr4::dfa::Vocabulary vocabulary; - antlr4::atn::SerializedATNView serializedATN; - std::unique_ptr atn; + vocabulary(this->literalNames, this->symbolicNames) + { + } + + ExprLexerStaticData(const ExprLexerStaticData&) = delete; + ExprLexerStaticData(ExprLexerStaticData&&) = delete; + ExprLexerStaticData& operator=(const ExprLexerStaticData&) = delete; + ExprLexerStaticData& operator=(ExprLexerStaticData&&) = delete; + + std::vector decisionToDFA; + antlr4::atn::PredictionContextCache sharedContextCache; + const std::vector ruleNames; + const std::vector channelNames; + const std::vector modeNames; + const std::vector literalNames; + const std::vector symbolicNames; + const antlr4::dfa::Vocabulary vocabulary; + antlr4::atn::SerializedATNView serializedATN; + std::unique_ptr atn; }; ::antlr4::internal::OnceFlag exprlexerLexerOnceFlag; #if ANTLR4_USE_THREAD_LOCAL_CACHE static thread_local #endif -ExprLexerStaticData *exprlexerLexerStaticData = nullptr; + ExprLexerStaticData* exprlexerLexerStaticData + = nullptr; -void exprlexerLexerInitialize() { +void exprlexerLexerInitialize() +{ #if ANTLR4_USE_THREAD_LOCAL_CACHE - if (exprlexerLexerStaticData != nullptr) { - return; - } + if (exprlexerLexerStaticData != nullptr) + { + return; + } #else - assert(exprlexerLexerStaticData == nullptr); + assert(exprlexerLexerStaticData == nullptr); #endif - auto staticData = std::make_unique( - std::vector{ - "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", - "DIGIT", "CHAR", "CHAR_OR_DIGIT", "NUMBER", "TIME", "IDENTIFIER", - "COMPARISON", "ADDSUB", "MULDIV", "LBRACKET", "RBRACKET", "WS" - }, - std::vector{ - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }, - std::vector{ - "DEFAULT_MODE" - }, - std::vector{ - "", "'+'", "'-'", "'/'", "'*'", "'.'", "'('", "')'", "','", "'..'", - "", "'t'", "", "", "", "", "'['", "']'" - }, - std::vector{ - "", "", "", "", "", "", "", "", "", "", "NUMBER", "TIME", "IDENTIFIER", - "COMPARISON", "ADDSUB", "MULDIV", "LBRACKET", "RBRACKET", "WS" + auto staticData = std::make_unique( + std::vector{"T__0", "T__1", "T__2", "T__3", "T__4", + "T__5", "T__6", "T__7", "T__8", "DIGIT", + "CHAR", "CHAR_OR_DIGIT", "NUMBER", "TIME", "IDENTIFIER", + "COMPARISON", "ADDSUB", "MULDIV", "LBRACKET", "RBRACKET", + "WS"}, + std::vector{"DEFAULT_TOKEN_CHANNEL", "HIDDEN"}, + std::vector{"DEFAULT_MODE"}, + std::vector{"", + "'+'", + "'-'", + "'/'", + "'*'", + "'.'", + "'('", + "')'", + "','", + "'..'", + "", + "'t'", + "", + "", + "", + "", + "'['", + "']'"}, + std::vector{"", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "NUMBER", + "TIME", + "IDENTIFIER", + "COMPARISON", + "ADDSUB", + "MULDIV", + "LBRACKET", + "RBRACKET", + "WS"}); + static const int32_t serializedATNSegment[] = { + 4, 0, 18, 111, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, + 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, + 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, + 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, + 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 1, 0, 1, 0, 1, + 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, + 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, + 10, 1, 10, 1, 11, 1, 11, 3, 11, 69, 8, 11, 1, 12, 4, 12, 72, 8, 12, + 11, 12, 12, 12, 73, 1, 12, 1, 12, 4, 12, 78, 8, 12, 11, 12, 12, 12, 79, + 3, 12, 82, 8, 12, 1, 13, 1, 13, 1, 14, 1, 14, 5, 14, 88, 8, 14, 10, + 14, 12, 14, 91, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 98, + 8, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, + 20, 1, 20, 1, 20, 1, 20, 0, 0, 21, 1, 1, 3, 2, 5, 3, 7, 4, 9, + 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 0, 21, 0, 23, 0, 25, 10, 27, 11, + 29, 12, 31, 13, 33, 14, 35, 15, 37, 16, 39, 17, 41, 18, 1, 0, 5, 1, 0, + 48, 57, 3, 0, 65, 90, 95, 95, 97, 122, 2, 0, 43, 43, 45, 45, 2, 0, 42, + 42, 47, 47, 3, 0, 9, 10, 13, 13, 32, 32, 114, 0, 1, 1, 0, 0, 0, 0, + 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, + 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, + 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, + 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, + 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, + 0, 41, 1, 0, 0, 0, 1, 43, 1, 0, 0, 0, 3, 45, 1, 0, 0, 0, 5, + 47, 1, 0, 0, 0, 7, 49, 1, 0, 0, 0, 9, 51, 1, 0, 0, 0, 11, 53, + 1, 0, 0, 0, 13, 55, 1, 0, 0, 0, 15, 57, 1, 0, 0, 0, 17, 59, 1, + 0, 0, 0, 19, 62, 1, 0, 0, 0, 21, 64, 1, 0, 0, 0, 23, 68, 1, 0, + 0, 0, 25, 71, 1, 0, 0, 0, 27, 83, 1, 0, 0, 0, 29, 85, 1, 0, 0, + 0, 31, 97, 1, 0, 0, 0, 33, 99, 1, 0, 0, 0, 35, 101, 1, 0, 0, 0, + 37, 103, 1, 0, 0, 0, 39, 105, 1, 0, 0, 0, 41, 107, 1, 0, 0, 0, 43, + 44, 5, 43, 0, 0, 44, 2, 1, 0, 0, 0, 45, 46, 5, 45, 0, 0, 46, 4, + 1, 0, 0, 0, 47, 48, 5, 47, 0, 0, 48, 6, 1, 0, 0, 0, 49, 50, 5, + 42, 0, 0, 50, 8, 1, 0, 0, 0, 51, 52, 5, 46, 0, 0, 52, 10, 1, 0, + 0, 0, 53, 54, 5, 40, 0, 0, 54, 12, 1, 0, 0, 0, 55, 56, 5, 41, 0, + 0, 56, 14, 1, 0, 0, 0, 57, 58, 5, 44, 0, 0, 58, 16, 1, 0, 0, 0, + 59, 60, 5, 46, 0, 0, 60, 61, 5, 46, 0, 0, 61, 18, 1, 0, 0, 0, 62, + 63, 7, 0, 0, 0, 63, 20, 1, 0, 0, 0, 64, 65, 7, 1, 0, 0, 65, 22, + 1, 0, 0, 0, 66, 69, 3, 21, 10, 0, 67, 69, 3, 19, 9, 0, 68, 66, 1, + 0, 0, 0, 68, 67, 1, 0, 0, 0, 69, 24, 1, 0, 0, 0, 70, 72, 3, 19, + 9, 0, 71, 70, 1, 0, 0, 0, 72, 73, 1, 0, 0, 0, 73, 71, 1, 0, 0, + 0, 73, 74, 1, 0, 0, 0, 74, 81, 1, 0, 0, 0, 75, 77, 5, 46, 0, 0, + 76, 78, 3, 19, 9, 0, 77, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, + 77, 1, 0, 0, 0, 79, 80, 1, 0, 0, 0, 80, 82, 1, 0, 0, 0, 81, 75, + 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 26, 1, 0, 0, 0, 83, 84, 5, + 116, 0, 0, 84, 28, 1, 0, 0, 0, 85, 89, 3, 21, 10, 0, 86, 88, 3, 23, + 11, 0, 87, 86, 1, 0, 0, 0, 88, 91, 1, 0, 0, 0, 89, 87, 1, 0, 0, + 0, 89, 90, 1, 0, 0, 0, 90, 30, 1, 0, 0, 0, 91, 89, 1, 0, 0, 0, + 92, 98, 5, 61, 0, 0, 93, 94, 5, 62, 0, 0, 94, 98, 5, 61, 0, 0, 95, + 96, 5, 60, 0, 0, 96, 98, 5, 61, 0, 0, 97, 92, 1, 0, 0, 0, 97, 93, + 1, 0, 0, 0, 97, 95, 1, 0, 0, 0, 98, 32, 1, 0, 0, 0, 99, 100, 7, + 2, 0, 0, 100, 34, 1, 0, 0, 0, 101, 102, 7, 3, 0, 0, 102, 36, 1, 0, + 0, 0, 103, 104, 5, 91, 0, 0, 104, 38, 1, 0, 0, 0, 105, 106, 5, 93, 0, + 0, 106, 40, 1, 0, 0, 0, 107, 108, 7, 4, 0, 0, 108, 109, 1, 0, 0, 0, + 109, 110, 6, 20, 0, 0, 110, 42, 1, 0, 0, 0, 7, 0, 68, 73, 79, 81, 89, + 97, 1, 6, 0, 0}; + staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, + sizeof(serializedATNSegment) + / sizeof(serializedATNSegment[0])); + + antlr4::atn::ATNDeserializer deserializer; + staticData->atn = deserializer.deserialize(staticData->serializedATN); + + const size_t count = staticData->atn->getNumberOfDecisions(); + staticData->decisionToDFA.reserve(count); + for (size_t i = 0; i < count; i++) + { + staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); } - ); - static const int32_t serializedATNSegment[] = { - 4,0,18,111,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, - 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14, - 7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20,7,20,1,0, - 1,0,1,1,1,1,1,2,1,2,1,3,1,3,1,4,1,4,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1,8,1, - 8,1,9,1,9,1,10,1,10,1,11,1,11,3,11,69,8,11,1,12,4,12,72,8,12,11,12,12, - 12,73,1,12,1,12,4,12,78,8,12,11,12,12,12,79,3,12,82,8,12,1,13,1,13,1, - 14,1,14,5,14,88,8,14,10,14,12,14,91,9,14,1,15,1,15,1,15,1,15,1,15,3,15, - 98,8,15,1,16,1,16,1,17,1,17,1,18,1,18,1,19,1,19,1,20,1,20,1,20,1,20,0, - 0,21,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,0,21,0,23,0,25,10,27, - 11,29,12,31,13,33,14,35,15,37,16,39,17,41,18,1,0,5,1,0,48,57,3,0,65,90, - 95,95,97,122,2,0,43,43,45,45,2,0,42,42,47,47,3,0,9,10,13,13,32,32,114, - 0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0, - 0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0, - 0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39, - 1,0,0,0,0,41,1,0,0,0,1,43,1,0,0,0,3,45,1,0,0,0,5,47,1,0,0,0,7,49,1,0, - 0,0,9,51,1,0,0,0,11,53,1,0,0,0,13,55,1,0,0,0,15,57,1,0,0,0,17,59,1,0, - 0,0,19,62,1,0,0,0,21,64,1,0,0,0,23,68,1,0,0,0,25,71,1,0,0,0,27,83,1,0, - 0,0,29,85,1,0,0,0,31,97,1,0,0,0,33,99,1,0,0,0,35,101,1,0,0,0,37,103,1, - 0,0,0,39,105,1,0,0,0,41,107,1,0,0,0,43,44,5,43,0,0,44,2,1,0,0,0,45,46, - 5,45,0,0,46,4,1,0,0,0,47,48,5,47,0,0,48,6,1,0,0,0,49,50,5,42,0,0,50,8, - 1,0,0,0,51,52,5,46,0,0,52,10,1,0,0,0,53,54,5,40,0,0,54,12,1,0,0,0,55, - 56,5,41,0,0,56,14,1,0,0,0,57,58,5,44,0,0,58,16,1,0,0,0,59,60,5,46,0,0, - 60,61,5,46,0,0,61,18,1,0,0,0,62,63,7,0,0,0,63,20,1,0,0,0,64,65,7,1,0, - 0,65,22,1,0,0,0,66,69,3,21,10,0,67,69,3,19,9,0,68,66,1,0,0,0,68,67,1, - 0,0,0,69,24,1,0,0,0,70,72,3,19,9,0,71,70,1,0,0,0,72,73,1,0,0,0,73,71, - 1,0,0,0,73,74,1,0,0,0,74,81,1,0,0,0,75,77,5,46,0,0,76,78,3,19,9,0,77, - 76,1,0,0,0,78,79,1,0,0,0,79,77,1,0,0,0,79,80,1,0,0,0,80,82,1,0,0,0,81, - 75,1,0,0,0,81,82,1,0,0,0,82,26,1,0,0,0,83,84,5,116,0,0,84,28,1,0,0,0, - 85,89,3,21,10,0,86,88,3,23,11,0,87,86,1,0,0,0,88,91,1,0,0,0,89,87,1,0, - 0,0,89,90,1,0,0,0,90,30,1,0,0,0,91,89,1,0,0,0,92,98,5,61,0,0,93,94,5, - 62,0,0,94,98,5,61,0,0,95,96,5,60,0,0,96,98,5,61,0,0,97,92,1,0,0,0,97, - 93,1,0,0,0,97,95,1,0,0,0,98,32,1,0,0,0,99,100,7,2,0,0,100,34,1,0,0,0, - 101,102,7,3,0,0,102,36,1,0,0,0,103,104,5,91,0,0,104,38,1,0,0,0,105,106, - 5,93,0,0,106,40,1,0,0,0,107,108,7,4,0,0,108,109,1,0,0,0,109,110,6,20, - 0,0,110,42,1,0,0,0,7,0,68,73,79,81,89,97,1,6,0,0 - }; - staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0])); - - antlr4::atn::ATNDeserializer deserializer; - staticData->atn = deserializer.deserialize(staticData->serializedATN); - - const size_t count = staticData->atn->getNumberOfDecisions(); - staticData->decisionToDFA.reserve(count); - for (size_t i = 0; i < count; i++) { - staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); - } - exprlexerLexerStaticData = staticData.release(); + exprlexerLexerStaticData = staticData.release(); } -} +} // namespace -ExprLexer::ExprLexer(CharStream *input) : Lexer(input) { - ExprLexer::initialize(); - _interpreter = new atn::LexerATNSimulator(this, *exprlexerLexerStaticData->atn, exprlexerLexerStaticData->decisionToDFA, exprlexerLexerStaticData->sharedContextCache); +ExprLexer::ExprLexer(CharStream* input): + Lexer(input) +{ + ExprLexer::initialize(); + _interpreter = new atn::LexerATNSimulator(this, + *exprlexerLexerStaticData->atn, + exprlexerLexerStaticData->decisionToDFA, + exprlexerLexerStaticData->sharedContextCache); } -ExprLexer::~ExprLexer() { - delete _interpreter; +ExprLexer::~ExprLexer() +{ + delete _interpreter; } -std::string ExprLexer::getGrammarFileName() const { - return "Expr.g4"; +std::string ExprLexer::getGrammarFileName() const +{ + return "Expr.g4"; } -const std::vector& ExprLexer::getRuleNames() const { - return exprlexerLexerStaticData->ruleNames; +const std::vector& ExprLexer::getRuleNames() const +{ + return exprlexerLexerStaticData->ruleNames; } -const std::vector& ExprLexer::getChannelNames() const { - return exprlexerLexerStaticData->channelNames; +const std::vector& ExprLexer::getChannelNames() const +{ + return exprlexerLexerStaticData->channelNames; } -const std::vector& ExprLexer::getModeNames() const { - return exprlexerLexerStaticData->modeNames; +const std::vector& ExprLexer::getModeNames() const +{ + return exprlexerLexerStaticData->modeNames; } -const dfa::Vocabulary& ExprLexer::getVocabulary() const { - return exprlexerLexerStaticData->vocabulary; +const dfa::Vocabulary& ExprLexer::getVocabulary() const +{ + return exprlexerLexerStaticData->vocabulary; } -antlr4::atn::SerializedATNView ExprLexer::getSerializedATN() const { - return exprlexerLexerStaticData->serializedATN; +antlr4::atn::SerializedATNView ExprLexer::getSerializedATN() const +{ + return exprlexerLexerStaticData->serializedATN; } -const atn::ATN& ExprLexer::getATN() const { - return *exprlexerLexerStaticData->atn; +const atn::ATN& ExprLexer::getATN() const +{ + return *exprlexerLexerStaticData->atn; } - - - -void ExprLexer::initialize() { +void ExprLexer::initialize() +{ #if ANTLR4_USE_THREAD_LOCAL_CACHE - exprlexerLexerInitialize(); + exprlexerLexerInitialize(); #else - ::antlr4::internal::call_once(exprlexerLexerOnceFlag, exprlexerLexerInitialize); + ::antlr4::internal::call_once(exprlexerLexerOnceFlag, exprlexerLexerInitialize); #endif } diff --git a/src/libs/antares/antlr-interface/ExprLexer.h b/src/libs/antares/antlr-interface/ExprLexer.h index c7db2c5f77..a569ec8d21 100644 --- a/src/libs/antares/antlr-interface/ExprLexer.h +++ b/src/libs/antares/antlr-interface/ExprLexer.h @@ -3,49 +3,58 @@ #pragma once - #include "antlr4-runtime.h" - - - -class ExprLexer : public antlr4::Lexer { +class ExprLexer: public antlr4::Lexer +{ public: - enum { - T__0 = 1, T__1 = 2, T__2 = 3, T__3 = 4, T__4 = 5, T__5 = 6, T__6 = 7, - T__7 = 8, T__8 = 9, NUMBER = 10, TIME = 11, IDENTIFIER = 12, COMPARISON = 13, - ADDSUB = 14, MULDIV = 15, LBRACKET = 16, RBRACKET = 17, WS = 18 - }; + enum + { + T__0 = 1, + T__1 = 2, + T__2 = 3, + T__3 = 4, + T__4 = 5, + T__5 = 6, + T__6 = 7, + T__7 = 8, + T__8 = 9, + NUMBER = 10, + TIME = 11, + IDENTIFIER = 12, + COMPARISON = 13, + ADDSUB = 14, + MULDIV = 15, + LBRACKET = 16, + RBRACKET = 17, + WS = 18 + }; - explicit ExprLexer(antlr4::CharStream *input); + explicit ExprLexer(antlr4::CharStream* input); - ~ExprLexer() override; + ~ExprLexer() override; + std::string getGrammarFileName() const override; - std::string getGrammarFileName() const override; + const std::vector& getRuleNames() const override; - const std::vector& getRuleNames() const override; + const std::vector& getChannelNames() const override; - const std::vector& getChannelNames() const override; + const std::vector& getModeNames() const override; - const std::vector& getModeNames() const override; + const antlr4::dfa::Vocabulary& getVocabulary() const override; - const antlr4::dfa::Vocabulary& getVocabulary() const override; + antlr4::atn::SerializedATNView getSerializedATN() const override; - antlr4::atn::SerializedATNView getSerializedATN() const override; + const antlr4::atn::ATN& getATN() const override; - const antlr4::atn::ATN& getATN() const override; - - // By default the static state used to implement the lexer is lazily initialized during the first - // call to the constructor. You can call this function if you wish to initialize the static state - // ahead of time. - static void initialize(); + // By default the static state used to implement the lexer is lazily initialized during the + // first call to the constructor. You can call this function if you wish to initialize the + // static state ahead of time. + static void initialize(); private: + // Individual action functions triggered by action() above. - // Individual action functions triggered by action() above. - - // Individual semantic predicate functions triggered by sempred() above. - + // Individual semantic predicate functions triggered by sempred() above. }; - diff --git a/src/libs/antares/antlr-interface/ExprParser.cpp b/src/libs/antares/antlr-interface/ExprParser.cpp index 3c688d96d3..64335f4d82 100644 --- a/src/libs/antares/antlr-interface/ExprParser.cpp +++ b/src/libs/antares/antlr-interface/ExprParser.cpp @@ -1,884 +1,1176 @@ // Generated from Expr.g4 by ANTLR 4.13.1 - -#include "ExprVisitor.h" - #include "ExprParser.h" +#include "ExprVisitor.h" using namespace antlrcpp; using namespace antlr4; -namespace { +namespace +{ -struct ExprParserStaticData final { - ExprParserStaticData(std::vector ruleNames, - std::vector literalNames, - std::vector symbolicNames) - : ruleNames(std::move(ruleNames)), literalNames(std::move(literalNames)), +struct ExprParserStaticData final +{ + ExprParserStaticData(std::vector ruleNames, + std::vector literalNames, + std::vector symbolicNames): + ruleNames(std::move(ruleNames)), + literalNames(std::move(literalNames)), symbolicNames(std::move(symbolicNames)), - vocabulary(this->literalNames, this->symbolicNames) {} - - ExprParserStaticData(const ExprParserStaticData&) = delete; - ExprParserStaticData(ExprParserStaticData&&) = delete; - ExprParserStaticData& operator=(const ExprParserStaticData&) = delete; - ExprParserStaticData& operator=(ExprParserStaticData&&) = delete; - - std::vector decisionToDFA; - antlr4::atn::PredictionContextCache sharedContextCache; - const std::vector ruleNames; - const std::vector literalNames; - const std::vector symbolicNames; - const antlr4::dfa::Vocabulary vocabulary; - antlr4::atn::SerializedATNView serializedATN; - std::unique_ptr atn; + vocabulary(this->literalNames, this->symbolicNames) + { + } + + ExprParserStaticData(const ExprParserStaticData&) = delete; + ExprParserStaticData(ExprParserStaticData&&) = delete; + ExprParserStaticData& operator=(const ExprParserStaticData&) = delete; + ExprParserStaticData& operator=(ExprParserStaticData&&) = delete; + + std::vector decisionToDFA; + antlr4::atn::PredictionContextCache sharedContextCache; + const std::vector ruleNames; + const std::vector literalNames; + const std::vector symbolicNames; + const antlr4::dfa::Vocabulary vocabulary; + antlr4::atn::SerializedATNView serializedATN; + std::unique_ptr atn; }; ::antlr4::internal::OnceFlag exprParserOnceFlag; #if ANTLR4_USE_THREAD_LOCAL_CACHE static thread_local #endif -ExprParserStaticData *exprParserStaticData = nullptr; + ExprParserStaticData* exprParserStaticData + = nullptr; -void exprParserInitialize() { +void exprParserInitialize() +{ #if ANTLR4_USE_THREAD_LOCAL_CACHE - if (exprParserStaticData != nullptr) { - return; - } + if (exprParserStaticData != nullptr) + { + return; + } #else - assert(exprParserStaticData == nullptr); + assert(exprParserStaticData == nullptr); #endif - auto staticData = std::make_unique( - std::vector{ - "fullexpr", "shift", "expr" - }, - std::vector{ - "", "'+'", "'-'", "'/'", "'*'", "'.'", "'('", "')'", "','", "'..'", - "", "'t'", "", "", "", "", "'['", "']'" - }, - std::vector{ - "", "", "", "", "", "", "", "", "", "", "NUMBER", "TIME", "IDENTIFIER", - "COMPARISON", "ADDSUB", "MULDIV", "LBRACKET", "RBRACKET", "WS" + auto staticData = std::make_unique(std::vector{"fullexpr", + "shift", + "expr"}, + std::vector{"", + "'+'", + "'-'", + "'/'", + "'*'", + "'.'", + "'('", + "')'", + "','", + "'..'", + "", + "'t'", + "", + "", + "", + "", + "'['", + "']'"}, + std::vector{"", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "NUMBER", + "TIME", + "IDENTIFIER", + "COMPARISON", + "ADDSUB", + "MULDIV", + "LBRACKET", + "RBRACKET", + "WS"}); + static const int32_t serializedATNSegment[] = { + 4, 1, 18, 86, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 1, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 3, 1, 13, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 5, 2, 37, 8, 2, 10, 2, 12, 2, 40, 9, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 5, 2, 49, 8, 2, 10, 2, 12, 2, 52, 9, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 3, 2, 70, 8, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 5, 2, 81, 8, 2, 10, 2, 12, 2, 84, 9, 2, 1, 2, 0, 1, 4, 3, 0, 2, 4, 0, + 2, 1, 0, 1, 2, 1, 0, 3, 4, 97, 0, 6, 1, 0, 0, 0, 2, 9, 1, 0, 0, 0, 4, 69, + 1, 0, 0, 0, 6, 7, 3, 4, 2, 0, 7, 8, 5, 0, 0, 1, 8, 1, 1, 0, 0, 0, 9, 12, + 5, 11, 0, 0, 10, 11, 7, 0, 0, 0, 11, 13, 3, 4, 2, 0, 12, 10, 1, 0, 0, 0, 12, 13, + 1, 0, 0, 0, 13, 3, 1, 0, 0, 0, 14, 15, 6, 2, -1, 0, 15, 16, 5, 2, 0, 0, 16, 70, + 3, 4, 2, 13, 17, 70, 5, 12, 0, 0, 18, 19, 5, 12, 0, 0, 19, 20, 5, 5, 0, 0, 20, 70, + 5, 12, 0, 0, 21, 70, 5, 10, 0, 0, 22, 23, 5, 6, 0, 0, 23, 24, 3, 4, 2, 0, 24, 25, + 5, 7, 0, 0, 25, 70, 1, 0, 0, 0, 26, 27, 5, 12, 0, 0, 27, 28, 5, 6, 0, 0, 28, 29, + 3, 4, 2, 0, 29, 30, 5, 7, 0, 0, 30, 70, 1, 0, 0, 0, 31, 32, 5, 12, 0, 0, 32, 33, + 5, 16, 0, 0, 33, 38, 3, 2, 1, 0, 34, 35, 5, 8, 0, 0, 35, 37, 3, 2, 1, 0, 36, 34, + 1, 0, 0, 0, 37, 40, 1, 0, 0, 0, 38, 36, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, + 1, 0, 0, 0, 40, 38, 1, 0, 0, 0, 41, 42, 5, 17, 0, 0, 42, 70, 1, 0, 0, 0, 43, 44, + 5, 12, 0, 0, 44, 45, 5, 16, 0, 0, 45, 50, 3, 4, 2, 0, 46, 47, 5, 8, 0, 0, 47, 49, + 3, 4, 2, 0, 48, 46, 1, 0, 0, 0, 49, 52, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 51, + 1, 0, 0, 0, 51, 53, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 53, 54, 5, 17, 0, 0, 54, 70, + 1, 0, 0, 0, 55, 56, 5, 12, 0, 0, 56, 57, 5, 16, 0, 0, 57, 58, 3, 2, 1, 0, 58, 59, + 5, 9, 0, 0, 59, 60, 3, 2, 1, 0, 60, 61, 5, 17, 0, 0, 61, 70, 1, 0, 0, 0, 62, 63, + 5, 12, 0, 0, 63, 64, 5, 16, 0, 0, 64, 65, 3, 4, 2, 0, 65, 66, 5, 9, 0, 0, 66, 67, + 3, 4, 2, 0, 67, 68, 5, 17, 0, 0, 68, 70, 1, 0, 0, 0, 69, 14, 1, 0, 0, 0, 69, 17, + 1, 0, 0, 0, 69, 18, 1, 0, 0, 0, 69, 21, 1, 0, 0, 0, 69, 22, 1, 0, 0, 0, 69, 26, + 1, 0, 0, 0, 69, 31, 1, 0, 0, 0, 69, 43, 1, 0, 0, 0, 69, 55, 1, 0, 0, 0, 69, 62, + 1, 0, 0, 0, 70, 82, 1, 0, 0, 0, 71, 72, 10, 12, 0, 0, 72, 73, 7, 1, 0, 0, 73, 81, + 3, 4, 2, 13, 74, 75, 10, 11, 0, 0, 75, 76, 7, 0, 0, 0, 76, 81, 3, 4, 2, 12, 77, 78, + 10, 10, 0, 0, 78, 79, 5, 13, 0, 0, 79, 81, 3, 4, 2, 11, 80, 71, 1, 0, 0, 0, 80, 74, + 1, 0, 0, 0, 80, 77, 1, 0, 0, 0, 81, 84, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, + 1, 0, 0, 0, 83, 5, 1, 0, 0, 0, 84, 82, 1, 0, 0, 0, 6, 12, 38, 50, 69, 80, 82}; + staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, + sizeof(serializedATNSegment) + / sizeof(serializedATNSegment[0])); + + antlr4::atn::ATNDeserializer deserializer; + staticData->atn = deserializer.deserialize(staticData->serializedATN); + + const size_t count = staticData->atn->getNumberOfDecisions(); + staticData->decisionToDFA.reserve(count); + for (size_t i = 0; i < count; i++) + { + staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); } - ); - static const int32_t serializedATNSegment[] = { - 4,1,18,86,2,0,7,0,2,1,7,1,2,2,7,2,1,0,1,0,1,0,1,1,1,1,1,1,3,1,13,8,1, - 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1, - 2,1,2,1,2,1,2,1,2,5,2,37,8,2,10,2,12,2,40,9,2,1,2,1,2,1,2,1,2,1,2,1,2, - 1,2,5,2,49,8,2,10,2,12,2,52,9,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1, - 2,1,2,1,2,1,2,1,2,1,2,1,2,3,2,70,8,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2, - 1,2,5,2,81,8,2,10,2,12,2,84,9,2,1,2,0,1,4,3,0,2,4,0,2,1,0,1,2,1,0,3,4, - 97,0,6,1,0,0,0,2,9,1,0,0,0,4,69,1,0,0,0,6,7,3,4,2,0,7,8,5,0,0,1,8,1,1, - 0,0,0,9,12,5,11,0,0,10,11,7,0,0,0,11,13,3,4,2,0,12,10,1,0,0,0,12,13,1, - 0,0,0,13,3,1,0,0,0,14,15,6,2,-1,0,15,16,5,2,0,0,16,70,3,4,2,13,17,70, - 5,12,0,0,18,19,5,12,0,0,19,20,5,5,0,0,20,70,5,12,0,0,21,70,5,10,0,0,22, - 23,5,6,0,0,23,24,3,4,2,0,24,25,5,7,0,0,25,70,1,0,0,0,26,27,5,12,0,0,27, - 28,5,6,0,0,28,29,3,4,2,0,29,30,5,7,0,0,30,70,1,0,0,0,31,32,5,12,0,0,32, - 33,5,16,0,0,33,38,3,2,1,0,34,35,5,8,0,0,35,37,3,2,1,0,36,34,1,0,0,0,37, - 40,1,0,0,0,38,36,1,0,0,0,38,39,1,0,0,0,39,41,1,0,0,0,40,38,1,0,0,0,41, - 42,5,17,0,0,42,70,1,0,0,0,43,44,5,12,0,0,44,45,5,16,0,0,45,50,3,4,2,0, - 46,47,5,8,0,0,47,49,3,4,2,0,48,46,1,0,0,0,49,52,1,0,0,0,50,48,1,0,0,0, - 50,51,1,0,0,0,51,53,1,0,0,0,52,50,1,0,0,0,53,54,5,17,0,0,54,70,1,0,0, - 0,55,56,5,12,0,0,56,57,5,16,0,0,57,58,3,2,1,0,58,59,5,9,0,0,59,60,3,2, - 1,0,60,61,5,17,0,0,61,70,1,0,0,0,62,63,5,12,0,0,63,64,5,16,0,0,64,65, - 3,4,2,0,65,66,5,9,0,0,66,67,3,4,2,0,67,68,5,17,0,0,68,70,1,0,0,0,69,14, - 1,0,0,0,69,17,1,0,0,0,69,18,1,0,0,0,69,21,1,0,0,0,69,22,1,0,0,0,69,26, - 1,0,0,0,69,31,1,0,0,0,69,43,1,0,0,0,69,55,1,0,0,0,69,62,1,0,0,0,70,82, - 1,0,0,0,71,72,10,12,0,0,72,73,7,1,0,0,73,81,3,4,2,13,74,75,10,11,0,0, - 75,76,7,0,0,0,76,81,3,4,2,12,77,78,10,10,0,0,78,79,5,13,0,0,79,81,3,4, - 2,11,80,71,1,0,0,0,80,74,1,0,0,0,80,77,1,0,0,0,81,84,1,0,0,0,82,80,1, - 0,0,0,82,83,1,0,0,0,83,5,1,0,0,0,84,82,1,0,0,0,6,12,38,50,69,80,82 - }; - staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0])); - - antlr4::atn::ATNDeserializer deserializer; - staticData->atn = deserializer.deserialize(staticData->serializedATN); - - const size_t count = staticData->atn->getNumberOfDecisions(); - staticData->decisionToDFA.reserve(count); - for (size_t i = 0; i < count; i++) { - staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); - } - exprParserStaticData = staticData.release(); -} - + exprParserStaticData = staticData.release(); } -ExprParser::ExprParser(TokenStream *input) : ExprParser(input, antlr4::atn::ParserATNSimulatorOptions()) {} +} // namespace -ExprParser::ExprParser(TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options) : Parser(input) { - ExprParser::initialize(); - _interpreter = new atn::ParserATNSimulator(this, *exprParserStaticData->atn, exprParserStaticData->decisionToDFA, exprParserStaticData->sharedContextCache, options); +ExprParser::ExprParser(TokenStream* input): + ExprParser(input, antlr4::atn::ParserATNSimulatorOptions()) +{ } -ExprParser::~ExprParser() { - delete _interpreter; +ExprParser::ExprParser(TokenStream* input, const antlr4::atn::ParserATNSimulatorOptions& options): + Parser(input) +{ + ExprParser::initialize(); + _interpreter = new atn::ParserATNSimulator(this, + *exprParserStaticData->atn, + exprParserStaticData->decisionToDFA, + exprParserStaticData->sharedContextCache, + options); } -const atn::ATN& ExprParser::getATN() const { - return *exprParserStaticData->atn; +ExprParser::~ExprParser() +{ + delete _interpreter; } -std::string ExprParser::getGrammarFileName() const { - return "Expr.g4"; +const atn::ATN& ExprParser::getATN() const +{ + return *exprParserStaticData->atn; } -const std::vector& ExprParser::getRuleNames() const { - return exprParserStaticData->ruleNames; +std::string ExprParser::getGrammarFileName() const +{ + return "Expr.g4"; } -const dfa::Vocabulary& ExprParser::getVocabulary() const { - return exprParserStaticData->vocabulary; +const std::vector& ExprParser::getRuleNames() const +{ + return exprParserStaticData->ruleNames; } -antlr4::atn::SerializedATNView ExprParser::getSerializedATN() const { - return exprParserStaticData->serializedATN; +const dfa::Vocabulary& ExprParser::getVocabulary() const +{ + return exprParserStaticData->vocabulary; } +antlr4::atn::SerializedATNView ExprParser::getSerializedATN() const +{ + return exprParserStaticData->serializedATN; +} -//----------------- FullexprContext ------------------------------------------------------------------ +//----------------- FullexprContext +//------------------------------------------------------------------ -ExprParser::FullexprContext::FullexprContext(ParserRuleContext *parent, size_t invokingState) - : ParserRuleContext(parent, invokingState) { +ExprParser::FullexprContext::FullexprContext(ParserRuleContext* parent, size_t invokingState): + ParserRuleContext(parent, invokingState) +{ } -ExprParser::ExprContext* ExprParser::FullexprContext::expr() { - return getRuleContext(0); +ExprParser::ExprContext* ExprParser::FullexprContext::expr() +{ + return getRuleContext(0); } -tree::TerminalNode* ExprParser::FullexprContext::EOF() { - return getToken(ExprParser::EOF, 0); +tree::TerminalNode* ExprParser::FullexprContext::EOF() +{ + return getToken(ExprParser::EOF, 0); } - -size_t ExprParser::FullexprContext::getRuleIndex() const { - return ExprParser::RuleFullexpr; +size_t ExprParser::FullexprContext::getRuleIndex() const +{ + return ExprParser::RuleFullexpr; } - -std::any ExprParser::FullexprContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitFullexpr(this); - else - return visitor->visitChildren(this); +std::any ExprParser::FullexprContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitFullexpr(this); + } + else + { + return visitor->visitChildren(this); + } } -ExprParser::FullexprContext* ExprParser::fullexpr() { - FullexprContext *_localctx = _tracker.createInstance(_ctx, getState()); - enterRule(_localctx, 0, ExprParser::RuleFullexpr); +ExprParser::FullexprContext* ExprParser::fullexpr() +{ + FullexprContext* _localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 0, ExprParser::RuleFullexpr); #if __cplusplus > 201703L - auto onExit = finally([=, this] { + auto onExit = finally( + [=, this] + { #else - auto onExit = finally([=] { + auto onExit = finally( + [=] + { #endif - exitRule(); - }); - try { - enterOuterAlt(_localctx, 1); - setState(6); - expr(0); - setState(7); - match(ExprParser::EOF); - - } - catch (RecognitionException &e) { - _errHandler->reportError(this, e); - _localctx->exception = std::current_exception(); - _errHandler->recover(this, _localctx->exception); - } - - return _localctx; + exitRule(); + }); + try + { + enterOuterAlt(_localctx, 1); + setState(6); + expr(0); + setState(7); + match(ExprParser::EOF); + } + catch (RecognitionException& e) + { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; } //----------------- ShiftContext ------------------------------------------------------------------ -ExprParser::ShiftContext::ShiftContext(ParserRuleContext *parent, size_t invokingState) - : ParserRuleContext(parent, invokingState) { +ExprParser::ShiftContext::ShiftContext(ParserRuleContext* parent, size_t invokingState): + ParserRuleContext(parent, invokingState) +{ } -tree::TerminalNode* ExprParser::ShiftContext::TIME() { - return getToken(ExprParser::TIME, 0); +tree::TerminalNode* ExprParser::ShiftContext::TIME() +{ + return getToken(ExprParser::TIME, 0); } -ExprParser::ExprContext* ExprParser::ShiftContext::expr() { - return getRuleContext(0); +ExprParser::ExprContext* ExprParser::ShiftContext::expr() +{ + return getRuleContext(0); } - -size_t ExprParser::ShiftContext::getRuleIndex() const { - return ExprParser::RuleShift; +size_t ExprParser::ShiftContext::getRuleIndex() const +{ + return ExprParser::RuleShift; } - -std::any ExprParser::ShiftContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitShift(this); - else - return visitor->visitChildren(this); +std::any ExprParser::ShiftContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitShift(this); + } + else + { + return visitor->visitChildren(this); + } } -ExprParser::ShiftContext* ExprParser::shift() { - ShiftContext *_localctx = _tracker.createInstance(_ctx, getState()); - enterRule(_localctx, 2, ExprParser::RuleShift); - size_t _la = 0; +ExprParser::ShiftContext* ExprParser::shift() +{ + ShiftContext* _localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 2, ExprParser::RuleShift); + size_t _la = 0; #if __cplusplus > 201703L - auto onExit = finally([=, this] { + auto onExit = finally( + [=, this] + { #else - auto onExit = finally([=] { + auto onExit = finally( + [=] + { #endif - exitRule(); - }); - try { - enterOuterAlt(_localctx, 1); - setState(9); - match(ExprParser::TIME); - setState(12); - _errHandler->sync(this); - - _la = _input->LA(1); - if (_la == ExprParser::T__0 - - || _la == ExprParser::T__1) { - setState(10); - antlrcpp::downCast(_localctx)->op = _input->LT(1); - _la = _input->LA(1); - if (!(_la == ExprParser::T__0 - - || _la == ExprParser::T__1)) { - antlrcpp::downCast(_localctx)->op = _errHandler->recoverInline(this); - } - else { - _errHandler->reportMatch(this); - consume(); - } - setState(11); - expr(0); - } - - } - catch (RecognitionException &e) { - _errHandler->reportError(this, e); - _localctx->exception = std::current_exception(); - _errHandler->recover(this, _localctx->exception); - } - - return _localctx; + exitRule(); + }); + try + { + enterOuterAlt(_localctx, 1); + setState(9); + match(ExprParser::TIME); + setState(12); + _errHandler->sync(this); + + _la = _input->LA(1); + if (_la == ExprParser::T__0 + + || _la == ExprParser::T__1) + { + setState(10); + antlrcpp::downCast(_localctx)->op = _input->LT(1); + _la = _input->LA(1); + if (!(_la == ExprParser::T__0 + + || _la == ExprParser::T__1)) + { + antlrcpp::downCast(_localctx)->op = _errHandler->recoverInline(this); + } + else + { + _errHandler->reportMatch(this); + consume(); + } + setState(11); + expr(0); + } + } + catch (RecognitionException& e) + { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; } //----------------- ExprContext ------------------------------------------------------------------ -ExprParser::ExprContext::ExprContext(ParserRuleContext *parent, size_t invokingState) - : ParserRuleContext(parent, invokingState) { +ExprParser::ExprContext::ExprContext(ParserRuleContext* parent, size_t invokingState): + ParserRuleContext(parent, invokingState) +{ } - -size_t ExprParser::ExprContext::getRuleIndex() const { - return ExprParser::RuleExpr; +size_t ExprParser::ExprContext::getRuleIndex() const +{ + return ExprParser::RuleExpr; } -void ExprParser::ExprContext::copyFrom(ExprContext *ctx) { - ParserRuleContext::copyFrom(ctx); +void ExprParser::ExprContext::copyFrom(ExprContext* ctx) +{ + ParserRuleContext::copyFrom(ctx); } -//----------------- IdentifierContext ------------------------------------------------------------------ +//----------------- IdentifierContext +//------------------------------------------------------------------ + +tree::TerminalNode* ExprParser::IdentifierContext::IDENTIFIER() +{ + return getToken(ExprParser::IDENTIFIER, 0); +} -tree::TerminalNode* ExprParser::IdentifierContext::IDENTIFIER() { - return getToken(ExprParser::IDENTIFIER, 0); +ExprParser::IdentifierContext::IdentifierContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::IdentifierContext::IdentifierContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::IdentifierContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitIdentifier(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- NegationContext +//------------------------------------------------------------------ -std::any ExprParser::IdentifierContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitIdentifier(this); - else - return visitor->visitChildren(this); +ExprParser::ExprContext* ExprParser::NegationContext::expr() +{ + return getRuleContext(0); } -//----------------- NegationContext ------------------------------------------------------------------ -ExprParser::ExprContext* ExprParser::NegationContext::expr() { - return getRuleContext(0); +ExprParser::NegationContext::NegationContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::NegationContext::NegationContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::NegationContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitNegation(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- ExpressionContext +//------------------------------------------------------------------ -std::any ExprParser::NegationContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitNegation(this); - else - return visitor->visitChildren(this); +ExprParser::ExprContext* ExprParser::ExpressionContext::expr() +{ + return getRuleContext(0); } -//----------------- ExpressionContext ------------------------------------------------------------------ -ExprParser::ExprContext* ExprParser::ExpressionContext::expr() { - return getRuleContext(0); +ExprParser::ExpressionContext::ExpressionContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::ExpressionContext::ExpressionContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::ExpressionContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitExpression(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- ComparisonContext +//------------------------------------------------------------------ -std::any ExprParser::ExpressionContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitExpression(this); - else - return visitor->visitChildren(this); +std::vector ExprParser::ComparisonContext::expr() +{ + return getRuleContexts(); } -//----------------- ComparisonContext ------------------------------------------------------------------ -std::vector ExprParser::ComparisonContext::expr() { - return getRuleContexts(); +ExprParser::ExprContext* ExprParser::ComparisonContext::expr(size_t i) +{ + return getRuleContext(i); } -ExprParser::ExprContext* ExprParser::ComparisonContext::expr(size_t i) { - return getRuleContext(i); +tree::TerminalNode* ExprParser::ComparisonContext::COMPARISON() +{ + return getToken(ExprParser::COMPARISON, 0); } -tree::TerminalNode* ExprParser::ComparisonContext::COMPARISON() { - return getToken(ExprParser::COMPARISON, 0); +ExprParser::ComparisonContext::ComparisonContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::ComparisonContext::ComparisonContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::ComparisonContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitComparison(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- AddsubContext ------------------------------------------------------------------ -std::any ExprParser::ComparisonContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitComparison(this); - else - return visitor->visitChildren(this); +std::vector ExprParser::AddsubContext::expr() +{ + return getRuleContexts(); } -//----------------- AddsubContext ------------------------------------------------------------------ -std::vector ExprParser::AddsubContext::expr() { - return getRuleContexts(); +ExprParser::ExprContext* ExprParser::AddsubContext::expr(size_t i) +{ + return getRuleContext(i); } -ExprParser::ExprContext* ExprParser::AddsubContext::expr(size_t i) { - return getRuleContext(i); +ExprParser::AddsubContext::AddsubContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::AddsubContext::AddsubContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::AddsubContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitAddsub(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- PortFieldContext +//------------------------------------------------------------------ -std::any ExprParser::AddsubContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitAddsub(this); - else - return visitor->visitChildren(this); +std::vector ExprParser::PortFieldContext::IDENTIFIER() +{ + return getTokens(ExprParser::IDENTIFIER); } -//----------------- PortFieldContext ------------------------------------------------------------------ -std::vector ExprParser::PortFieldContext::IDENTIFIER() { - return getTokens(ExprParser::IDENTIFIER); +tree::TerminalNode* ExprParser::PortFieldContext::IDENTIFIER(size_t i) +{ + return getToken(ExprParser::IDENTIFIER, i); } -tree::TerminalNode* ExprParser::PortFieldContext::IDENTIFIER(size_t i) { - return getToken(ExprParser::IDENTIFIER, i); +ExprParser::PortFieldContext::PortFieldContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::PortFieldContext::PortFieldContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::PortFieldContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitPortField(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- MuldivContext ------------------------------------------------------------------ -std::any ExprParser::PortFieldContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitPortField(this); - else - return visitor->visitChildren(this); +std::vector ExprParser::MuldivContext::expr() +{ + return getRuleContexts(); } -//----------------- MuldivContext ------------------------------------------------------------------ -std::vector ExprParser::MuldivContext::expr() { - return getRuleContexts(); +ExprParser::ExprContext* ExprParser::MuldivContext::expr(size_t i) +{ + return getRuleContext(i); } -ExprParser::ExprContext* ExprParser::MuldivContext::expr(size_t i) { - return getRuleContext(i); +ExprParser::MuldivContext::MuldivContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::MuldivContext::MuldivContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::MuldivContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitMuldiv(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- NumberContext ------------------------------------------------------------------ -std::any ExprParser::MuldivContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitMuldiv(this); - else - return visitor->visitChildren(this); +tree::TerminalNode* ExprParser::NumberContext::NUMBER() +{ + return getToken(ExprParser::NUMBER, 0); } -//----------------- NumberContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::NumberContext::NUMBER() { - return getToken(ExprParser::NUMBER, 0); +ExprParser::NumberContext::NumberContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::NumberContext::NumberContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::NumberContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitNumber(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- TimeIndexContext +//------------------------------------------------------------------ -std::any ExprParser::NumberContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitNumber(this); - else - return visitor->visitChildren(this); +tree::TerminalNode* ExprParser::TimeIndexContext::IDENTIFIER() +{ + return getToken(ExprParser::IDENTIFIER, 0); } -//----------------- TimeIndexContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::TimeIndexContext::IDENTIFIER() { - return getToken(ExprParser::IDENTIFIER, 0); +tree::TerminalNode* ExprParser::TimeIndexContext::LBRACKET() +{ + return getToken(ExprParser::LBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeIndexContext::LBRACKET() { - return getToken(ExprParser::LBRACKET, 0); +std::vector ExprParser::TimeIndexContext::expr() +{ + return getRuleContexts(); } -std::vector ExprParser::TimeIndexContext::expr() { - return getRuleContexts(); +ExprParser::ExprContext* ExprParser::TimeIndexContext::expr(size_t i) +{ + return getRuleContext(i); } -ExprParser::ExprContext* ExprParser::TimeIndexContext::expr(size_t i) { - return getRuleContext(i); +tree::TerminalNode* ExprParser::TimeIndexContext::RBRACKET() +{ + return getToken(ExprParser::RBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeIndexContext::RBRACKET() { - return getToken(ExprParser::RBRACKET, 0); +ExprParser::TimeIndexContext::TimeIndexContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::TimeIndexContext::TimeIndexContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::TimeIndexContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitTimeIndex(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- TimeShiftContext +//------------------------------------------------------------------ -std::any ExprParser::TimeIndexContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitTimeIndex(this); - else - return visitor->visitChildren(this); +tree::TerminalNode* ExprParser::TimeShiftContext::IDENTIFIER() +{ + return getToken(ExprParser::IDENTIFIER, 0); } -//----------------- TimeShiftContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::TimeShiftContext::IDENTIFIER() { - return getToken(ExprParser::IDENTIFIER, 0); +tree::TerminalNode* ExprParser::TimeShiftContext::LBRACKET() +{ + return getToken(ExprParser::LBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeShiftContext::LBRACKET() { - return getToken(ExprParser::LBRACKET, 0); +std::vector ExprParser::TimeShiftContext::shift() +{ + return getRuleContexts(); } -std::vector ExprParser::TimeShiftContext::shift() { - return getRuleContexts(); +ExprParser::ShiftContext* ExprParser::TimeShiftContext::shift(size_t i) +{ + return getRuleContext(i); } -ExprParser::ShiftContext* ExprParser::TimeShiftContext::shift(size_t i) { - return getRuleContext(i); +tree::TerminalNode* ExprParser::TimeShiftContext::RBRACKET() +{ + return getToken(ExprParser::RBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeShiftContext::RBRACKET() { - return getToken(ExprParser::RBRACKET, 0); +ExprParser::TimeShiftContext::TimeShiftContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::TimeShiftContext::TimeShiftContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::TimeShiftContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitTimeShift(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- FunctionContext +//------------------------------------------------------------------ -std::any ExprParser::TimeShiftContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitTimeShift(this); - else - return visitor->visitChildren(this); +tree::TerminalNode* ExprParser::FunctionContext::IDENTIFIER() +{ + return getToken(ExprParser::IDENTIFIER, 0); } -//----------------- FunctionContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::FunctionContext::IDENTIFIER() { - return getToken(ExprParser::IDENTIFIER, 0); +ExprParser::ExprContext* ExprParser::FunctionContext::expr() +{ + return getRuleContext(0); } -ExprParser::ExprContext* ExprParser::FunctionContext::expr() { - return getRuleContext(0); +ExprParser::FunctionContext::FunctionContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::FunctionContext::FunctionContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::FunctionContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitFunction(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- TimeShiftRangeContext +//------------------------------------------------------------------ -std::any ExprParser::FunctionContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitFunction(this); - else - return visitor->visitChildren(this); +tree::TerminalNode* ExprParser::TimeShiftRangeContext::IDENTIFIER() +{ + return getToken(ExprParser::IDENTIFIER, 0); } -//----------------- TimeShiftRangeContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::TimeShiftRangeContext::IDENTIFIER() { - return getToken(ExprParser::IDENTIFIER, 0); +tree::TerminalNode* ExprParser::TimeShiftRangeContext::LBRACKET() +{ + return getToken(ExprParser::LBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeShiftRangeContext::LBRACKET() { - return getToken(ExprParser::LBRACKET, 0); +tree::TerminalNode* ExprParser::TimeShiftRangeContext::RBRACKET() +{ + return getToken(ExprParser::RBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeShiftRangeContext::RBRACKET() { - return getToken(ExprParser::RBRACKET, 0); +std::vector ExprParser::TimeShiftRangeContext::shift() +{ + return getRuleContexts(); } -std::vector ExprParser::TimeShiftRangeContext::shift() { - return getRuleContexts(); +ExprParser::ShiftContext* ExprParser::TimeShiftRangeContext::shift(size_t i) +{ + return getRuleContext(i); } -ExprParser::ShiftContext* ExprParser::TimeShiftRangeContext::shift(size_t i) { - return getRuleContext(i); +ExprParser::TimeShiftRangeContext::TimeShiftRangeContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::TimeShiftRangeContext::TimeShiftRangeContext(ExprContext *ctx) { copyFrom(ctx); } +std::any ExprParser::TimeShiftRangeContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitTimeShiftRange(this); + } + else + { + return visitor->visitChildren(this); + } +} +//----------------- TimeRangeContext +//------------------------------------------------------------------ -std::any ExprParser::TimeShiftRangeContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitTimeShiftRange(this); - else - return visitor->visitChildren(this); +tree::TerminalNode* ExprParser::TimeRangeContext::IDENTIFIER() +{ + return getToken(ExprParser::IDENTIFIER, 0); } -//----------------- TimeRangeContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::TimeRangeContext::IDENTIFIER() { - return getToken(ExprParser::IDENTIFIER, 0); +tree::TerminalNode* ExprParser::TimeRangeContext::LBRACKET() +{ + return getToken(ExprParser::LBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeRangeContext::LBRACKET() { - return getToken(ExprParser::LBRACKET, 0); +std::vector ExprParser::TimeRangeContext::expr() +{ + return getRuleContexts(); } -std::vector ExprParser::TimeRangeContext::expr() { - return getRuleContexts(); +ExprParser::ExprContext* ExprParser::TimeRangeContext::expr(size_t i) +{ + return getRuleContext(i); } -ExprParser::ExprContext* ExprParser::TimeRangeContext::expr(size_t i) { - return getRuleContext(i); +tree::TerminalNode* ExprParser::TimeRangeContext::RBRACKET() +{ + return getToken(ExprParser::RBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeRangeContext::RBRACKET() { - return getToken(ExprParser::RBRACKET, 0); +ExprParser::TimeRangeContext::TimeRangeContext(ExprContext* ctx) +{ + copyFrom(ctx); } -ExprParser::TimeRangeContext::TimeRangeContext(ExprContext *ctx) { copyFrom(ctx); } - - -std::any ExprParser::TimeRangeContext::accept(tree::ParseTreeVisitor *visitor) { - if (auto parserVisitor = dynamic_cast(visitor)) - return parserVisitor->visitTimeRange(this); - else - return visitor->visitChildren(this); +std::any ExprParser::TimeRangeContext::accept(tree::ParseTreeVisitor* visitor) +{ + if (auto parserVisitor = dynamic_cast(visitor)) + { + return parserVisitor->visitTimeRange(this); + } + else + { + return visitor->visitChildren(this); + } } -ExprParser::ExprContext* ExprParser::expr() { - return expr(0); +ExprParser::ExprContext* ExprParser::expr() +{ + return expr(0); } -ExprParser::ExprContext* ExprParser::expr(int precedence) { - ParserRuleContext *parentContext = _ctx; - size_t parentState = getState(); - ExprParser::ExprContext *_localctx = _tracker.createInstance(_ctx, parentState); - ExprParser::ExprContext *previousContext = _localctx; - (void)previousContext; // Silence compiler, in case the context is not used by generated code. - size_t startState = 4; - enterRecursionRule(_localctx, 4, ExprParser::RuleExpr, precedence); +ExprParser::ExprContext* ExprParser::expr(int precedence) +{ + ParserRuleContext* parentContext = _ctx; + size_t parentState = getState(); + ExprParser::ExprContext* _localctx = _tracker.createInstance(_ctx, parentState); + ExprParser::ExprContext* previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. + size_t startState = 4; + enterRecursionRule(_localctx, 4, ExprParser::RuleExpr, precedence); size_t _la = 0; #if __cplusplus > 201703L - auto onExit = finally([=, this] { + auto onExit = finally( + [=, this] + { #else - auto onExit = finally([=] { + auto onExit = finally( + [=] + { #endif - unrollRecursionContexts(parentContext); - }); - try { - size_t alt; - enterOuterAlt(_localctx, 1); - setState(69); - _errHandler->sync(this); - switch (getInterpreter()->adaptivePredict(_input, 3, _ctx)) { - case 1: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - - setState(15); - match(ExprParser::T__1); - setState(16); - expr(13); - break; - } - - case 2: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(17); - match(ExprParser::IDENTIFIER); - break; - } - - case 3: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(18); - match(ExprParser::IDENTIFIER); - setState(19); - match(ExprParser::T__4); - setState(20); - match(ExprParser::IDENTIFIER); - break; - } - - case 4: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(21); - match(ExprParser::NUMBER); - break; - } - - case 5: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(22); - match(ExprParser::T__5); - setState(23); - expr(0); - setState(24); - match(ExprParser::T__6); - break; - } - - case 6: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(26); - match(ExprParser::IDENTIFIER); - setState(27); - match(ExprParser::T__5); - setState(28); - expr(0); - setState(29); - match(ExprParser::T__6); - break; - } - - case 7: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(31); - match(ExprParser::IDENTIFIER); - setState(32); - match(ExprParser::LBRACKET); - setState(33); - shift(); - setState(38); - _errHandler->sync(this); - _la = _input->LA(1); - while (_la == ExprParser::T__7) { - setState(34); - match(ExprParser::T__7); - setState(35); - shift(); - setState(40); - _errHandler->sync(this); - _la = _input->LA(1); - } - setState(41); - match(ExprParser::RBRACKET); - break; - } - - case 8: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(43); - match(ExprParser::IDENTIFIER); - setState(44); - match(ExprParser::LBRACKET); - setState(45); - expr(0); - setState(50); - _errHandler->sync(this); - _la = _input->LA(1); - while (_la == ExprParser::T__7) { - setState(46); - match(ExprParser::T__7); - setState(47); - expr(0); - setState(52); + unrollRecursionContexts(parentContext); + }); + try + { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(69); _errHandler->sync(this); - _la = _input->LA(1); - } - setState(53); - match(ExprParser::RBRACKET); - break; - } - - case 9: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(55); - match(ExprParser::IDENTIFIER); - setState(56); - match(ExprParser::LBRACKET); - setState(57); - antlrcpp::downCast(_localctx)->shift1 = shift(); - setState(58); - match(ExprParser::T__8); - setState(59); - antlrcpp::downCast(_localctx)->shift2 = shift(); - setState(60); - match(ExprParser::RBRACKET); - break; - } - - case 10: { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(62); - match(ExprParser::IDENTIFIER); - setState(63); - match(ExprParser::LBRACKET); - setState(64); - expr(0); - setState(65); - match(ExprParser::T__8); - setState(66); - expr(0); - setState(67); - match(ExprParser::RBRACKET); - break; - } + switch (getInterpreter()->adaptivePredict(_input, 3, _ctx)) + { + case 1: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + + setState(15); + match(ExprParser::T__1); + setState(16); + expr(13); + break; + } - default: - break; - } - _ctx->stop = _input->LT(-1); - setState(82); - _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 5, _ctx); - while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { - if (alt == 1) { - if (!_parseListeners.empty()) - triggerExitRuleEvent(); - previousContext = _localctx; - setState(80); - _errHandler->sync(this); - switch (getInterpreter()->adaptivePredict(_input, 4, _ctx)) { - case 1: { - auto newContext = _tracker.createInstance(_tracker.createInstance(parentContext, parentState)); - _localctx = newContext; - pushNewRecursionContext(newContext, startState, RuleExpr); - setState(71); - - if (!(precpred(_ctx, 12))) throw FailedPredicateException(this, "precpred(_ctx, 12)"); - setState(72); - antlrcpp::downCast(_localctx)->op = _input->LT(1); - _la = _input->LA(1); - if (!(_la == ExprParser::T__2 - - || _la == ExprParser::T__3)) { - antlrcpp::downCast(_localctx)->op = _errHandler->recoverInline(this); - } - else { - _errHandler->reportMatch(this); - consume(); - } - setState(73); - expr(13); - break; + case 2: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(17); + match(ExprParser::IDENTIFIER); + break; } - case 2: { - auto newContext = _tracker.createInstance(_tracker.createInstance(parentContext, parentState)); - _localctx = newContext; - pushNewRecursionContext(newContext, startState, RuleExpr); - setState(74); - - if (!(precpred(_ctx, 11))) throw FailedPredicateException(this, "precpred(_ctx, 11)"); - setState(75); - antlrcpp::downCast(_localctx)->op = _input->LT(1); - _la = _input->LA(1); - if (!(_la == ExprParser::T__0 - - || _la == ExprParser::T__1)) { - antlrcpp::downCast(_localctx)->op = _errHandler->recoverInline(this); - } - else { - _errHandler->reportMatch(this); - consume(); - } - setState(76); - expr(12); - break; + case 3: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(18); + match(ExprParser::IDENTIFIER); + setState(19); + match(ExprParser::T__4); + setState(20); + match(ExprParser::IDENTIFIER); + break; } - case 3: { - auto newContext = _tracker.createInstance(_tracker.createInstance(parentContext, parentState)); - _localctx = newContext; - pushNewRecursionContext(newContext, startState, RuleExpr); - setState(77); - - if (!(precpred(_ctx, 10))) throw FailedPredicateException(this, "precpred(_ctx, 10)"); - setState(78); - match(ExprParser::COMPARISON); - setState(79); - expr(11); - break; + case 4: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(21); + match(ExprParser::NUMBER); + break; + } + + case 5: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(22); + match(ExprParser::T__5); + setState(23); + expr(0); + setState(24); + match(ExprParser::T__6); + break; + } + + case 6: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(26); + match(ExprParser::IDENTIFIER); + setState(27); + match(ExprParser::T__5); + setState(28); + expr(0); + setState(29); + match(ExprParser::T__6); + break; + } + + case 7: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(31); + match(ExprParser::IDENTIFIER); + setState(32); + match(ExprParser::LBRACKET); + setState(33); + shift(); + setState(38); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == ExprParser::T__7) + { + setState(34); + match(ExprParser::T__7); + setState(35); + shift(); + setState(40); + _errHandler->sync(this); + _la = _input->LA(1); + } + setState(41); + match(ExprParser::RBRACKET); + break; + } + + case 8: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(43); + match(ExprParser::IDENTIFIER); + setState(44); + match(ExprParser::LBRACKET); + setState(45); + expr(0); + setState(50); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == ExprParser::T__7) + { + setState(46); + match(ExprParser::T__7); + setState(47); + expr(0); + setState(52); + _errHandler->sync(this); + _la = _input->LA(1); + } + setState(53); + match(ExprParser::RBRACKET); + break; + } + + case 9: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(55); + match(ExprParser::IDENTIFIER); + setState(56); + match(ExprParser::LBRACKET); + setState(57); + antlrcpp::downCast(_localctx)->shift1 = shift(); + setState(58); + match(ExprParser::T__8); + setState(59); + antlrcpp::downCast(_localctx)->shift2 = shift(); + setState(60); + match(ExprParser::RBRACKET); + break; + } + + case 10: + { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(62); + match(ExprParser::IDENTIFIER); + setState(63); + match(ExprParser::LBRACKET); + setState(64); + expr(0); + setState(65); + match(ExprParser::T__8); + setState(66); + expr(0); + setState(67); + match(ExprParser::RBRACKET); + break; } default: - break; - } - } - setState(84); - _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 5, _ctx); + break; + } + _ctx->stop = _input->LT(-1); + setState(82); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 5, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) + { + if (alt == 1) + { + if (!_parseListeners.empty()) + { + triggerExitRuleEvent(); + } + previousContext = _localctx; + setState(80); + _errHandler->sync(this); + switch (getInterpreter()->adaptivePredict(_input, 4, _ctx)) + { + case 1: + { + auto newContext = _tracker.createInstance( + _tracker.createInstance(parentContext, parentState)); + _localctx = newContext; + pushNewRecursionContext(newContext, startState, RuleExpr); + setState(71); + + if (!(precpred(_ctx, 12))) + { + throw FailedPredicateException(this, "precpred(_ctx, 12)"); + } + setState(72); + antlrcpp::downCast(_localctx)->op = _input->LT(1); + _la = _input->LA(1); + if (!(_la == ExprParser::T__2 + + || _la == ExprParser::T__3)) + { + antlrcpp::downCast(_localctx)->op = _errHandler + ->recoverInline(this); + } + else + { + _errHandler->reportMatch(this); + consume(); + } + setState(73); + expr(13); + break; + } + + case 2: + { + auto newContext = _tracker.createInstance( + _tracker.createInstance(parentContext, parentState)); + _localctx = newContext; + pushNewRecursionContext(newContext, startState, RuleExpr); + setState(74); + + if (!(precpred(_ctx, 11))) + { + throw FailedPredicateException(this, "precpred(_ctx, 11)"); + } + setState(75); + antlrcpp::downCast(_localctx)->op = _input->LT(1); + _la = _input->LA(1); + if (!(_la == ExprParser::T__0 + + || _la == ExprParser::T__1)) + { + antlrcpp::downCast(_localctx)->op = _errHandler + ->recoverInline(this); + } + else + { + _errHandler->reportMatch(this); + consume(); + } + setState(76); + expr(12); + break; + } + + case 3: + { + auto newContext = _tracker.createInstance( + _tracker.createInstance(parentContext, parentState)); + _localctx = newContext; + pushNewRecursionContext(newContext, startState, RuleExpr); + setState(77); + + if (!(precpred(_ctx, 10))) + { + throw FailedPredicateException(this, "precpred(_ctx, 10)"); + } + setState(78); + match(ExprParser::COMPARISON); + setState(79); + expr(11); + break; + } + + default: + break; + } + } + setState(84); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 5, _ctx); + } + } + catch (RecognitionException& e) + { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); } - } - catch (RecognitionException &e) { - _errHandler->reportError(this, e); - _localctx->exception = std::current_exception(); - _errHandler->recover(this, _localctx->exception); - } - return _localctx; + return _localctx; } -bool ExprParser::sempred(RuleContext *context, size_t ruleIndex, size_t predicateIndex) { - switch (ruleIndex) { - case 2: return exprSempred(antlrcpp::downCast(context), predicateIndex); +bool ExprParser::sempred(RuleContext* context, size_t ruleIndex, size_t predicateIndex) +{ + switch (ruleIndex) + { + case 2: + return exprSempred(antlrcpp::downCast(context), predicateIndex); - default: - break; - } - return true; + default: + break; + } + return true; } -bool ExprParser::exprSempred(ExprContext *_localctx, size_t predicateIndex) { - switch (predicateIndex) { - case 0: return precpred(_ctx, 12); - case 1: return precpred(_ctx, 11); - case 2: return precpred(_ctx, 10); +bool ExprParser::exprSempred(ExprContext* _localctx, size_t predicateIndex) +{ + switch (predicateIndex) + { + case 0: + return precpred(_ctx, 12); + case 1: + return precpred(_ctx, 11); + case 2: + return precpred(_ctx, 10); - default: - break; - } - return true; + default: + break; + } + return true; } -void ExprParser::initialize() { +void ExprParser::initialize() +{ #if ANTLR4_USE_THREAD_LOCAL_CACHE - exprParserInitialize(); + exprParserInitialize(); #else - ::antlr4::internal::call_once(exprParserOnceFlag, exprParserInitialize); + ::antlr4::internal::call_once(exprParserOnceFlag, exprParserInitialize); #endif } diff --git a/src/libs/antares/antlr-interface/ExprParser.h b/src/libs/antares/antlr-interface/ExprParser.h index aa1c8b6f09..6573ea2b2d 100644 --- a/src/libs/antares/antlr-interface/ExprParser.h +++ b/src/libs/antares/antlr-interface/ExprParser.h @@ -3,242 +3,266 @@ #pragma once - #include "antlr4-runtime.h" - - - -class ExprParser : public antlr4::Parser { +class ExprParser: public antlr4::Parser +{ public: - enum { - T__0 = 1, T__1 = 2, T__2 = 3, T__3 = 4, T__4 = 5, T__5 = 6, T__6 = 7, - T__7 = 8, T__8 = 9, NUMBER = 10, TIME = 11, IDENTIFIER = 12, COMPARISON = 13, - ADDSUB = 14, MULDIV = 15, LBRACKET = 16, RBRACKET = 17, WS = 18 - }; - - enum { - RuleFullexpr = 0, RuleShift = 1, RuleExpr = 2 - }; - - explicit ExprParser(antlr4::TokenStream *input); - - ExprParser(antlr4::TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options); - - ~ExprParser() override; - - std::string getGrammarFileName() const override; - - const antlr4::atn::ATN& getATN() const override; - - const std::vector& getRuleNames() const override; + enum + { + T__0 = 1, + T__1 = 2, + T__2 = 3, + T__3 = 4, + T__4 = 5, + T__5 = 6, + T__6 = 7, + T__7 = 8, + T__8 = 9, + NUMBER = 10, + TIME = 11, + IDENTIFIER = 12, + COMPARISON = 13, + ADDSUB = 14, + MULDIV = 15, + LBRACKET = 16, + RBRACKET = 17, + WS = 18 + }; + + enum + { + RuleFullexpr = 0, + RuleShift = 1, + RuleExpr = 2 + }; + + explicit ExprParser(antlr4::TokenStream* input); - const antlr4::dfa::Vocabulary& getVocabulary() const override; + ExprParser(antlr4::TokenStream* input, const antlr4::atn::ParserATNSimulatorOptions& options); + + ~ExprParser() override; - antlr4::atn::SerializedATNView getSerializedATN() const override; + std::string getGrammarFileName() const override; + + const antlr4::atn::ATN& getATN() const override; + const std::vector& getRuleNames() const override; + + const antlr4::dfa::Vocabulary& getVocabulary() const override; - class FullexprContext; - class ShiftContext; - class ExprContext; + antlr4::atn::SerializedATNView getSerializedATN() const override; + + class FullexprContext; + class ShiftContext; + class ExprContext; + + class FullexprContext: public antlr4::ParserRuleContext + { + public: + FullexprContext(antlr4::ParserRuleContext* parent, size_t invokingState); + virtual size_t getRuleIndex() const override; + ExprContext* expr(); + antlr4::tree::TerminalNode* EOF(); + + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; + + FullexprContext* fullexpr(); - class FullexprContext : public antlr4::ParserRuleContext { - public: - FullexprContext(antlr4::ParserRuleContext *parent, size_t invokingState); - virtual size_t getRuleIndex() const override; - ExprContext *expr(); - antlr4::tree::TerminalNode *EOF(); + class ShiftContext: public antlr4::ParserRuleContext + { + public: + antlr4::Token* op = nullptr; + ShiftContext(antlr4::ParserRuleContext* parent, size_t invokingState); + virtual size_t getRuleIndex() const override; + antlr4::tree::TerminalNode* TIME(); + ExprContext* expr(); + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - - }; + ShiftContext* shift(); - FullexprContext* fullexpr(); + class ExprContext: public antlr4::ParserRuleContext + { + public: + ExprContext(antlr4::ParserRuleContext* parent, size_t invokingState); - class ShiftContext : public antlr4::ParserRuleContext { - public: - antlr4::Token *op = nullptr; - ShiftContext(antlr4::ParserRuleContext *parent, size_t invokingState); - virtual size_t getRuleIndex() const override; - antlr4::tree::TerminalNode *TIME(); - ExprContext *expr(); + ExprContext() = default; + void copyFrom(ExprContext* context); + using antlr4::ParserRuleContext::copyFrom; + + virtual size_t getRuleIndex() const override; + }; + + class IdentifierContext: public ExprContext + { + public: + IdentifierContext(ExprContext* ctx); + + antlr4::tree::TerminalNode* IDENTIFIER(); + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; + + class NegationContext: public ExprContext + { + public: + NegationContext(ExprContext* ctx); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - - }; + ExprContext* expr(); - ShiftContext* shift(); + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class ExprContext : public antlr4::ParserRuleContext { - public: - ExprContext(antlr4::ParserRuleContext *parent, size_t invokingState); - - ExprContext() = default; - void copyFrom(ExprContext *context); - using antlr4::ParserRuleContext::copyFrom; + class ExpressionContext: public ExprContext + { + public: + ExpressionContext(ExprContext* ctx); - virtual size_t getRuleIndex() const override; + ExprContext* expr(); - - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class IdentifierContext : public ExprContext { - public: - IdentifierContext(ExprContext *ctx); + class ComparisonContext: public ExprContext + { + public: + ComparisonContext(ExprContext* ctx); - antlr4::tree::TerminalNode *IDENTIFIER(); + std::vector expr(); + ExprContext* expr(size_t i); + antlr4::tree::TerminalNode* COMPARISON(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class NegationContext : public ExprContext { - public: - NegationContext(ExprContext *ctx); + class AddsubContext: public ExprContext + { + public: + AddsubContext(ExprContext* ctx); - ExprContext *expr(); + antlr4::Token* op = nullptr; + std::vector expr(); + ExprContext* expr(size_t i); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class ExpressionContext : public ExprContext { - public: - ExpressionContext(ExprContext *ctx); + class PortFieldContext: public ExprContext + { + public: + PortFieldContext(ExprContext* ctx); - ExprContext *expr(); + std::vector IDENTIFIER(); + antlr4::tree::TerminalNode* IDENTIFIER(size_t i); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class ComparisonContext : public ExprContext { - public: - ComparisonContext(ExprContext *ctx); + class MuldivContext: public ExprContext + { + public: + MuldivContext(ExprContext* ctx); - std::vector expr(); - ExprContext* expr(size_t i); - antlr4::tree::TerminalNode *COMPARISON(); + antlr4::Token* op = nullptr; + std::vector expr(); + ExprContext* expr(size_t i); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class AddsubContext : public ExprContext { - public: - AddsubContext(ExprContext *ctx); + class NumberContext: public ExprContext + { + public: + NumberContext(ExprContext* ctx); - antlr4::Token *op = nullptr; - std::vector expr(); - ExprContext* expr(size_t i); + antlr4::tree::TerminalNode* NUMBER(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class PortFieldContext : public ExprContext { - public: - PortFieldContext(ExprContext *ctx); + class TimeIndexContext: public ExprContext + { + public: + TimeIndexContext(ExprContext* ctx); - std::vector IDENTIFIER(); - antlr4::tree::TerminalNode* IDENTIFIER(size_t i); + antlr4::tree::TerminalNode* IDENTIFIER(); + antlr4::tree::TerminalNode* LBRACKET(); + std::vector expr(); + ExprContext* expr(size_t i); + antlr4::tree::TerminalNode* RBRACKET(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class MuldivContext : public ExprContext { - public: - MuldivContext(ExprContext *ctx); + class TimeShiftContext: public ExprContext + { + public: + TimeShiftContext(ExprContext* ctx); - antlr4::Token *op = nullptr; - std::vector expr(); - ExprContext* expr(size_t i); + antlr4::tree::TerminalNode* IDENTIFIER(); + antlr4::tree::TerminalNode* LBRACKET(); + std::vector shift(); + ShiftContext* shift(size_t i); + antlr4::tree::TerminalNode* RBRACKET(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class NumberContext : public ExprContext { - public: - NumberContext(ExprContext *ctx); + class FunctionContext: public ExprContext + { + public: + FunctionContext(ExprContext* ctx); - antlr4::tree::TerminalNode *NUMBER(); + antlr4::tree::TerminalNode* IDENTIFIER(); + ExprContext* expr(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class TimeIndexContext : public ExprContext { - public: - TimeIndexContext(ExprContext *ctx); + class TimeShiftRangeContext: public ExprContext + { + public: + TimeShiftRangeContext(ExprContext* ctx); - antlr4::tree::TerminalNode *IDENTIFIER(); - antlr4::tree::TerminalNode *LBRACKET(); - std::vector expr(); - ExprContext* expr(size_t i); - antlr4::tree::TerminalNode *RBRACKET(); + ExprParser::ShiftContext* shift1 = nullptr; + ExprParser::ShiftContext* shift2 = nullptr; + antlr4::tree::TerminalNode* IDENTIFIER(); + antlr4::tree::TerminalNode* LBRACKET(); + antlr4::tree::TerminalNode* RBRACKET(); + std::vector shift(); + ShiftContext* shift(size_t i); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class TimeShiftContext : public ExprContext { - public: - TimeShiftContext(ExprContext *ctx); + class TimeRangeContext: public ExprContext + { + public: + TimeRangeContext(ExprContext* ctx); - antlr4::tree::TerminalNode *IDENTIFIER(); - antlr4::tree::TerminalNode *LBRACKET(); - std::vector shift(); - ShiftContext* shift(size_t i); - antlr4::tree::TerminalNode *RBRACKET(); + antlr4::tree::TerminalNode* IDENTIFIER(); + antlr4::tree::TerminalNode* LBRACKET(); + std::vector expr(); + ExprContext* expr(size_t i); + antlr4::tree::TerminalNode* RBRACKET(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; + }; - class FunctionContext : public ExprContext { - public: - FunctionContext(ExprContext *ctx); + ExprContext* expr(); + ExprContext* expr(int precedence); - antlr4::tree::TerminalNode *IDENTIFIER(); - ExprContext *expr(); + bool sempred(antlr4::RuleContext* _localctx, size_t ruleIndex, size_t predicateIndex) override; - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; + bool exprSempred(ExprContext* _localctx, size_t predicateIndex); - class TimeShiftRangeContext : public ExprContext { - public: - TimeShiftRangeContext(ExprContext *ctx); - - ExprParser::ShiftContext *shift1 = nullptr; - ExprParser::ShiftContext *shift2 = nullptr; - antlr4::tree::TerminalNode *IDENTIFIER(); - antlr4::tree::TerminalNode *LBRACKET(); - antlr4::tree::TerminalNode *RBRACKET(); - std::vector shift(); - ShiftContext* shift(size_t i); - - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; - - class TimeRangeContext : public ExprContext { - public: - TimeRangeContext(ExprContext *ctx); - - antlr4::tree::TerminalNode *IDENTIFIER(); - antlr4::tree::TerminalNode *LBRACKET(); - std::vector expr(); - ExprContext* expr(size_t i); - antlr4::tree::TerminalNode *RBRACKET(); - - virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; - }; - - ExprContext* expr(); - ExprContext* expr(int precedence); - - bool sempred(antlr4::RuleContext *_localctx, size_t ruleIndex, size_t predicateIndex) override; - - bool exprSempred(ExprContext *_localctx, size_t predicateIndex); - - // By default the static state used to implement the parser is lazily initialized during the first - // call to the constructor. You can call this function if you wish to initialize the static state - // ahead of time. - static void initialize(); + // By default the static state used to implement the parser is lazily initialized during the + // first call to the constructor. You can call this function if you wish to initialize the + // static state ahead of time. + static void initialize(); private: }; - diff --git a/src/libs/antares/antlr-interface/ExprVisitor.cpp b/src/libs/antares/antlr-interface/ExprVisitor.cpp index c214f0f76f..bf0de76765 100644 --- a/src/libs/antares/antlr-interface/ExprVisitor.cpp +++ b/src/libs/antares/antlr-interface/ExprVisitor.cpp @@ -1,7 +1,4 @@ // Generated from Expr.g4 by ANTLR 4.13.1 - #include "ExprVisitor.h" - - diff --git a/src/libs/antares/antlr-interface/ExprVisitor.h b/src/libs/antares/antlr-interface/ExprVisitor.h index c064d6d54a..6caed416f5 100644 --- a/src/libs/antares/antlr-interface/ExprVisitor.h +++ b/src/libs/antares/antlr-interface/ExprVisitor.h @@ -3,52 +3,46 @@ #pragma once - -#include "antlr4-runtime.h" #include "ExprParser.h" - - +#include "antlr4-runtime.h" /** * This class defines an abstract visitor for a parse tree * produced by ExprParser. */ -class ExprVisitor : public antlr4::tree::AbstractParseTreeVisitor { +class ExprVisitor: public antlr4::tree::AbstractParseTreeVisitor +{ public: + /** + * Visit parse trees produced by ExprParser. + */ + virtual std::any visitFullexpr(ExprParser::FullexprContext* context) = 0; - /** - * Visit parse trees produced by ExprParser. - */ - virtual std::any visitFullexpr(ExprParser::FullexprContext *context) = 0; + virtual std::any visitShift(ExprParser::ShiftContext* context) = 0; - virtual std::any visitShift(ExprParser::ShiftContext *context) = 0; + virtual std::any visitIdentifier(ExprParser::IdentifierContext* context) = 0; - virtual std::any visitIdentifier(ExprParser::IdentifierContext *context) = 0; + virtual std::any visitNegation(ExprParser::NegationContext* context) = 0; - virtual std::any visitNegation(ExprParser::NegationContext *context) = 0; + virtual std::any visitExpression(ExprParser::ExpressionContext* context) = 0; - virtual std::any visitExpression(ExprParser::ExpressionContext *context) = 0; + virtual std::any visitComparison(ExprParser::ComparisonContext* context) = 0; - virtual std::any visitComparison(ExprParser::ComparisonContext *context) = 0; + virtual std::any visitAddsub(ExprParser::AddsubContext* context) = 0; - virtual std::any visitAddsub(ExprParser::AddsubContext *context) = 0; + virtual std::any visitPortField(ExprParser::PortFieldContext* context) = 0; - virtual std::any visitPortField(ExprParser::PortFieldContext *context) = 0; + virtual std::any visitMuldiv(ExprParser::MuldivContext* context) = 0; - virtual std::any visitMuldiv(ExprParser::MuldivContext *context) = 0; + virtual std::any visitNumber(ExprParser::NumberContext* context) = 0; - virtual std::any visitNumber(ExprParser::NumberContext *context) = 0; + virtual std::any visitTimeIndex(ExprParser::TimeIndexContext* context) = 0; - virtual std::any visitTimeIndex(ExprParser::TimeIndexContext *context) = 0; + virtual std::any visitTimeShift(ExprParser::TimeShiftContext* context) = 0; - virtual std::any visitTimeShift(ExprParser::TimeShiftContext *context) = 0; - - virtual std::any visitFunction(ExprParser::FunctionContext *context) = 0; - - virtual std::any visitTimeShiftRange(ExprParser::TimeShiftRangeContext *context) = 0; - - virtual std::any visitTimeRange(ExprParser::TimeRangeContext *context) = 0; + virtual std::any visitFunction(ExprParser::FunctionContext* context) = 0; + virtual std::any visitTimeShiftRange(ExprParser::TimeShiftRangeContext* context) = 0; + virtual std::any visitTimeRange(ExprParser::TimeRangeContext* context) = 0; }; - diff --git a/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h b/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h index 113451410f..62352390bc 100644 --- a/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h +++ b/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h @@ -28,7 +28,6 @@ void checkOrtoolsUsage(Antares::Data::UnitCommitmentMode ucMode, bool ortoolsUsed, const std::string& solverName); - void checkStudyVersion(const AnyString& optStudyFolder); void checkSimplexRangeHydroPricing(Antares::Data::SimplexOptimization optRange, diff --git a/src/libs/antares/exception/include/antares/exception/LoadingError.hpp b/src/libs/antares/exception/include/antares/exception/LoadingError.hpp index ab1ae664d8..c79b1a791e 100644 --- a/src/libs/antares/exception/include/antares/exception/LoadingError.hpp +++ b/src/libs/antares/exception/include/antares/exception/LoadingError.hpp @@ -130,13 +130,14 @@ class InvalidSolver: public LoadingError explicit InvalidSolver(const std::string& solver, const std::string& availableSolverList); }; -class InvalidSolverSpecificParameters : public LoadingError +class InvalidSolverSpecificParameters: public LoadingError { public: - explicit InvalidSolverSpecificParameters(const std::string& solver, const std::string& specificParameters); + explicit InvalidSolverSpecificParameters(const std::string& solver, + const std::string& specificParameters); }; -class InvalidStudy : public LoadingError +class InvalidStudy: public LoadingError { public: explicit InvalidStudy(const Yuni::String& study); diff --git a/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h b/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h index 687afa12ae..7b46a95c3a 100644 --- a/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h +++ b/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h @@ -31,6 +31,7 @@ namespace Data { class Study; } + /** * @class FileTreeStudyLoader * @brief A class to load studies from the file tree. diff --git a/src/libs/antares/inifile/include/antares/inifile/inifile.hxx b/src/libs/antares/inifile/include/antares/inifile/inifile.hxx index 64785d1ece..20498c3ee2 100644 --- a/src/libs/antares/inifile/include/antares/inifile/inifile.hxx +++ b/src/libs/antares/inifile/include/antares/inifile/inifile.hxx @@ -32,7 +32,8 @@ inline bool IniFile::empty() const return not firstSection; } -inline IniFile::Section::Section(const AnyString& name): name(name) +inline IniFile::Section::Section(const AnyString& name): + name(name) { } diff --git a/src/libs/antares/inifile/inifile.cpp b/src/libs/antares/inifile/inifile.cpp index 67190a0654..8cfa6b9607 100644 --- a/src/libs/antares/inifile/inifile.cpp +++ b/src/libs/antares/inifile/inifile.cpp @@ -65,9 +65,8 @@ void IniFile::Section::saveToStream(std::ostream& stream_out, uint64_t& written) stream_out << '[' << name << "]\n"; written += 4 /* []\n\n */ + name.size(); - each([&stream_out, &written](const IniFile::Property& p) { - p.saveToStream(stream_out, written); - }); + each([&stream_out, &written](const IniFile::Property& p) + { p.saveToStream(stream_out, written); }); stream_out << '\n'; } @@ -249,7 +248,7 @@ bool IniFile::open(const fs::path& filename, bool warnings) if (std::ifstream file(filename); file.is_open()) { - if (! readStream(file)) + if (!readStream(file)) { logs.error() << "Invalid INI file : " << filename; return false; @@ -266,9 +265,8 @@ bool IniFile::open(const fs::path& filename, bool warnings) void IniFile::saveToStream(std::ostream& stream_out, uint64_t& written) const { - each([&stream_out, &written](const IniFile::Section& s) { - s.saveToStream(stream_out, written); - }); + each([&stream_out, &written](const IniFile::Section& s) + { s.saveToStream(stream_out, written); }); if (written != 0) { diff --git a/src/libs/antares/io/file.cpp b/src/libs/antares/io/file.cpp index 10bf5b30b9..8ef66b3a3d 100644 --- a/src/libs/antares/io/file.cpp +++ b/src/libs/antares/io/file.cpp @@ -27,13 +27,13 @@ #ifdef YUNI_OS_WINDOWS #include + #include #else #include #include #endif #include - #include #include diff --git a/src/libs/antares/io/include/antares/io/file.h b/src/libs/antares/io/include/antares/io/file.h index e9fd0e91dc..b401b1cece 100644 --- a/src/libs/antares/io/include/antares/io/file.h +++ b/src/libs/antares/io/include/antares/io/file.h @@ -21,10 +21,10 @@ #ifndef __LIBS_ANTARES_IO_FILE_H__ #define __LIBS_ANTARES_IO_FILE_H__ -#include - #include +#include + namespace Antares::IO { /*! diff --git a/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h b/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h index 9b4c710ed4..7d6f25373b 100644 --- a/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h +++ b/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h @@ -29,6 +29,7 @@ namespace Data { class Study; } + /** * @class IStudyLoader * @brief The IStudyLoader class is an interface for loading studies. diff --git a/src/libs/antares/study/area/area.cpp b/src/libs/antares/study/area/area.cpp index da99f973ae..fe2b2b7b75 100644 --- a/src/libs/antares/study/area/area.cpp +++ b/src/libs/antares/study/area/area.cpp @@ -52,19 +52,20 @@ Area::Area(): internalInitialize(); } -Area::Area(const AnyString& name) : Area() +Area::Area(const AnyString& name): + Area() { internalInitialize(); this->name = name; this->id = Antares::transformNameIntoID(this->name); } -Area::Area(const AnyString& name, const AnyString& id) : Area() +Area::Area(const AnyString& name, const AnyString& id): + Area() { internalInitialize(); this->name = name; this->id = Antares::transformNameIntoID(id); - } Area::~Area() diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 40da9df149..3523643328 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -142,8 +142,8 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { const std::string idprepro = std::string(from->id) + "/" + std::string(with->id); - tsGeneration.prepro = - std::make_unique(idprepro, tsGeneration.unitCount); + tsGeneration.prepro = std::make_unique(idprepro, + tsGeneration.unitCount); bool anyFileWasLoaded = false; @@ -157,10 +157,10 @@ bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { anyFileWasLoaded = true; tsGeneration.valid = tsGeneration.prepro->data.loadFromCSVFile( - filepath.string(), - Antares::Data::PreproAvailability::preproAvailabilityMax, - DAYS_PER_YEAR) - && tsGeneration.prepro->validate(); + filepath.string(), + Antares::Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && tsGeneration.prepro->validate(); } // Modulation @@ -170,7 +170,7 @@ bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { anyFileWasLoaded = true; tsGeneration.valid &= tsGeneration.modulationCapacityDirect - .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); } filepath = preproFile; @@ -179,7 +179,7 @@ bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { anyFileWasLoaded = true; tsGeneration.valid &= tsGeneration.modulationCapacityIndirect - .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); } if (anyFileWasLoaded) @@ -506,11 +506,8 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) return false; } -bool handleTSGenKey(Data::LinkTsGeneration& out, - const std::string& key, - const String& value) +bool handleTSGenKey(Data::LinkTsGeneration& out, const std::string& key, const String& value) { - if (key == "unitcount") { return value.to(out.unitCount); @@ -572,7 +569,11 @@ bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const } } // anonymous namespace -bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::path& folder, bool loadTSGen) +bool AreaLinksLoadFromFolder(Study& study, + AreaList* l, + Area* area, + const fs::path& folder, + bool loadTSGen) { // Assert assert(area); diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index f76afb5686..181159933b 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -968,8 +968,9 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, ret = hydroSeries->LoadMaxPower(area.id, buffer) && ret; } - hydroSeries->resizeTSinDeratedMode( - study.parameters.derated, studyVersion, study.usedByTheSolver); + hydroSeries->resizeTSinDeratedMode(study.parameters.derated, + studyVersion, + study.usedByTheSolver); } // Wind @@ -1278,7 +1279,7 @@ Area* AreaList::findFromPosition(const int x, const int y) const { auto lastArea = i->second; if (lastArea->ui && std::abs(lastArea->ui->x - x) < nearestDistance - && std::abs(lastArea->ui->y - y) < nearestDistance) + && std::abs(lastArea->ui->y - y) < nearestDistance) { nearestItem = lastArea; } @@ -1326,12 +1327,14 @@ void AreaListEnsureDataLoadPrepro(AreaList* l) /* Asserts */ assert(l); - l->each([](Data::Area& area) { - if (!area.load.prepro) - { - area.load.prepro = new Antares::Data::Load::Prepro(); - } - }); + l->each( + [](Data::Area& area) + { + if (!area.load.prepro) + { + area.load.prepro = new Antares::Data::Load::Prepro(); + } + }); } void AreaListEnsureDataSolarPrepro(AreaList* l) diff --git a/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp b/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp index ff181e7ed8..b29ad4fba2 100644 --- a/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp +++ b/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp @@ -60,7 +60,9 @@ bool BindingConstraintGroupRepository::buildFrom(const BindingConstraintsReposit bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const { - bool allConsistent = !std::ranges::any_of(groups_, [](const auto& group) + bool allConsistent = !std::ranges::any_of( + groups_, + [](const auto& group) { const auto& constraints = group->constraints(); if (constraints.empty()) @@ -68,7 +70,8 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const return false; } auto width = (*constraints.begin())->RHSTimeSeries().width; - bool isConsistent = std::ranges::all_of(constraints, + bool isConsistent = std::ranges::all_of( + constraints, [&width](const std::shared_ptr& bc) { bool sameWidth = bc->RHSTimeSeries().width == width; @@ -89,15 +92,16 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const void BindingConstraintGroupRepository::resizeAllTimeseriesNumbers(unsigned int nb_years) { - std::ranges::for_each(groups_, [&nb_years](auto& group) - { group->timeseriesNumbers.reset(nb_years); }); + std::ranges::for_each(groups_, + [&nb_years](auto& group) { group->timeseriesNumbers.reset(nb_years); }); } BindingConstraintGroup* BindingConstraintGroupRepository::operator[](const std::string& name) const { - if (auto group = std::ranges::find_if(groups_, [&name](auto& group_of_constraint) - { return group_of_constraint->name() == name; }); - group != groups_.end()) + if (auto group = std::ranges::find_if(groups_, + [&name](auto& group_of_constraint) + { return group_of_constraint->name() == name; }); + group != groups_.end()) { return group->get(); } diff --git a/src/libs/antares/study/cleaner/cleaner-v20.cpp b/src/libs/antares/study/cleaner/cleaner-v20.cpp index 7d1aadf58e..3fa46cf4b5 100644 --- a/src/libs/antares/study/cleaner/cleaner-v20.cpp +++ b/src/libs/antares/study/cleaner/cleaner-v20.cpp @@ -391,7 +391,6 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) buffer.clear() << infos->folder << "/input/bindingconstraints/bindingconstraints.ini"; if (ini.open(buffer)) { - ini.each( [&e](const IniFile::Section& section) { diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index 791e20f865..1eacc026bb 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -504,8 +504,7 @@ class Parameters final private: //! Load data from an INI file - bool loadFromINI(const IniFile& ini, - const StudyVersion& version); + bool loadFromINI(const IniFile& ini, const StudyVersion& version); void resetPlayedYears(uint nbOfYears); diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index e09970b79c..9d80ce4369 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -22,6 +22,7 @@ #define __ANTARES_LIBS_STUDY_PARTS_HYDRO_CONTAINER_H__ #include + #include "../../fwd.h" #include "allocation.h" #include "prepro.h" @@ -178,9 +179,7 @@ class PartHydro // As this function can be called a lot of times, we pass working variables and returned variables // as arguments, so that we don't have to create them locally (as in a classical function) each // time. -double getWaterValue(const double& level, - const Matrix& waterValues, - const uint day); +double getWaterValue(const double& level, const Matrix& waterValues, const uint day); // Interpolates a rate from the credit modulation table according to a level double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */, diff --git a/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h index 42aff6336a..b5cb21073d 100644 --- a/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h +++ b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h @@ -21,9 +21,10 @@ #ifndef __LIBS_STUDY_SCENARIO_BUILDER_DATA_HYDRO_LEVELS_H__ #define __LIBS_STUDY_SCENARIO_BUILDER_DATA_HYDRO_LEVELS_H__ -#include "scBuilderDataInterface.h" #include +#include "scBuilderDataInterface.h" + namespace Antares { namespace Data diff --git a/src/libs/antares/study/include/antares/study/sets.hxx b/src/libs/antares/study/include/antares/study/sets.hxx index d2976252cc..df1f9cff93 100644 --- a/src/libs/antares/study/include/antares/study/sets.hxx +++ b/src/libs/antares/study/include/antares/study/sets.hxx @@ -288,8 +288,8 @@ bool Sets::loadFromFile(const std::filesystem::path& filename) continue; } - logs.warning() << "sets: `" << filename << "`: Invalid property `" - << p->key << '\''; + logs.warning() << "sets: `" << filename << "`: Invalid property `" << p->key + << '\''; } // Add the new group diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index 7337b9c8b0..2f4c0b30b1 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -1109,10 +1109,16 @@ static bool SGDIntLoadFamily_Legacy(Parameters& d, if (key == "initial-reservoir-levels") // ignored since 9.2 { - if (version >= StudyVersion(9,2)) - logs.warning() << "Option initial-reservoir-levels is deprecated, please remove it from the study"; + if (version >= StudyVersion(9, 2)) + { + logs.warning() + << "Option initial-reservoir-levels is deprecated, please remove it from the study"; + } else if (value == "hot start") - logs.warning() << "Hydro hot start not supported with this solver, please use a version < 9.2"; + { + logs.warning() + << "Hydro hot start not supported with this solver, please use a version < 9.2"; + } return true; } @@ -1125,8 +1131,7 @@ bool firstKeyLetterIsValid(const String& name) return (firstLetter >= 'a' && firstLetter <= 'z'); } -bool Parameters::loadFromINI(const IniFile& ini, - const StudyVersion& version) +bool Parameters::loadFromINI(const IniFile& ini, const StudyVersion& version) { // Reset inner data reset(); @@ -1292,7 +1297,9 @@ void Parameters::fixBadValues() } if (simulationDays.first == 0) + { simulationDays.first = 1; + } else { simulationDays.first = std::clamp(simulationDays.first, 1u, 365u); diff --git a/src/libs/antares/study/parts/common/cluster_list.cpp b/src/libs/antares/study/parts/common/cluster_list.cpp index 9be5c2ca57..9c39ca7c8b 100644 --- a/src/libs/antares/study/parts/common/cluster_list.cpp +++ b/src/libs/antares/study/parts/common/cluster_list.cpp @@ -263,8 +263,9 @@ bool ClusterList::saveDataSeriesToFolder(const AnyString& folder) cons template bool ClusterList::loadDataSeriesFromFolder(Study& s, const AnyString& folder) { - return std::ranges::all_of(allClusters_, [&s, &folder](auto c) - { return c->loadDataSeriesFromFolder(s, folder); }); + return std::ranges::all_of(allClusters_, + [&s, &folder](auto c) + { return c->loadDataSeriesFromFolder(s, folder); }); } template diff --git a/src/libs/antares/study/parts/hydro/allocation.cpp b/src/libs/antares/study/parts/hydro/allocation.cpp index 597264cf20..052bc3411d 100644 --- a/src/libs/antares/study/parts/hydro/allocation.cpp +++ b/src/libs/antares/study/parts/hydro/allocation.cpp @@ -164,8 +164,7 @@ void HydroAllocation::clear() #endif } -bool HydroAllocation::loadFromFile(const AreaName& referencearea, - const fs::path& filename) +bool HydroAllocation::loadFromFile(const AreaName& referencearea, const fs::path& filename) { clear(); @@ -177,21 +176,24 @@ bool HydroAllocation::loadFromFile(const AreaName& referencearea, } if (ini.empty()) + { return true; + } - ini.each([this](const IniFile::Section& section) - { - for (auto* p = section.firstProperty; p; p = p->next) - { - double coeff = p->value.to(); - if (!Utils::isZero(coeff)) - { - AreaName areaname = p->key; - areaname.toLower(); - pValues[areaname] = coeff; - } - } - }); + ini.each( + [this](const IniFile::Section& section) + { + for (auto* p = section.firstProperty; p; p = p->next) + { + double coeff = p->value.to(); + if (!Utils::isZero(coeff)) + { + AreaName areaname = p->key; + areaname.toLower(); + pValues[areaname] = coeff; + } + } + }); return true; } diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index c9dc476de5..e98d94bee4 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -32,7 +32,7 @@ using namespace Yuni; namespace Antares::Data { -PartHydro::PartHydro(const Data::Area& area) : +PartHydro::PartHydro(const Data::Area& area): interDailyBreakdown(0.), intraDailyModulation(2.), intermonthlyBreakdown(0), @@ -113,7 +113,9 @@ static bool loadProperties(Study& study, T PartHydro::*ptr) { if (!property) + { return false; + } bool ret = true; @@ -242,52 +244,74 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if (IniFile::Section* section = ini.find("inter-daily-breakdown")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::interDailyBreakdown) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::interDailyBreakdown) + && ret; } if (IniFile::Section* section = ini.find("intra-daily-modulation")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::intraDailyModulation) && ret; + ret = loadProperties(study, + section->firstProperty, + buffer, + &PartHydro::intraDailyModulation) + && ret; } if (IniFile::Section* section = ini.find("reservoir")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirManagement) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirManagement) + && ret; } if (IniFile::Section* section = ini.find("reservoir capacity")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirCapacity) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirCapacity) + && ret; } if (IniFile::Section* section = ini.find("follow load")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::followLoadModulations) && ret; + ret = loadProperties(study, + section->firstProperty, + buffer, + &PartHydro::followLoadModulations) + && ret; } if (IniFile::Section* section = ini.find("use water")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useWaterValue) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useWaterValue) + && ret; } if (IniFile::Section* section = ini.find("hard bounds")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::hardBoundsOnRuleCurves) && ret; + ret = loadProperties(study, + section->firstProperty, + buffer, + &PartHydro::hardBoundsOnRuleCurves) + && ret; } if (IniFile::Section* section = ini.find("use heuristic")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useHeuristicTarget) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useHeuristicTarget) + && ret; } if (IniFile::Section* section = ini.find("power to level")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::powerToLevel) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::powerToLevel) + && ret; } if (IniFile::Section* section = ini.find("initialize reservoir date")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::initializeReservoirLevelDate) && ret; + ret = loadProperties(study, + section->firstProperty, + buffer, + &PartHydro::initializeReservoirLevelDate) + && ret; } if (IniFile::Section* section = ini.find("use leeway")) @@ -297,17 +321,20 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if (IniFile::Section* section = ini.find("leeway low")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayLowerBound) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayLowerBound) + && ret; } if (IniFile::Section* section = ini.find("leeway up")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayUpperBound) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayUpperBound) + && ret; } if (IniFile::Section* section = ini.find("pumping efficiency")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) + && ret; } return ret; @@ -317,10 +344,12 @@ bool PartHydro::checkReservoirLevels(const Study& study) { bool ret = true; - for (const auto& [areaName, area] : study.areas) + for (const auto& [areaName, area]: study.areas) { if (!study.usedByTheSolver) + { return true; + } auto& col = area->hydro.inflowPattern[0]; bool errorInflow = false; @@ -340,8 +369,8 @@ bool PartHydro::checkReservoirLevels(const Study& study) for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) { if (!errorLevels - && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] - || colAvg[day] > 100 || colMax[day] > 100)) + && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] + || colAvg[day] > 100 || colMax[day] > 100)) { logs.error() << areaName << ": invalid reservoir level value"; errorLevels = true; @@ -352,7 +381,7 @@ bool PartHydro::checkReservoirLevels(const Study& study) for (int i = 0; i < 101; i++) { if ((area->hydro.creditModulation[i][0] < 0) - || (area->hydro.creditModulation[i][1] < 0)) + || (area->hydro.creditModulation[i][1] < 0)) { logs.error() << areaName << ": invalid credit modulation value"; ret = false; @@ -372,75 +401,73 @@ bool PartHydro::checkProperties(Study& study) // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and // capacity = 0 because of further division by capacity. reservoir management = no and capacity // = 0 is possible (no use of capacity further) - study.areas.each([&ret](Data::Area& area) - { - if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) - { - logs.error() << area.name - << ": reservoir capacity not defined. Impossible to manage."; - ret = false; - } + study.areas.each( + [&ret](Data::Area& area) + { + if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) + { + logs.error() << area.name + << ": reservoir capacity not defined. Impossible to manage."; + ret = false; + } - if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) - { - logs.error() << area.name - << " : use water value = no conflicts with use heuristic target = no"; - ret = false; - } + if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) + { + logs.error() << area.name + << " : use water value = no conflicts with use heuristic target = no"; + ret = false; + } - if (area.hydro.intraDailyModulation < 1.) - { - logs.error() - << area.id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " - << area.hydro.intraDailyModulation << " (truncated to 1)"; - area.hydro.intraDailyModulation = 1.; - } + if (area.hydro.intraDailyModulation < 1.) + { + logs.error() << area.id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " + << area.hydro.intraDailyModulation << " (truncated to 1)"; + area.hydro.intraDailyModulation = 1.; + } - if (area.hydro.reservoirCapacity < 0) - { - logs.error() << area.id << ": Invalid reservoir capacity."; - area.hydro.reservoirCapacity = 0.; - } + if (area.hydro.reservoirCapacity < 0) + { + logs.error() << area.id << ": Invalid reservoir capacity."; + area.hydro.reservoirCapacity = 0.; + } - if (area.hydro.intermonthlyBreakdown < 0) - { - logs.error() << area.id << ": Invalid intermonthly breakdown"; - area.hydro.intermonthlyBreakdown = 0.; - } + if (area.hydro.intermonthlyBreakdown < 0) + { + logs.error() << area.id << ": Invalid intermonthly breakdown"; + area.hydro.intermonthlyBreakdown = 0.; + } - if (area.hydro.initializeReservoirLevelDate < 0) - { - logs.error() << area.id << ": Invalid initialize reservoir date"; - area.hydro.initializeReservoirLevelDate = 0; - } + if (area.hydro.initializeReservoirLevelDate < 0) + { + logs.error() << area.id << ": Invalid initialize reservoir date"; + area.hydro.initializeReservoirLevelDate = 0; + } - if (area.hydro.leewayLowerBound < 0.) - { - logs.error() - << area.id << ": Invalid leeway lower bound. It must be >= 0.0, Got " - << area.hydro.leewayLowerBound; - area.hydro.leewayLowerBound = 0.; - } + if (area.hydro.leewayLowerBound < 0.) + { + logs.error() << area.id << ": Invalid leeway lower bound. It must be >= 0.0, Got " + << area.hydro.leewayLowerBound; + area.hydro.leewayLowerBound = 0.; + } - if (area.hydro.leewayUpperBound < 0.) - { - logs.error() - << area.id << ": Invalid leeway upper bound. It must be >= 0.0, Got " - << area.hydro.leewayUpperBound; - area.hydro.leewayUpperBound = 0.; - } + if (area.hydro.leewayUpperBound < 0.) + { + logs.error() << area.id << ": Invalid leeway upper bound. It must be >= 0.0, Got " + << area.hydro.leewayUpperBound; + area.hydro.leewayUpperBound = 0.; + } - if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) - { + if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) + { logs.error() << area.id << ": Leeway lower bound greater than leeway upper bound."; - } + } - if (area.hydro.pumpingEfficiency < 0) - { - logs.error() << area.id << ": Invalid pumping efficiency"; - area.hydro.pumpingEfficiency = 0.; - } - }); + if (area.hydro.pumpingEfficiency < 0) + { + logs.error() << area.id << ": Invalid pumping efficiency"; + area.hydro.pumpingEfficiency = 0.; + } + }); return ret; } @@ -465,40 +492,40 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) struct AllSections { - IniFile::Section* s; - IniFile::Section* smod; - IniFile::Section* sIMB; - IniFile::Section* sreservoir; - IniFile::Section* sreservoirCapacity; - IniFile::Section* sFollowLoad; - IniFile::Section* sUseWater; - IniFile::Section* sHardBounds; - IniFile::Section* sInitializeReservoirDate; - IniFile::Section* sUseHeuristic; - IniFile::Section* sUseLeeway; - IniFile::Section* sPowerToLevel; - IniFile::Section* sLeewayLow; - IniFile::Section* sLeewayUp; - IniFile::Section* spumpingEfficiency; - - AllSections(IniFile& ini) : - s(ini.addSection("inter-daily-breakdown")), - smod(ini.addSection("intra-daily-modulation")), - sIMB(ini.addSection("inter-monthly-breakdown")), - sreservoir(ini.addSection("reservoir")), - sreservoirCapacity(ini.addSection("reservoir capacity")), - sFollowLoad(ini.addSection("follow load")), - sUseWater(ini.addSection("use water")), - sHardBounds(ini.addSection("hard bounds")), - sInitializeReservoirDate(ini.addSection("initialize reservoir date")), - sUseHeuristic(ini.addSection("use heuristic")), - sUseLeeway(ini.addSection("use leeway")), - sPowerToLevel(ini.addSection("power to level")), - sLeewayLow(ini.addSection("leeway low")), - sLeewayUp(ini.addSection("leeway up")), - spumpingEfficiency(ini.addSection("pumping efficiency")) + IniFile::Section* s; + IniFile::Section* smod; + IniFile::Section* sIMB; + IniFile::Section* sreservoir; + IniFile::Section* sreservoirCapacity; + IniFile::Section* sFollowLoad; + IniFile::Section* sUseWater; + IniFile::Section* sHardBounds; + IniFile::Section* sInitializeReservoirDate; + IniFile::Section* sUseHeuristic; + IniFile::Section* sUseLeeway; + IniFile::Section* sPowerToLevel; + IniFile::Section* sLeewayLow; + IniFile::Section* sLeewayUp; + IniFile::Section* spumpingEfficiency; + + AllSections(IniFile& ini): + s(ini.addSection("inter-daily-breakdown")), + smod(ini.addSection("intra-daily-modulation")), + sIMB(ini.addSection("inter-monthly-breakdown")), + sreservoir(ini.addSection("reservoir")), + sreservoirCapacity(ini.addSection("reservoir capacity")), + sFollowLoad(ini.addSection("follow load")), + sUseWater(ini.addSection("use water")), + sHardBounds(ini.addSection("hard bounds")), + sInitializeReservoirDate(ini.addSection("initialize reservoir date")), + sUseHeuristic(ini.addSection("use heuristic")), + sUseLeeway(ini.addSection("use leeway")), + sPowerToLevel(ini.addSection("power to level")), + sLeewayLow(ini.addSection("leeway low")), + sLeewayUp(ini.addSection("leeway up")), + spumpingEfficiency(ini.addSection("pumping efficiency")) { - } + } }; // Init @@ -515,7 +542,8 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) allSections.s->add(area.id, area.hydro.interDailyBreakdown); allSections.smod->add(area.id, area.hydro.intraDailyModulation); allSections.sIMB->add(area.id, area.hydro.intermonthlyBreakdown); - allSections.sInitializeReservoirDate->add(area.id, area.hydro.initializeReservoirLevelDate); + allSections.sInitializeReservoirDate->add(area.id, + area.hydro.initializeReservoirLevelDate); allSections.sLeewayLow->add(area.id, area.hydro.leewayLowerBound); allSections.sLeewayUp->add(area.id, area.hydro.leewayUpperBound); allSections.spumpingEfficiency->add(area.id, area.hydro.pumpingEfficiency); @@ -740,8 +768,8 @@ bool PartHydro::CheckDailyMaxEnergy(const AnyString& areaName) } double getWaterValue(const double& level /* format : in % of reservoir capacity */, - const Matrix& waterValues, - const uint day) + const Matrix& waterValues, + const uint day) { assert((level >= 0. && level <= 100.) && "getWaterValue function : invalid level"); double levelUp = ceil(level); @@ -752,7 +780,7 @@ double getWaterValue(const double& level /* format : in % of reservoir capacity return waterValues[(int)(levelUp)][day]; } return waterValues[(int)(levelUp)][day] * (level - levelDown) - + waterValues[(int)(levelDown)][day] * (levelUp - level); + + waterValues[(int)(levelDown)][day] * (levelUp - level); } double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */, diff --git a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp index 2229f75f97..5aa233fedb 100644 --- a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp +++ b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp @@ -37,8 +37,8 @@ FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, double finalLevel, const unsigned int year, const unsigned int lastSimulationDay, - const unsigned int firstMonthOfSimulation) - : hydro_(hydro), + const unsigned int firstMonthOfSimulation): + hydro_(hydro), areaName_(areaName), areaIndex_(areaIndex), initialLevel_(initialLevel), @@ -52,36 +52,46 @@ FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, bool FinalLevelValidator::check() { if (skippingFinalLevelUse()) + { return true; - if (! checkForInfeasibility()) + } + if (!checkForInfeasibility()) + { return false; + } finalLevelFineForUse_ = true; return true; } bool FinalLevelValidator::skippingFinalLevelUse() { - if(! wasSetInScenarioBuilder()) + if (!wasSetInScenarioBuilder()) + { return true; - if (! compatibleWithReservoirProperties()) + } + if (!compatibleWithReservoirProperties()) + { return true; + } return false; } bool FinalLevelValidator::wasSetInScenarioBuilder() { - return ! isnan(finalLevel_); + return !isnan(finalLevel_); } bool FinalLevelValidator::compatibleWithReservoirProperties() { if (hydro_.reservoirManagement && !hydro_.useWaterValue) + { return true; + } - logs.warning() << "Final reservoir level not applicable! Year:" << year_ + 1 - << ", Area:" << areaName_ - << ". Check: Reservoir management = Yes, Use water values = No and proper initial " - "reservoir level is provided "; + logs.warning() + << "Final reservoir level not applicable! Year:" << year_ + 1 << ", Area:" << areaName_ + << ". Check: Reservoir management = Yes, Use water values = No and proper initial " + "reservoir level is provided "; return false; } @@ -98,10 +108,12 @@ bool FinalLevelValidator::hydroAllocationStartMatchesSimulation() const { int initReservoirLvlMonth = hydro_.initializeReservoirLevelDate; // month [0-11] if (lastSimulationDay_ == DAYS_PER_YEAR && initReservoirLvlMonth == firstMonthOfSimulation_) + { return true; + } - logs.error() << "Year " << year_ + 1 << ", area '" << areaName_ << "' : " - << "Hydro allocation must start on the 1st simulation month and " + logs.error() << "Year " << year_ + 1 << ", area '" << areaName_ + << "' : " << "Hydro allocation must start on the 1st simulation month and " << "simulation last a whole year"; return false; } @@ -115,8 +127,8 @@ bool FinalLevelValidator::isFinalLevelReachable() const { logs.error() << "Year: " << year_ + 1 << ". Area: " << areaName_ << ". Incompatible total inflows: " << totalYearInflows - << " with initial: " << initialLevel_ - << " and final: " << finalLevel_ << " reservoir levels."; + << " with initial: " << initialLevel_ << " and final: " << finalLevel_ + << " reservoir levels."; return false; } return true; @@ -125,17 +137,19 @@ bool FinalLevelValidator::isFinalLevelReachable() const double FinalLevelValidator::calculateTotalInflows() const { // calculate yearly inflows - auto const& srcinflows = hydro_.series->storage.getColumn(year_); + const auto& srcinflows = hydro_.series->storage.getColumn(year_); double totalYearInflows = 0.0; for (unsigned int day = 0; day < DAYS_PER_YEAR; ++day) + { totalYearInflows += srcinflows[day]; + } return totalYearInflows; } bool FinalLevelValidator::isBetweenRuleCurves() const { - double lowLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::minimum][DAYS_PER_YEAR - 1]; + double lowLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::minimum][DAYS_PER_YEAR - 1]; double highLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::maximum][DAYS_PER_YEAR - 1]; if (finalLevel_ < lowLevelLastDay || finalLevel_ > highLevelLastDay) diff --git a/src/libs/antares/study/parts/hydro/prepro.cpp b/src/libs/antares/study/parts/hydro/prepro.cpp index 9370c562fa..13711759f4 100644 --- a/src/libs/antares/study/parts/hydro/prepro.cpp +++ b/src/libs/antares/study/parts/hydro/prepro.cpp @@ -151,6 +151,7 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::st { mtrxOption = Matrix<>::optFixedSize | Matrix<>::optImmediate, }; + constexpr int maxNbOfLineToLoad = 12; data.resize(hydroPreproMax, 12, true); @@ -160,7 +161,8 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::st bool ret = PreproHydroLoadSettings(this, buffer); buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; - ret = data.loadFromCSVFile(buffer, hydroPreproMax, maxNbOfLineToLoad, mtrxOption, &s.dataBuffer) && ret; + ret = data.loadFromCSVFile(buffer, hydroPreproMax, maxNbOfLineToLoad, mtrxOption, &s.dataBuffer) + && ret; return ret; } @@ -203,8 +205,8 @@ bool PreproHydro::validate(const std::string& areaID) { ret = false; logs.error() << "Hydro: Prepro: `" << areaID - << "`: minimum energy: At least one value is negative (line: " - << (i + 1) << ')'; + << "`: minimum energy: At least one value is negative (line: " << (i + 1) + << ')'; continue; } if (colMin[i] > colMax[i]) diff --git a/src/libs/antares/study/parts/hydro/series.cpp b/src/libs/antares/study/parts/hydro/series.cpp index 3eda6d5fc3..8c73772565 100644 --- a/src/libs/antares/study/parts/hydro/series.cpp +++ b/src/libs/antares/study/parts/hydro/series.cpp @@ -54,7 +54,7 @@ static void ConvertDailyTSintoHourlyTS(const Matrix::ColumnType& dailyCo { uint hour = 0; uint day = 0; - + while (hour < HOURS_PER_YEAR && day < DAYS_PER_YEAR) { for (uint i = 0; i < HOURS_PER_DAY; ++i) diff --git a/src/libs/antares/study/parts/renewable/cluster_list.cpp b/src/libs/antares/study/parts/renewable/cluster_list.cpp index 62db61a900..aa1c915a75 100644 --- a/src/libs/antares/study/parts/renewable/cluster_list.cpp +++ b/src/libs/antares/study/parts/renewable/cluster_list.cpp @@ -223,7 +223,7 @@ bool RenewableClusterList::loadFromFolder(const AnyString& folder, Area* area) bool RenewableClusterList::validateClusters() const { bool ret = true; - for (const auto& cluster : allClusters_) + for (const auto& cluster: allClusters_) { ret = cluster->integrityCheck() && ret; } diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 749613a14b..9a27233064 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -37,8 +37,7 @@ namespace Antares::Data::ShortTermStorage { bool STStorageInput::validate() const { - return std::ranges::all_of(storagesByIndex, [](auto& cluster) - { return cluster.validate(); }); + return std::ranges::all_of(storagesByIndex, [](auto& cluster) { return cluster.validate(); }); } bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) @@ -68,8 +67,9 @@ bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) storagesByIndex.push_back(cluster); } - std::ranges::sort(storagesByIndex, [](const auto& a, const auto& b) - { return a.properties.name < b.properties.name; }); + std::ranges::sort(storagesByIndex, + [](const auto& a, const auto& b) + { return a.properties.name < b.properties.name; }); return true; } @@ -100,8 +100,8 @@ bool STStorageInput::saveToFolder(const std::string& folder) const IniFile ini; logs.debug() << "saving file " << pathIni; - std::ranges::for_each(storagesByIndex, [&ini](auto& storage) - { return storage.saveProperties(ini); }); + std::ranges::for_each(storagesByIndex, + [&ini](auto& storage) { return storage.saveProperties(ini); }); return ini.save(pathIni); } @@ -109,20 +109,20 @@ bool STStorageInput::saveToFolder(const std::string& folder) const bool STStorageInput::saveDataSeriesToFolder(const std::string& folder) const { Yuni::IO::Directory::Create(folder); - return std::ranges::all_of(storagesByIndex, [&folder](auto& storage) - { return storage.saveSeries(folder + SEP + storage.id); }); + return std::ranges::all_of(storagesByIndex, + [&folder](auto& storage) + { return storage.saveSeries(folder + SEP + storage.id); }); } std::size_t STStorageInput::count() const { - return std::ranges::count_if(storagesByIndex, [](const STStorageCluster& st) - { return st.properties.enabled; }); + return std::ranges::count_if(storagesByIndex, + [](const STStorageCluster& st) { return st.properties.enabled; }); } uint STStorageInput::removeDisabledClusters() { - return std::erase_if(storagesByIndex, [](const auto& c) - { return !c.enabled(); }); + return std::erase_if(storagesByIndex, [](const auto& c) { return !c.enabled(); }); } } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/parts/thermal/cluster_list.cpp b/src/libs/antares/study/parts/thermal/cluster_list.cpp index 4bf2e042c2..8435870d0a 100644 --- a/src/libs/antares/study/parts/thermal/cluster_list.cpp +++ b/src/libs/antares/study/parts/thermal/cluster_list.cpp @@ -162,7 +162,8 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A ret = cluster->modulation.loadFromCSVFile(modulationFile, thermalModulationMax, HOURS_PER_YEAR, - options) && ret; + options) + && ret; // Check the data integrity of the cluster addToCompleteList(cluster); @@ -174,12 +175,11 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A return ret; } - bool ThermalClusterList::validateClusters(const Parameters& parameters) const { bool ret = true; - for (const auto& cluster : allClusters_) + for (const auto& cluster: allClusters_) { cluster->minUpTime = std::clamp(cluster->minUpTime, 1u, 168u); cluster->minDownTime = std::clamp(cluster->minDownTime, 1u, 168u); @@ -206,7 +206,6 @@ bool ThermalClusterList::validateClusters(const Parameters& parameters) const cluster->nominalCapacityWithSpinning = cluster->nominalCapacity; ret = cluster->integrityCheck() && ret; - } return ret; @@ -377,7 +376,7 @@ void ThermalClusterList::reverseCalculationOfSpinning() void ThermalClusterList::enableMustrunForEveryone() { - for (const auto& c : allClusters_) + for (const auto& c: allClusters_) { c->mustrun = true; } @@ -541,7 +540,6 @@ bool ThermalClusterList::saveToFolder(const AnyString& folder) const { ret = false; } - } // Write the ini file @@ -598,27 +596,32 @@ bool ThermalClusterList::loadPreproFromFolder(Study& study, const AnyString& fol return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), loadPrepro); } -bool ThermalClusterList::validatePrepro(const Study& study) { +bool ThermalClusterList::validatePrepro(const Study& study) +{ auto hasPrepro = [](auto c) { return (bool)c->prepro; }; - const bool globalThermalTSgeneration = - study.parameters.timeSeriesToGenerate & timeSeriesThermal; + const bool globalThermalTSgeneration = study.parameters.timeSeriesToGenerate + & timeSeriesThermal; if (!study.usedByTheSolver) + { return true; + } - return std::ranges::all_of( - allClusters_ | std::views::filter(hasPrepro), - [&globalThermalTSgeneration](auto& c) { - if (globalThermalTSgeneration && !c->prepro->validate()) { - return false; - } - - if (c->doWeGenerateTS(globalThermalTSgeneration)) { - return c->prepro->normalizeAndCheckNPO(); - } - return true; - }); + return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), + [&globalThermalTSgeneration](auto& c) + { + if (globalThermalTSgeneration && !c->prepro->validate()) + { + return false; + } + + if (c->doWeGenerateTS(globalThermalTSgeneration)) + { + return c->prepro->normalizeAndCheckNPO(); + } + return true; + }); } bool ThermalClusterList::loadEconomicCosts(Study& study, const AnyString& folder) diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index 035faf86ac..c094450243 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -213,8 +213,7 @@ void StudyRuntimeInfos::initializeRangeLimits(const Study& study, StudyRangeLimi } else { - simulationDaysPerMonth[ca.month] = study.calendar.months[ca.month].days - - ca.dayMonth; + simulationDaysPerMonth[ca.month] = study.calendar.months[ca.month].days - ca.dayMonth; simulationDaysPerMonth[cb.month] = cb.dayMonth + 1; for (uint i = ca.month + 1; i < cb.month; ++i) { @@ -441,7 +440,8 @@ void StudyRangeLimits::checkIntegrity() const void StudyRuntimeInfos::disableAllFilters(Study& study) { - study.areas.each([](Data::Area& area) + study.areas.each( + [](Data::Area& area) { area.filterSynthesis = filterAll; area.filterYearByYear = filterAll; diff --git a/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp b/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp index 46a0694a58..5ffef13e98 100644 --- a/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp +++ b/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp @@ -81,11 +81,11 @@ bool BindingConstraintsTSNumberData::reset(const Study& study) { const uint nbYears = study.parameters.nbYears; std::ranges::for_each(study.bindingConstraintsGroups, - [this, &nbYears](const auto& group) - { - auto& ts_numbers = rules_[group->name()]; - ts_numbers.reset(1, nbYears); - }); + [this, &nbYears](const auto& group) + { + auto& ts_numbers = rules_[group->name()]; + ts_numbers.reset(1, nbYears); + }); return true; } diff --git a/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp b/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp index 3295df4503..8d0575b96a 100644 --- a/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp +++ b/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp @@ -29,9 +29,9 @@ namespace Antares::Data::ScenarioBuilder { hydroLevelsData::hydroLevelsData(const std::string& iniFilePrefix, - std::function applyToTarget) : - addToPrefix_(iniFilePrefix), - applyToTarget_(applyToTarget) + std::function applyToTarget): + addToPrefix_(iniFilePrefix), + applyToTarget_(applyToTarget) { } diff --git a/src/libs/antares/study/scenario-builder/rules.cpp b/src/libs/antares/study/scenario-builder/rules.cpp index fd79f07f7c..2037eede6b 100644 --- a/src/libs/antares/study/scenario-builder/rules.cpp +++ b/src/libs/antares/study/scenario-builder/rules.cpp @@ -288,7 +288,9 @@ bool Rules::readFinalHydroLevels(const AreaName::Vector& splitKey, String value, const Data::Area* area = getArea(areaname, updaterMode); if (!area) + { return false; + } double finalLevel = fromStringToHydroLevel(value, 1.); hydroFinalLevels.setTSnumber(area->index, year, finalLevel); @@ -450,8 +452,7 @@ bool Rules::apply() void Rules::sendWarningsForDisabledClusters() { - for (auto it = disabledClustersOnRuleActive.begin(); - it != disabledClustersOnRuleActive.end(); + for (auto it = disabledClustersOnRuleActive.begin(); it != disabledClustersOnRuleActive.end(); it++) { std::vector& scenariiForCurrentCluster = it->second; diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 511e61a592..5b1dde8c5f 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -856,7 +856,8 @@ void Study::areaDelete(Area::Vector& arealist) << area.name; // Updating all hydro allocation - areas.each([&area](Data::Area& areait) { areait.hydro.allocation.remove(area.id); }); + areas.each([&area](Data::Area& areait) + { areait.hydro.allocation.remove(area.id); }); // Remove all binding constraints attached to the area bindingConstraints.remove(*i); @@ -956,7 +957,7 @@ bool Study::areaRename(Area* area, AreaName newName) // Updating all hydro allocation areas.each([&oldid, &newid](Data::Area& areait) - { areait.hydro.allocation.rename(oldid, newid); }); + { areait.hydro.allocation.rename(oldid, newid); }); ScenarioBuilderUpdater updaterSB(*this); bool ret = true; @@ -1109,13 +1110,14 @@ void Study::destroyAllWindTSGeneratorData() void Study::destroyAllThermalTSGeneratorData() { - areas.each([](const Data::Area& area) - { - for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) - { - FreeAndNil(cluster->prepro); - } - }); + areas.each( + [](const Data::Area& area) + { + for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) + { + FreeAndNil(cluster->prepro); + } + }); } void Study::ensureDataAreLoadedForAllBindingConstraints() @@ -1358,7 +1360,6 @@ bool Study::checkForFilenameLimits(bool output, const String& chfolder) const areas.each( [&output, &linkname, &areaname](const Area& area) { - if (areaname.size() < area.id.size()) { areaname = area.id; diff --git a/src/libs/antares/study/study.importprepro.cpp b/src/libs/antares/study/study.importprepro.cpp index 3b8263eadf..f7c8082050 100644 --- a/src/libs/antares/study/study.importprepro.cpp +++ b/src/libs/antares/study/study.importprepro.cpp @@ -50,7 +50,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesLoad)) { logs.info() << "Importing load timeseries..."; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { logs.info() << "Importing load timeseries : " << areaName; buffer.clear() << folderInput << SEP << "load" << SEP << "series"; @@ -63,7 +63,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesSolar)) { logs.info() << "Importing solar timeseries..."; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { logs.info() << "Importing solar timeseries : " << areaName; buffer.clear() << folderInput << SEP << "solar" << SEP << "series"; @@ -76,7 +76,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesHydro)) { logs.info() << "Importing hydro timeseries..."; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { logs.info() << "Importing hydro timeseries : " << areaName; buffer.clear() << folderInput << SEP << "hydro" << SEP << "series"; @@ -89,7 +89,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesWind)) { logs.info() << "Importing wind timeseries..."; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { logs.info() << "Importing wind timeseries : " << areaName; buffer.clear() << folderInput << SEP << "wind" << SEP << "series"; @@ -104,7 +104,7 @@ bool Study::importTimeseriesIntoInput() logs.info() << "Importing thermal timeseries..."; String msg; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { msg.clear() << "Importing thermal timeseries : " << areaName; diff --git a/src/libs/antares/study/xcast/xcast.cpp b/src/libs/antares/study/xcast/xcast.cpp index 51ed1624b0..0f2e05956b 100644 --- a/src/libs/antares/study/xcast/xcast.cpp +++ b/src/libs/antares/study/xcast/xcast.cpp @@ -207,7 +207,8 @@ bool XCast::loadFromFolder(const AnyString& folder) // For each property if (section.name == "general") { - for (const IniFile::Property* p = section.firstProperty; p != nullptr; p = p->next) + for (const IniFile::Property* p = section.firstProperty; p != nullptr; + p = p->next) { CString<30, false> key = p->key; key.toLower(); diff --git a/src/libs/antares/writer/in_memory_writer.cpp b/src/libs/antares/writer/in_memory_writer.cpp index e3e643a74f..182fee1927 100644 --- a/src/libs/antares/writer/in_memory_writer.cpp +++ b/src/libs/antares/writer/in_memory_writer.cpp @@ -24,9 +24,9 @@ #include #include +#include #include #include -#include namespace fs = std::filesystem; diff --git a/src/libs/antares/writer/zip_writer.cpp b/src/libs/antares/writer/zip_writer.cpp index 362d0e730e..6359460f8a 100644 --- a/src/libs/antares/writer/zip_writer.cpp +++ b/src/libs/antares/writer/zip_writer.cpp @@ -51,7 +51,6 @@ static void logErrorAndThrow [[noreturn]] (const std::string& errorMessage) throw std::runtime_error(errorMessage); } - // Class ZipWriteJob template ZipWriteJob::ZipWriteJob(ZipWriter& writer, diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index d222ad88c0..9ec3ce3e14 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -337,10 +337,14 @@ void Application::prepare(int argc, char* argv[]) // don't de-allocate these. if (!parseCommandLine(options)) // --help + { return; + } if (!handleOptions(options)) // --version, --list-solvers - return; + { + return; + } // Perform some checks checkAndCorrectSettingsAndOptions(pSettings, options); diff --git a/src/solver/constraints-builder/cbuilder.cpp b/src/solver/constraints-builder/cbuilder.cpp index a49806ff16..0b37556347 100644 --- a/src/solver/constraints-builder/cbuilder.cpp +++ b/src/solver/constraints-builder/cbuilder.cpp @@ -364,8 +364,7 @@ bool CBuilder::saveCBuilderToFile(const String& filename) const if (filename == "") { - fs::path path = fs::path(pStudy.folder.c_str()) / "settings" - / "constraintbuilder.ini"; + fs::path path = fs::path(pStudy.folder.c_str()) / "settings" / "constraintbuilder.ini"; return ini.save(path.string()); } diff --git a/src/solver/hydro/include/antares/solver/hydro/management/management.h b/src/solver/hydro/include/antares/solver/hydro/management/management.h index b642e441c2..30528d92d2 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -152,8 +152,7 @@ class HydroManagement final // \return The total inflow for the whole year double prepareMonthlyTargetGenerations(Data::Area& area, TmpDataByArea& data); - void prepareDailyOptimalGenerations(uint y, - Antares::Data::Area::ScratchMap& scratchmap); + void prepareDailyOptimalGenerations(uint y, Antares::Data::Area::ScratchMap& scratchmap); void prepareDailyOptimalGenerations(Data::Area& area, uint y, diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index f7e4665159..d9651a1197 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -219,9 +219,9 @@ struct DebugData }; inline void HydroManagement::prepareDailyOptimalGenerations( - Data::Area& area, - uint y, - Antares::Data::Area::ScratchMap& scratchmap) + Data::Area& area, + uint y, + Antares::Data::Area::ScratchMap& scratchmap) { const auto srcinflows = area.hydro.series->storage.getColumn(y); diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 703235fc61..a863668f64 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -385,23 +385,31 @@ bool HydroManagement::checkMinGeneration(uint year) const void HydroManagement::changeInflowsToAccommodateFinalLevels(uint year) { - areas_.each([this, &year](Data::Area& area) - { - auto& data = tmpDataByArea_[&area]; - - if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) - return; - - // Must be done before prepareMonthlyTargetGenerations - double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); - if (delta < 0) - data.inflows[0] -= delta; - else if (delta > 0) - data.inflows[11] -= delta; - }); + areas_.each( + [this, &year](Data::Area& area) + { + auto& data = tmpDataByArea_[&area]; + + if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) + { + return; + } + + // Must be done before prepareMonthlyTargetGenerations + double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); + if (delta < 0) + { + data.inflows[0] -= delta; + } + else if (delta > 0) + { + data.inflows[11] -= delta; + } + }); } -void HydroManagement::prepareNetDemand(uint year, Data::SimulationMode mode, +void HydroManagement::prepareNetDemand(uint year, + Data::SimulationMode mode, const Antares::Data::Area::ScratchMap& scratchmap) { areas_.each( diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index aa10b7c10e..37c2085e3c 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -290,22 +290,22 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ auto monthName = calendar_.text.months[simulationMonth].name; - buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; - buffer << '\t'; - buffer << data.inflows[realmonth] << '\t'; - buffer << data.MTG[realmonth] << '\t'; - buffer << data.MOG[realmonth] / area.hydro.reservoirCapacity << '\t'; - buffer << data.MOL[realmonth] << '\t'; - buffer << minLvl[firstDay] << '\t'; - buffer << maxLvl[firstDay] << '\t'; - buffer << '\n'; - } - auto content = buffer.str(); - resultWriter_.addEntryFromBuffer(path.str(), content); - } + buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; + buffer << '\t'; + buffer << data.inflows[realmonth] << '\t'; + buffer << data.MTG[realmonth] << '\t'; + buffer << data.MOG[realmonth] / area.hydro.reservoirCapacity << '\t'; + buffer << data.MOL[realmonth] << '\t'; + buffer << minLvl[firstDay] << '\t'; + buffer << maxLvl[firstDay] << '\t'; + buffer << '\n'; + } + auto content = buffer.str(); + resultWriter_.addEntryFromBuffer(path.str(), content); + } - indexArea++; - }); + indexArea++; + }); } } // namespace Antares diff --git a/src/solver/misc/include/antares/solver/misc/options.h b/src/solver/misc/include/antares/solver/misc/options.h index 2560a74d1c..00daf5aec7 100644 --- a/src/solver/misc/include/antares/solver/misc/options.h +++ b/src/solver/misc/include/antares/solver/misc/options.h @@ -27,8 +27,8 @@ #include #include -#include #include +#include /*! ** \brief Command line settings for launching the simulation diff --git a/src/solver/misc/options.cpp b/src/solver/misc/options.cpp index 9429b50e79..458ae2fa06 100644 --- a/src/solver/misc/options.cpp +++ b/src/solver/misc/options.cpp @@ -22,8 +22,8 @@ #include "antares/solver/misc/options.h" #include -#include #include +#include #include #include diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index 2b03f7bcdc..fa4a292902 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -68,7 +68,10 @@ bool Adequacy::simulationBegin() pProblemesHebdo.resize(pNbMaxPerformedYearsInParallel); for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) { - SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], nbHoursInAWeek, numSpace); + SIM_InitialisationProblemeHebdo(study, + pProblemesHebdo[numSpace], + nbHoursInAWeek, + numSpace); } } diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index 1f56235499..8095cc85bb 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -395,21 +395,23 @@ void PrepareRandomNumbers(Data::Study& study, }); } - void SetInitialHydroLevel(Data::Study& study, PROBLEME_HEBDO& problem, const HYDRO_VENTILATION_RESULTS& hydroVentilationResults) { uint firstDaySimu = study.parameters.simulationDays.first; - study.areas.each([&problem, &firstDaySimu, &hydroVentilationResults](const Data::Area& area) - { - if (area.hydro.reservoirManagement) - { - double capacity = area.hydro.reservoirCapacity; - problem.previousSimulationFinalLevel[area.index] = - hydroVentilationResults[area.index].NiveauxReservoirsDebutJours[firstDaySimu] * capacity; - } - }); + study.areas.each( + [&problem, &firstDaySimu, &hydroVentilationResults](const Data::Area& area) + { + if (area.hydro.reservoirManagement) + { + double capacity = area.hydro.reservoirCapacity; + problem.previousSimulationFinalLevel[area.index] = hydroVentilationResults[area.index] + .NiveauxReservoirsDebutJours + [firstDaySimu] + * capacity; + } + }); } void BuildThermalPartOfWeeklyProblem(Data::Study& study, diff --git a/src/solver/simulation/common-hydro-levels.cpp b/src/solver/simulation/common-hydro-levels.cpp index 81602073a1..b0ba258b0e 100644 --- a/src/solver/simulation/common-hydro-levels.cpp +++ b/src/solver/simulation/common-hydro-levels.cpp @@ -33,7 +33,7 @@ void computingHydroLevels(const Data::AreaList& areas, bool remixWasRun, bool computeAnyway) { - for (const auto& [_, area] : areas) + for (const auto& [_, area]: areas) { if (!area->hydro.reservoirManagement) { @@ -50,7 +50,7 @@ void computingHydroLevels(const Data::AreaList& areas, double reservoirCapacity = area->hydro.reservoirCapacity; std::vector& inflows = problem.CaracteristiquesHydrauliques[index] - .ApportNaturelHoraire; + .ApportNaturelHoraire; RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; @@ -65,7 +65,7 @@ void computingHydroLevels(const Data::AreaList& areas, std::vector& ovf = weeklyResults.debordementsHoraires; computeTimeStepLevel - computeLvlObj(nivInit, inflows, ovf, turb, pumpingRatio, pump, reservoirCapacity); + computeLvlObj(nivInit, inflows, ovf, turb, pumpingRatio, pump, reservoirCapacity); for (uint h = 0; h < nbHoursInAWeek - 1; h++) { @@ -94,7 +94,7 @@ void interpolateWaterValue(const Data::AreaList& areas, daysOfWeek[d] = weekFirstDay + d; } - for (const auto& [_, area] : areas) + for (const auto& [_, area]: areas) { uint index = area->index; @@ -118,22 +118,22 @@ void interpolateWaterValue(const Data::AreaList& areas, std::vector& niv = weeklyResults.niveauxHoraires; waterVal[0] = Data::getWaterValue(problem.previousSimulationFinalLevel[index] * 100 - / reservoirCapacity, - area->hydro.waterValues, - weekFirstDay); + / reservoirCapacity, + area->hydro.waterValues, + weekFirstDay); for (uint h = 1; h < nbHoursInAWeek; h++) { waterVal[h] = Data::getWaterValue(niv[h - 1], - area->hydro.waterValues, - daysOfWeek[h / 24]); + area->hydro.waterValues, + daysOfWeek[h / 24]); } } } void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& problem) { - for (const auto& [_, area] : areas) + for (const auto& [_, area]: areas) { if (!area->hydro.reservoirManagement) { @@ -149,7 +149,7 @@ void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& std::vector& niv = weeklyResults.niveauxHoraires; problem.previousSimulationFinalLevel[index] = niv[nbHoursInAWeek - 1] * reservoirCapacity - / 100; + / 100; } } diff --git a/src/solver/simulation/common-hydro-remix.cpp b/src/solver/simulation/common-hydro-remix.cpp index dcf39052ce..de8e3f5328 100644 --- a/src/solver/simulation/common-hydro-remix.cpp +++ b/src/solver/simulation/common-hydro-remix.cpp @@ -51,8 +51,7 @@ static bool Remix(const Data::AreaList& areas, bool status = true; areas.each( - [&HE, &DE, &remix, &G, &status, &problem, &numSpace, &hourInYear] - (const Data::Area& area) + [&HE, &DE, &remix, &G, &status, &problem, &numSpace, &hourInYear](const Data::Area& area) { auto index = area.index; diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 934ebc4c2c..ac40117b2c 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -73,7 +73,10 @@ bool Economy::simulationBegin() for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) { - SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], nbHoursInAWeek, numSpace); + SIM_InitialisationProblemeHebdo(study, + pProblemesHebdo[numSpace], + nbHoursInAWeek, + numSpace); auto options = createOptimizationOptions(study); weeklyOptProblems_[numSpace] = Antares::Solver::Optimization::WeeklyOptimization:: diff --git a/src/solver/simulation/hydro-final-reservoir-level-functions.cpp b/src/solver/simulation/hydro-final-reservoir-level-functions.cpp index 32f2d4dfa2..225a0e2be9 100644 --- a/src/solver/simulation/hydro-final-reservoir-level-functions.cpp +++ b/src/solver/simulation/hydro-final-reservoir-level-functions.cpp @@ -26,43 +26,47 @@ */ #include "antares/solver/simulation/hydro-final-reservoir-level-functions.h" -#include "antares/study/parts/hydro/finalLevelValidator.h" + #include +#include "antares/study/parts/hydro/finalLevelValidator.h" namespace Antares::Solver { void CheckFinalReservoirLevelsConfiguration(const Data::Study& study) { - study.areas.each([&study](Data::Area &area) - { - uint nbYears = study.parameters.nbYears; - for (uint year = 0; year != nbYears; ++year) - { - if (! study.parameters.yearsFilter.at(year)) - continue; + study.areas.each( + [&study](Data::Area& area) + { + uint nbYears = study.parameters.nbYears; + for (uint year = 0; year != nbYears; ++year) + { + if (!study.parameters.yearsFilter.at(year)) + { + continue; + } - double initialLevel = study.scenarioInitialHydroLevels.entry[area.index][year]; - double finalLevel = study.scenarioFinalHydroLevels.entry[area.index][year]; + double initialLevel = study.scenarioInitialHydroLevels.entry[area.index][year]; + double finalLevel = study.scenarioFinalHydroLevels.entry[area.index][year]; - Data::FinalLevelValidator validator(area.hydro, - area.index, - area.name, - initialLevel, - finalLevel, - year, - study.parameters.simulationDays.end, - study.parameters.firstMonthInYear); - if (! validator.check()) - { - throw FatalError("hydro final level : infeasibility"); - } - if (validator.finalLevelFineForUse()) - { - area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; - } - } - }); + Data::FinalLevelValidator validator(area.hydro, + area.index, + area.name, + initialLevel, + finalLevel, + year, + study.parameters.simulationDays.end, + study.parameters.firstMonthInYear); + if (!validator.check()) + { + throw FatalError("hydro final level : infeasibility"); + } + if (validator.finalLevelFineForUse()) + { + area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; + } + } + }); } // End function CheckFinalReservoirLevelsConfiguration -} // namespace Antares::Solver \ No newline at end of file +} // namespace Antares::Solver diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 232fa520fc..cd6bcb5f62 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -39,7 +39,6 @@ #include "antares/solver/simulation/timeseries-numbers.h" #include "antares/solver/ts-generator/generator.h" - #include "hydro-final-reservoir-level-functions.h" namespace Antares::Solver::Simulation @@ -75,10 +74,7 @@ public: yearByYear(pYearByYear), pDurationCollector(durationCollector), pResultWriter(resultWriter), - hydroManagement(study.areas, - study.parameters, - study.calendar, - resultWriter) + hydroManagement(study.areas, study.parameters, study.calendar, resultWriter) { scratchmap = study.areas.buildScratchMap(numSpace); } @@ -162,11 +158,8 @@ public: simulation_->prepareClustersInMustRunMode(scratchmap, y); // 4 - Hydraulic ventilation - pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] { - hydroManagement.makeVentilation(randomReservoirLevel, - y, - scratchmap); - }; + pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] + { hydroManagement.makeVentilation(randomReservoirLevel, y, scratchmap); }; // Updating the state state.year = y; @@ -748,15 +741,15 @@ void ISimulation::computeRandomNumbers( max[firstDayOfMonth], randomHydroGenerator); - // Possibly update the intial level from scenario builder - if (study.parameters.useCustomScenario) - { - double levelFromScenarioBuilder = study.scenarioInitialHydroLevels[areaIndex][y]; - if (levelFromScenarioBuilder >= 0.) - { - randomLevel = levelFromScenarioBuilder; - } - } + // Possibly update the intial level from scenario builder + if (study.parameters.useCustomScenario) + { + double levelFromScenarioBuilder = study.scenarioInitialHydroLevels[areaIndex][y]; + if (levelFromScenarioBuilder >= 0.) + { + randomLevel = levelFromScenarioBuilder; + } + } // Current area's hydro starting (or initial) level computation // (no matter if the year is performed or not, we always draw a random initial @@ -780,7 +773,12 @@ void ISimulation::computeRandomNumbers( bool SpilledEnergySeedIsDefault = (currentSpilledEnergySeed == defaultSpilledEnergySeed); areaIndex = 0; study.areas.each( - [&isPerformed, &areaIndex, &randomUnsupplied, &randomSpilled, &randomForYears, &indexYear, + [&isPerformed, + &areaIndex, + &randomUnsupplied, + &randomSpilled, + &randomForYears, + &indexYear, &SpilledEnergySeedIsDefault](Data::Area& area) { (void)area; // Avoiding warnings at compilation (unused variable) on linux @@ -1030,19 +1028,19 @@ void ISimulation::loopThroughYears(uint firstYear, // continue; auto task = std::make_shared>( - this, - y, - set_it->yearFailed, - set_it->isFirstPerformedYearOfASet, - pFirstSetParallelWithAPerformedYearWasRun, - numSpace, - randomForParallelYears, - performCalculations, - study, - state[numSpace], - pYearByYear, - pDurationCollector, - pResultWriter); + this, + y, + set_it->yearFailed, + set_it->isFirstPerformedYearOfASet, + pFirstSetParallelWithAPerformedYearWasRun, + numSpace, + randomForParallelYears, + performCalculations, + study, + state[numSpace], + pYearByYear, + pDurationCollector, + pResultWriter); results.add(Concurrency::AddTask(*pQueueService, task)); } // End loop over years of the current set of parallel years diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index ed13d54fe1..7fb3336599 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -513,11 +513,11 @@ void SIM_RenseignementProblemeHebdo(const Study& study, if (area.hydro.useWaterValue) { - problem.CaracteristiquesHydrauliques[k].WeeklyWaterValueStateRegular = - getWaterValue( - problem.previousSimulationFinalLevel[k] * 100 / area.hydro.reservoirCapacity, - area.hydro.waterValues, - weekFirstDay); + problem.CaracteristiquesHydrauliques[k].WeeklyWaterValueStateRegular + = getWaterValue(problem.previousSimulationFinalLevel[k] * 100 + / area.hydro.reservoirCapacity, + area.hydro.waterValues, + weekFirstDay); } if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable > 0) diff --git a/src/solver/simulation/timeseries-numbers.cpp b/src/solver/simulation/timeseries-numbers.cpp index 52b1213ada..446a0efa08 100644 --- a/src/solver/simulation/timeseries-numbers.cpp +++ b/src/solver/simulation/timeseries-numbers.cpp @@ -329,8 +329,7 @@ bool checkInterModalConsistencyForArea(const Area& area, { logs.error() << "Inter-modal correlation: time-series numbers of inter-modal modes in area '" - << area.name << "'" - << " are not identical"; + << area.name << "'" << " are not identical"; return false; } diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 69f62a10a1..dfb2d8c1f4 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -99,7 +99,9 @@ class GeneratorTempData final const T& duration) const; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen, MersenneTwister& rndGenerator): +GeneratorTempData::GeneratorTempData(Data::Study& study, + unsigned nbOfSeriesToGen, + MersenneTwister& rndGenerator): derated(study.parameters.derated), nbOfSeriesToGen_(nbOfSeriesToGen), rndgenerator(rndGenerator) @@ -616,10 +618,13 @@ listOfLinks getAllLinksToGen(Data::AreaList& areas) areas.each( [&links](const Data::Area& area) { - std::ranges::for_each(area.links, [&links](auto& l) + std::ranges::for_each(area.links, + [&links](auto& l) { if (!l.second->tsGeneration.forceNoGeneration) + { links.push_back(l.second); + } }); }); @@ -698,7 +703,10 @@ bool generateLinkTimeSeries(Data::Study& study, } // DIRECT - AvailabilityTSGeneratorData tsConfigDataDirect(tsGenStruct, ts, tsGenStruct.modulationCapacityDirect, link->with->name); + AvailabilityTSGeneratorData tsConfigDataDirect(tsGenStruct, + ts, + tsGenStruct.modulationCapacityDirect, + link->with->name); generator.generateTS(*link->from, tsConfigDataDirect); @@ -707,12 +715,14 @@ bool generateLinkTimeSeries(Data::Study& study, writeResultsToDisk(study, writer, ts.timeSeries, filePath); // INDIRECT - AvailabilityTSGeneratorData tsConfigDataIndirect(tsGenStruct, ts, tsGenStruct.modulationCapacityIndirect, link->with->name); + AvailabilityTSGeneratorData tsConfigDataIndirect(tsGenStruct, + ts, + tsGenStruct.modulationCapacityIndirect, + link->with->name); generator.generateTS(*link->from, tsConfigDataIndirect); - filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() - + "_indirect.txt"; + filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + "_indirect.txt"; writeResultsToDisk(study, writer, ts.timeSeries, filePath); } diff --git a/src/solver/ts-generator/xcast/xcast.cpp b/src/solver/ts-generator/xcast/xcast.cpp index ca0c96087a..56f7234119 100644 --- a/src/solver/ts-generator/xcast/xcast.cpp +++ b/src/solver/ts-generator/xcast/xcast.cpp @@ -593,7 +593,8 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi if (study.parameters.derated) { - study.areas.each([&predicate](Data::Area& area) { predicate.matrix(area).averageTimeseries(); }); + study.areas.each([&predicate](Data::Area& area) + { predicate.matrix(area).averageTimeseries(); }); } if (study.parameters.timeSeriesToArchive & timeSeriesType) diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index 1f2f5e4169..2cc81b80fa 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -56,10 +56,9 @@ static void checkSetSolverSpecificParameters(bool status, } } -static void TuneSolverSpecificOptions( - MPSolver* solver, - const std::string& solverName, - const std::string& solverParameters) +static void TuneSolverSpecificOptions(MPSolver* solver, + const std::string& solverName, + const std::string& solverParameters) { if (!solver) { @@ -135,7 +134,6 @@ MPSolver* ProblemSimplexeNommeConverter::Convert() return solver; } - void ProblemSimplexeNommeConverter::CopyMatrix(const MPSolver* solver) const { auto variables = solver->variables(); diff --git a/src/solver/variable/include/antares/solver/variable/economy/all.h b/src/solver/variable/include/antares/solver/variable/economy/all.h index a3c637c43f..b7a62eb6bf 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/all.h +++ b/src/solver/variable/include/antares/solver/variable/economy/all.h @@ -248,8 +248,8 @@ typedef Variable::Join< Variable::Areas, // Variables for each set of areas Variable::Join, - // Variables for each binding constraint - Variable::BindingConstraints>> + // Variables for each binding constraint + Variable::BindingConstraints>> ItemList; /*! diff --git a/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h b/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h index 6d7e02fa3e..8a1f97676f 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h +++ b/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h @@ -147,7 +147,6 @@ class BindingConstMarginCost NextType::simulationEnd(); } - void initializeFromStudy(Data::Study& study) { pNbYearsParallel = study.maxNbYearsInParallel; @@ -257,8 +256,8 @@ class BindingConstMarginCost for (int dayInTheWeek = 0; dayInTheWeek < 7; dayInTheWeek++) { pValuesForTheCurrentYear[numSpace].day[dayInTheYear] - -= state.problemeHebdo - ->ResultatsContraintesCouplantes[associatedBC_][dayInTheWeek]; + -= state.problemeHebdo + ->ResultatsContraintesCouplantes[associatedBC_][dayInTheWeek]; dayInTheYear++; } @@ -270,7 +269,7 @@ class BindingConstMarginCost { uint weekInTheYear = state.weekInTheYear; double weeklyValue = -state.problemeHebdo - ->ResultatsContraintesCouplantes[associatedBC_][0]; + ->ResultatsContraintesCouplantes[associatedBC_][0]; pValuesForTheCurrentYear[numSpace].week[weekInTheYear] = weeklyValue; diff --git a/src/solver/variable/include/antares/solver/variable/endoflist.h b/src/solver/variable/include/antares/solver/variable/endoflist.h index 7c32c32ecb..d8cb5dd69d 100644 --- a/src/solver/variable/include/antares/solver/variable/endoflist.h +++ b/src/solver/variable/include/antares/solver/variable/endoflist.h @@ -254,7 +254,6 @@ class EndOfList static void computeSpatialAggregateWith(O&, const Data::Area*, uint numSpace) { UNUSED_VARIABLE(numSpace); - assert(false); } template diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index bfad50326f..96a66aef3e 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -82,7 +82,7 @@ HydroMaxPowerStudy::HydroMaxPowerStudy() area = addAreaToStudy("Area"); area->thermal.unsuppliedEnergyCost = 1; - setNumberMCyears(1); + setNumberMCyears(1); TimeSeriesConfigurer loadTSconfig(area->load.series.timeSeries); loadTSconfig.setColumnCount(1).fillColumnWith(0, loadInArea); diff --git a/src/tests/end-to-end/utils/utils.cpp b/src/tests/end-to-end/utils/utils.cpp index a42891ea45..fdba99c007 100644 --- a/src/tests/end-to-end/utils/utils.cpp +++ b/src/tests/end-to-end/utils/utils.cpp @@ -219,7 +219,8 @@ void StudyBuilder::setNumberMCyears(unsigned int nbYears) { study->parameters.resetPlaylist(nbYears); study->areas.resizeAllTimeseriesNumbers(nbYears); - study->areas.each([&](Data::Area& area) { area.hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); }); + study->areas.each([&](Data::Area& area) + { area.hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); }); } void StudyBuilder::playOnlyYear(unsigned int year) diff --git a/src/tests/end-to-end/utils/utils.h b/src/tests/end-to-end/utils/utils.h index 1fa55efbff..84362bf2e0 100644 --- a/src/tests/end-to-end/utils/utils.h +++ b/src/tests/end-to-end/utils/utils.h @@ -164,14 +164,17 @@ class ScenarioBuilderRule { return rules_->load; } + BindingConstraintsTSNumberData& bcGroup() { return rules_->binding_constraints; } + hydroTSNumberData& hydro() { return rules_->hydro; } + private: Rules::Ptr rules_; }; diff --git a/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp b/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp index e97f4e3524..04d1c7be9f 100644 --- a/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp +++ b/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp @@ -19,15 +19,17 @@ ** along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE antlr_interface tests -#include -#include -#include "antlr4-runtime.h" #include +#include +#include + #include "ExprLexer.h" #include "ExprParser.h" +#include "antlr4-runtime.h" using namespace antlr4; + BOOST_AUTO_TEST_CASE(test_antlr_interface) { const std::string my_input = "y = b + a*x"; diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp index 7879559fb0..de09d007d1 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp @@ -355,10 +355,12 @@ BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_17__hydro_level_0_123_is_chosen__re AreaName::Vector splitKey = {"hl", "area 1", yearNumber}; my_rule.readLine(splitKey, level); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_1->index), level.to()); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_1->index), + level.to()); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_1->index][yearNumber.to()], level.to()); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_1->index][yearNumber.to()], + level.to()); } BOOST_FIXTURE_TEST_CASE( @@ -370,10 +372,11 @@ BOOST_FIXTURE_TEST_CASE( AreaName::Vector splitKey = {"hl", "area 2", yearNumber}; BOOST_CHECK(my_rule.readLine(splitKey, level)); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_2->index), 1.); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_2->index), + 1.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_2->index][yearNumber.to()], 1.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_2->index][yearNumber.to()], 1.); } BOOST_FIXTURE_TEST_CASE( @@ -385,10 +388,11 @@ BOOST_FIXTURE_TEST_CASE( AreaName::Vector splitKey = {"hl", "area 3", yearNumber}; BOOST_CHECK(my_rule.readLine(splitKey, level)); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_3->index), 0.); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_3->index), + 0.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_3->index][yearNumber.to()], 0.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_3->index][yearNumber.to()], 0.); } // ======================== @@ -396,47 +400,47 @@ BOOST_FIXTURE_TEST_CASE( // ======================== BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_8__hydro_level_0_342_is_chosen__reading_OK, Fixture) { - AreaName yearNumber = "8"; - String level = "0.342"; - AreaName::Vector splitKey = {"hfl", "area 1", yearNumber}; - my_rule.readLine(splitKey, level, false); + AreaName yearNumber = "8"; + String level = "0.342"; + AreaName::Vector splitKey = {"hfl", "area 1", yearNumber}; + my_rule.readLine(splitKey, level, false); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_1->index), - level.to()); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_1->index), + level.to()); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_1->index][yearNumber.to()], - level.to()); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_1->index][yearNumber.to()], + level.to()); } -BOOST_FIXTURE_TEST_CASE(on_area2_and_on_year_1__hydro_level_2_4_is_chosen_level_lowered_to_1__reading_OK, Fixture) +BOOST_FIXTURE_TEST_CASE( + on_area2_and_on_year_1__hydro_level_2_4_is_chosen_level_lowered_to_1__reading_OK, + Fixture) { - AreaName yearNumber = "1"; - String level = "2.4"; - AreaName::Vector splitKey = {"hfl", "area 2", yearNumber}; - BOOST_CHECK(my_rule.readLine(splitKey, level, false)); + AreaName yearNumber = "1"; + String level = "2.4"; + AreaName::Vector splitKey = {"hfl", "area 2", yearNumber}; + BOOST_CHECK(my_rule.readLine(splitKey, level, false)); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_2->index), - 1.); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_2->index), 1.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_2->index][yearNumber.to()], - 1.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_2->index][yearNumber.to()], 1.); } -BOOST_FIXTURE_TEST_CASE(on_area3_and_on_year_3__hydro_level_neg_5_2_is_chosen__level_raised_to_0__reading_OK, Fixture) +BOOST_FIXTURE_TEST_CASE( + on_area3_and_on_year_3__hydro_level_neg_5_2_is_chosen__level_raised_to_0__reading_OK, + Fixture) { - AreaName yearNumber = "3"; - String level = "-5.2"; - AreaName::Vector splitKey = {"hfl", "area 3", yearNumber}; - BOOST_CHECK(my_rule.readLine(splitKey, level, false)); + AreaName yearNumber = "3"; + String level = "-5.2"; + AreaName::Vector splitKey = {"hfl", "area 3", yearNumber}; + BOOST_CHECK(my_rule.readLine(splitKey, level, false)); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_3->index), - 0.); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_3->index), 0.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_3->index][yearNumber.to()], - 0.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_3->index][yearNumber.to()], 0.); } // ====================== diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp index 13d5a38b48..64813637fc 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp @@ -436,7 +436,9 @@ BOOST_FIXTURE_TEST_CASE( // ======================== // Tests on Hydro final levels // ======================== -BOOST_FIXTURE_TEST_CASE(HYDRO_FINAL_LEVEL__TS_number_for_many_areas_and_years__generated_and_ref_sc_buider_files_are_identical, saveFixture) +BOOST_FIXTURE_TEST_CASE( + HYDRO_FINAL_LEVEL__TS_number_for_many_areas_and_years__generated_and_ref_sc_buider_files_are_identical, + saveFixture) { my_rule->hydroFinalLevels.setTSnumber(area_1->index, 4, 8); my_rule->hydroFinalLevels.setTSnumber(area_2->index, 11, 3); diff --git a/src/tests/src/libs/antares/test_utils.cpp b/src/tests/src/libs/antares/test_utils.cpp index ad7e97d833..5cb05e27c4 100644 --- a/src/tests/src/libs/antares/test_utils.cpp +++ b/src/tests/src/libs/antares/test_utils.cpp @@ -19,14 +19,14 @@ * along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE test utils +#include #include #include -#include - #include -#include + +#include namespace fs = std::filesystem; @@ -99,7 +99,8 @@ BOOST_AUTO_TEST_CASE(yuni_normalize_vs_std_lexically_normal) { Yuni::String yuniNorm; Yuni::IO::Normalize(yuniNorm, path.string()); - BOOST_CHECK_MESSAGE(path.lexically_normal().string() == yuniNorm, std::string("Check failed for ") + path.string()); + BOOST_CHECK_MESSAGE(path.lexically_normal().string() == yuniNorm, + std::string("Check failed for ") + path.string()); }; helper(fs::path("a/./b/..")); helper(fs::path("a/.///b/../")); diff --git a/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp b/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp index ebfbc4bba8..87978fbcaa 100644 --- a/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp +++ b/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp @@ -19,19 +19,22 @@ ** along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE yamlcpp tests -#include -#include -#include "yaml-cpp/yaml.h" -#include #include +#include #include #include +#include +#include + +#include "yaml-cpp/yaml.h" + // our data types struct Vec3 { float x, y, z; }; + struct Power { std::string name; @@ -44,6 +47,7 @@ struct Monster Vec3 position; std::vector powers; }; + namespace YAML { template<> @@ -71,6 +75,7 @@ struct convert return true; } }; + template<> struct convert { @@ -89,6 +94,7 @@ struct convert return true; } }; + template<> struct convert { @@ -108,7 +114,7 @@ struct convert rhs.name = node["name"].as(); rhs.position = node["position"].as(); const YAML::Node& powers = node["powers"]; - for (const auto power : powers) + for (const auto power: powers) { rhs.powers.push_back(power.as()); } diff --git a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp index d4a6c3512b..a38d7ea12c 100644 --- a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp +++ b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp @@ -6,23 +6,24 @@ #define WIN32_LEAN_AND_MEAN #include +#include + #include "include/antares/solver/simulation/hydro-final-reservoir-level-functions.h" #include "include/antares/study/parts/hydro/finalLevelValidator.h" -#include using namespace Antares::Solver; using namespace Antares::Data; - struct Fixture { Fixture(const Fixture& f) = delete; Fixture(const Fixture&& f) = delete; Fixture& operator=(const Fixture& f) = delete; Fixture& operator=(const Fixture&& f) = delete; + Fixture() { - // Simulation last day must be 365 so that final level checks succeeds + // Simulation last day must be 365 so that final level checks succeeds study->parameters.simulationDays.end = 365; study->parameters.firstMonthInYear = january; uint nbYears = study->parameters.nbYears = 2; @@ -56,7 +57,6 @@ struct Fixture area_1->hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); area_2->hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); - // Scenario builder for initial and final reservoir levels // ------------------------------------------------------- uint areasCount = study->areas.size(); @@ -96,7 +96,7 @@ struct Fixture // ... Area 2 : Inflows time series area_2->hydro.series->storage.resize(nbInflowTS, 365); area_2->hydro.series->storage.timeSeries.fill(300.); - area_2->hydro.series->storage[0][0] = 300. + 1.; //DAYS_PER_YEAR + area_2->hydro.series->storage[0][0] = 300. + 1.; // DAYS_PER_YEAR area_2->hydro.series->storage[0][DAYS_PER_YEAR - 1] = 300. + 2.; } @@ -178,7 +178,8 @@ BOOST_AUTO_TEST_CASE(final_level_not_set_by_user____check_succeeds_but_final_lev BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); } -BOOST_AUTO_TEST_CASE(initial_level_month_and_simulation_first_month_different___check_fails_and_final_level_not_usable) +BOOST_AUTO_TEST_CASE( + initial_level_month_and_simulation_first_month_different___check_fails_and_final_level_not_usable) { uint year = 0; area_1->hydro.initializeReservoirLevelDate = 3; // initialize reservoir level != January @@ -233,7 +234,8 @@ BOOST_AUTO_TEST_CASE(final_level_out_of_rule_curves___check_fails_and_final_leve BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); } -BOOST_AUTO_TEST_CASE(final_level_unreachable_because_of_too_few_inflows___check_fails_and_final_level_not_usable) +BOOST_AUTO_TEST_CASE( + final_level_unreachable_because_of_too_few_inflows___check_fails_and_final_level_not_usable) { area_1->hydro.reservoirCapacity = 185000; uint year = 0; @@ -272,4 +274,4 @@ BOOST_AUTO_TEST_CASE(check_all_areas_final_levels_when_config_is_ok___all_checks BOOST_CHECK_EQUAL(area_2->hydro.deltaBetweenFinalAndInitialLevels[1].value(), 4.3 - 2.4); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END() From 41b3f457422a38e9b26bb5d6a063b805a29357ed Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Wed, 26 Jun 2024 11:24:13 +0200 Subject: [PATCH 036/127] Revert "Check formatting as part of the CI" (#2196) Reverts AntaresSimulatorTeam/Antares_Simulator#2193 --- .github/workflows/clang-format.yml | 36 - .../antlr-interface/ExprBaseVisitor.cpp | 3 + .../antares/antlr-interface/ExprBaseVisitor.h | 144 +- .../antares/antlr-interface/ExprLexer.cpp | 323 ++-- src/libs/antares/antlr-interface/ExprLexer.h | 67 +- .../antares/antlr-interface/ExprParser.cpp | 1590 +++++++---------- src/libs/antares/antlr-interface/ExprParser.h | 392 ++-- .../antares/antlr-interface/ExprVisitor.cpp | 3 + .../antares/antlr-interface/ExprVisitor.h | 48 +- .../antares/checks/checkLoadedInputData.h | 1 + .../antares/exception/LoadingError.hpp | 7 +- .../FileTreeStudyLoader.h | 1 - .../include/antares/inifile/inifile.hxx | 3 +- src/libs/antares/inifile/inifile.cpp | 12 +- src/libs/antares/io/file.cpp | 2 +- src/libs/antares/io/include/antares/io/file.h | 4 +- .../antares/study-loader/IStudyLoader.h | 1 - src/libs/antares/study/area/area.cpp | 7 +- src/libs/antares/study/area/links.cpp | 27 +- src/libs/antares/study/area/list.cpp | 21 +- .../BindingConstraintGroupRepository.cpp | 18 +- .../antares/study/cleaner/cleaner-v20.cpp | 1 + .../study/include/antares/study/parameters.h | 3 +- .../antares/study/parts/hydro/container.h | 5 +- .../study/scenario-builder/hydroLevelsData.h | 3 +- .../study/include/antares/study/sets.hxx | 4 +- src/libs/antares/study/parameters.cpp | 17 +- .../study/parts/common/cluster_list.cpp | 5 +- .../antares/study/parts/hydro/allocation.cpp | 32 +- .../antares/study/parts/hydro/container.cpp | 256 ++- .../study/parts/hydro/finalLevelValidator.cpp | 46 +- src/libs/antares/study/parts/hydro/prepro.cpp | 8 +- src/libs/antares/study/parts/hydro/series.cpp | 2 +- .../study/parts/renewable/cluster_list.cpp | 2 +- .../parts/short-term-storage/container.cpp | 24 +- .../study/parts/thermal/cluster_list.cpp | 45 +- src/libs/antares/study/runtime/runtime.cpp | 6 +- .../BindingConstraintsTSNumbersData.cpp | 10 +- .../scenario-builder/hydroLevelsData.cpp | 6 +- .../antares/study/scenario-builder/rules.cpp | 5 +- src/libs/antares/study/study.cpp | 21 +- src/libs/antares/study/study.importprepro.cpp | 10 +- src/libs/antares/study/xcast/xcast.cpp | 3 +- src/libs/antares/writer/in_memory_writer.cpp | 2 +- src/libs/antares/writer/zip_writer.cpp | 1 + src/solver/application/application.cpp | 6 +- src/solver/constraints-builder/cbuilder.cpp | 3 +- .../solver/hydro/management/management.h | 3 +- src/solver/hydro/management/daily.cpp | 6 +- src/solver/hydro/management/management.cpp | 38 +- src/solver/hydro/management/monthly.cpp | 30 +- .../include/antares/solver/misc/options.h | 2 +- src/solver/misc/options.cpp | 2 +- src/solver/simulation/adequacy.cpp | 5 +- src/solver/simulation/common-eco-adq.cpp | 22 +- src/solver/simulation/common-hydro-levels.cpp | 22 +- src/solver/simulation/common-hydro-remix.cpp | 3 +- src/solver/simulation/economy.cpp | 5 +- .../hydro-final-reservoir-level-functions.cpp | 62 +- .../antares/solver/simulation/solver.hxx | 64 +- .../simulation/sim_calcul_economique.cpp | 10 +- src/solver/simulation/timeseries-numbers.cpp | 3 +- src/solver/ts-generator/availability.cpp | 22 +- src/solver/ts-generator/xcast/xcast.cpp | 3 +- src/solver/utils/ortools_utils.cpp | 8 +- .../antares/solver/variable/economy/all.h | 4 +- .../bindingConstraintsMarginalCost.h | 7 +- .../antares/solver/variable/endoflist.h | 1 + .../end-to-end/simple_study/simple-study.cpp | 2 +- src/tests/end-to-end/utils/utils.cpp | 3 +- src/tests/end-to-end/utils/utils.h | 3 - .../antlr4-interface/test_antlr_interface.cpp | 8 +- .../test-sc-builder-file-read-line.cpp | 80 +- .../test-sc-builder-file-save.cpp | 4 +- src/tests/src/libs/antares/test_utils.cpp | 9 +- .../antares/yaml-parser/test_yaml_parser.cpp | 16 +- ...-hydro-final-reservoir-level-functions.cpp | 18 +- 77 files changed, 1584 insertions(+), 2117 deletions(-) delete mode 100644 .github/workflows/clang-format.yml diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml deleted file mode 100644 index 9e00892851..0000000000 --- a/.github/workflows/clang-format.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Check cpp formatting - -on: - push: - branches: - - develop - - feature/* - - features/* - - fix/* - -jobs: - build: - name: clang-format - - runs-on: ubuntu-24.04 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Print version - run: clang-format --version - - - name: clang-format - run: cd src && ./format-code.sh - - - name: git diff - run: | - DIFF=`git status --porcelain` - if [[ $DIFF ]]; then - echo "The following files are not well formatted" - echo "$DIFF" - exit 1 - else - echo "Code is well formatted, congrats !" - fi diff --git a/src/libs/antares/antlr-interface/ExprBaseVisitor.cpp b/src/libs/antares/antlr-interface/ExprBaseVisitor.cpp index ec45c3a47e..42d6fef5d3 100644 --- a/src/libs/antares/antlr-interface/ExprBaseVisitor.cpp +++ b/src/libs/antares/antlr-interface/ExprBaseVisitor.cpp @@ -1,4 +1,7 @@ // Generated from Expr.g4 by ANTLR 4.13.1 + #include "ExprBaseVisitor.h" + + diff --git a/src/libs/antares/antlr-interface/ExprBaseVisitor.h b/src/libs/antares/antlr-interface/ExprBaseVisitor.h index 7ff7be623d..a8af3c573f 100644 --- a/src/libs/antares/antlr-interface/ExprBaseVisitor.h +++ b/src/libs/antares/antlr-interface/ExprBaseVisitor.h @@ -3,88 +3,78 @@ #pragma once -#include "ExprVisitor.h" + #include "antlr4-runtime.h" +#include "ExprVisitor.h" + /** * This class provides an empty implementation of ExprVisitor, which can be * extended to create a visitor which only needs to handle a subset of the available methods. */ -class ExprBaseVisitor: public ExprVisitor -{ +class ExprBaseVisitor : public ExprVisitor { public: - virtual std::any visitFullexpr(ExprParser::FullexprContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitShift(ExprParser::ShiftContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitIdentifier(ExprParser::IdentifierContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitNegation(ExprParser::NegationContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitExpression(ExprParser::ExpressionContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitComparison(ExprParser::ComparisonContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitAddsub(ExprParser::AddsubContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitPortField(ExprParser::PortFieldContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitMuldiv(ExprParser::MuldivContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitNumber(ExprParser::NumberContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitTimeIndex(ExprParser::TimeIndexContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitTimeShift(ExprParser::TimeShiftContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitFunction(ExprParser::FunctionContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitTimeShiftRange(ExprParser::TimeShiftRangeContext* ctx) override - { - return visitChildren(ctx); - } - - virtual std::any visitTimeRange(ExprParser::TimeRangeContext* ctx) override - { - return visitChildren(ctx); - } + + virtual std::any visitFullexpr(ExprParser::FullexprContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitShift(ExprParser::ShiftContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitIdentifier(ExprParser::IdentifierContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitNegation(ExprParser::NegationContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitExpression(ExprParser::ExpressionContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitComparison(ExprParser::ComparisonContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitAddsub(ExprParser::AddsubContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitPortField(ExprParser::PortFieldContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitMuldiv(ExprParser::MuldivContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitNumber(ExprParser::NumberContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitTimeIndex(ExprParser::TimeIndexContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitTimeShift(ExprParser::TimeShiftContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitFunction(ExprParser::FunctionContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitTimeShiftRange(ExprParser::TimeShiftRangeContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitTimeRange(ExprParser::TimeRangeContext *ctx) override { + return visitChildren(ctx); + } + + }; + diff --git a/src/libs/antares/antlr-interface/ExprLexer.cpp b/src/libs/antares/antlr-interface/ExprLexer.cpp index 9250294cf8..a645fcddd0 100644 --- a/src/libs/antares/antlr-interface/ExprLexer.cpp +++ b/src/libs/antares/antlr-interface/ExprLexer.cpp @@ -1,238 +1,177 @@ // Generated from Expr.g4 by ANTLR 4.13.1 + #include "ExprLexer.h" + using namespace antlr4; + + using namespace antlr4; -namespace -{ - -struct ExprLexerStaticData final -{ - ExprLexerStaticData(std::vector ruleNames, - std::vector channelNames, - std::vector modeNames, - std::vector literalNames, - std::vector symbolicNames): - ruleNames(std::move(ruleNames)), - channelNames(std::move(channelNames)), - modeNames(std::move(modeNames)), - literalNames(std::move(literalNames)), - symbolicNames(std::move(symbolicNames)), - vocabulary(this->literalNames, this->symbolicNames) - { - } +namespace { - ExprLexerStaticData(const ExprLexerStaticData&) = delete; - ExprLexerStaticData(ExprLexerStaticData&&) = delete; - ExprLexerStaticData& operator=(const ExprLexerStaticData&) = delete; - ExprLexerStaticData& operator=(ExprLexerStaticData&&) = delete; - - std::vector decisionToDFA; - antlr4::atn::PredictionContextCache sharedContextCache; - const std::vector ruleNames; - const std::vector channelNames; - const std::vector modeNames; - const std::vector literalNames; - const std::vector symbolicNames; - const antlr4::dfa::Vocabulary vocabulary; - antlr4::atn::SerializedATNView serializedATN; - std::unique_ptr atn; +struct ExprLexerStaticData final { + ExprLexerStaticData(std::vector ruleNames, + std::vector channelNames, + std::vector modeNames, + std::vector literalNames, + std::vector symbolicNames) + : ruleNames(std::move(ruleNames)), channelNames(std::move(channelNames)), + modeNames(std::move(modeNames)), literalNames(std::move(literalNames)), + symbolicNames(std::move(symbolicNames)), + vocabulary(this->literalNames, this->symbolicNames) {} + + ExprLexerStaticData(const ExprLexerStaticData&) = delete; + ExprLexerStaticData(ExprLexerStaticData&&) = delete; + ExprLexerStaticData& operator=(const ExprLexerStaticData&) = delete; + ExprLexerStaticData& operator=(ExprLexerStaticData&&) = delete; + + std::vector decisionToDFA; + antlr4::atn::PredictionContextCache sharedContextCache; + const std::vector ruleNames; + const std::vector channelNames; + const std::vector modeNames; + const std::vector literalNames; + const std::vector symbolicNames; + const antlr4::dfa::Vocabulary vocabulary; + antlr4::atn::SerializedATNView serializedATN; + std::unique_ptr atn; }; ::antlr4::internal::OnceFlag exprlexerLexerOnceFlag; #if ANTLR4_USE_THREAD_LOCAL_CACHE static thread_local #endif - ExprLexerStaticData* exprlexerLexerStaticData - = nullptr; +ExprLexerStaticData *exprlexerLexerStaticData = nullptr; -void exprlexerLexerInitialize() -{ +void exprlexerLexerInitialize() { #if ANTLR4_USE_THREAD_LOCAL_CACHE - if (exprlexerLexerStaticData != nullptr) - { - return; - } + if (exprlexerLexerStaticData != nullptr) { + return; + } #else - assert(exprlexerLexerStaticData == nullptr); + assert(exprlexerLexerStaticData == nullptr); #endif - auto staticData = std::make_unique( - std::vector{"T__0", "T__1", "T__2", "T__3", "T__4", - "T__5", "T__6", "T__7", "T__8", "DIGIT", - "CHAR", "CHAR_OR_DIGIT", "NUMBER", "TIME", "IDENTIFIER", - "COMPARISON", "ADDSUB", "MULDIV", "LBRACKET", "RBRACKET", - "WS"}, - std::vector{"DEFAULT_TOKEN_CHANNEL", "HIDDEN"}, - std::vector{"DEFAULT_MODE"}, - std::vector{"", - "'+'", - "'-'", - "'/'", - "'*'", - "'.'", - "'('", - "')'", - "','", - "'..'", - "", - "'t'", - "", - "", - "", - "", - "'['", - "']'"}, - std::vector{"", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "NUMBER", - "TIME", - "IDENTIFIER", - "COMPARISON", - "ADDSUB", - "MULDIV", - "LBRACKET", - "RBRACKET", - "WS"}); - static const int32_t serializedATNSegment[] = { - 4, 0, 18, 111, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, - 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, - 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, - 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, - 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 1, 0, 1, 0, 1, - 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, - 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, - 10, 1, 10, 1, 11, 1, 11, 3, 11, 69, 8, 11, 1, 12, 4, 12, 72, 8, 12, - 11, 12, 12, 12, 73, 1, 12, 1, 12, 4, 12, 78, 8, 12, 11, 12, 12, 12, 79, - 3, 12, 82, 8, 12, 1, 13, 1, 13, 1, 14, 1, 14, 5, 14, 88, 8, 14, 10, - 14, 12, 14, 91, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 98, - 8, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, - 20, 1, 20, 1, 20, 1, 20, 0, 0, 21, 1, 1, 3, 2, 5, 3, 7, 4, 9, - 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 0, 21, 0, 23, 0, 25, 10, 27, 11, - 29, 12, 31, 13, 33, 14, 35, 15, 37, 16, 39, 17, 41, 18, 1, 0, 5, 1, 0, - 48, 57, 3, 0, 65, 90, 95, 95, 97, 122, 2, 0, 43, 43, 45, 45, 2, 0, 42, - 42, 47, 47, 3, 0, 9, 10, 13, 13, 32, 32, 114, 0, 1, 1, 0, 0, 0, 0, - 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, - 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, - 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, - 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, - 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, - 0, 41, 1, 0, 0, 0, 1, 43, 1, 0, 0, 0, 3, 45, 1, 0, 0, 0, 5, - 47, 1, 0, 0, 0, 7, 49, 1, 0, 0, 0, 9, 51, 1, 0, 0, 0, 11, 53, - 1, 0, 0, 0, 13, 55, 1, 0, 0, 0, 15, 57, 1, 0, 0, 0, 17, 59, 1, - 0, 0, 0, 19, 62, 1, 0, 0, 0, 21, 64, 1, 0, 0, 0, 23, 68, 1, 0, - 0, 0, 25, 71, 1, 0, 0, 0, 27, 83, 1, 0, 0, 0, 29, 85, 1, 0, 0, - 0, 31, 97, 1, 0, 0, 0, 33, 99, 1, 0, 0, 0, 35, 101, 1, 0, 0, 0, - 37, 103, 1, 0, 0, 0, 39, 105, 1, 0, 0, 0, 41, 107, 1, 0, 0, 0, 43, - 44, 5, 43, 0, 0, 44, 2, 1, 0, 0, 0, 45, 46, 5, 45, 0, 0, 46, 4, - 1, 0, 0, 0, 47, 48, 5, 47, 0, 0, 48, 6, 1, 0, 0, 0, 49, 50, 5, - 42, 0, 0, 50, 8, 1, 0, 0, 0, 51, 52, 5, 46, 0, 0, 52, 10, 1, 0, - 0, 0, 53, 54, 5, 40, 0, 0, 54, 12, 1, 0, 0, 0, 55, 56, 5, 41, 0, - 0, 56, 14, 1, 0, 0, 0, 57, 58, 5, 44, 0, 0, 58, 16, 1, 0, 0, 0, - 59, 60, 5, 46, 0, 0, 60, 61, 5, 46, 0, 0, 61, 18, 1, 0, 0, 0, 62, - 63, 7, 0, 0, 0, 63, 20, 1, 0, 0, 0, 64, 65, 7, 1, 0, 0, 65, 22, - 1, 0, 0, 0, 66, 69, 3, 21, 10, 0, 67, 69, 3, 19, 9, 0, 68, 66, 1, - 0, 0, 0, 68, 67, 1, 0, 0, 0, 69, 24, 1, 0, 0, 0, 70, 72, 3, 19, - 9, 0, 71, 70, 1, 0, 0, 0, 72, 73, 1, 0, 0, 0, 73, 71, 1, 0, 0, - 0, 73, 74, 1, 0, 0, 0, 74, 81, 1, 0, 0, 0, 75, 77, 5, 46, 0, 0, - 76, 78, 3, 19, 9, 0, 77, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, - 77, 1, 0, 0, 0, 79, 80, 1, 0, 0, 0, 80, 82, 1, 0, 0, 0, 81, 75, - 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 26, 1, 0, 0, 0, 83, 84, 5, - 116, 0, 0, 84, 28, 1, 0, 0, 0, 85, 89, 3, 21, 10, 0, 86, 88, 3, 23, - 11, 0, 87, 86, 1, 0, 0, 0, 88, 91, 1, 0, 0, 0, 89, 87, 1, 0, 0, - 0, 89, 90, 1, 0, 0, 0, 90, 30, 1, 0, 0, 0, 91, 89, 1, 0, 0, 0, - 92, 98, 5, 61, 0, 0, 93, 94, 5, 62, 0, 0, 94, 98, 5, 61, 0, 0, 95, - 96, 5, 60, 0, 0, 96, 98, 5, 61, 0, 0, 97, 92, 1, 0, 0, 0, 97, 93, - 1, 0, 0, 0, 97, 95, 1, 0, 0, 0, 98, 32, 1, 0, 0, 0, 99, 100, 7, - 2, 0, 0, 100, 34, 1, 0, 0, 0, 101, 102, 7, 3, 0, 0, 102, 36, 1, 0, - 0, 0, 103, 104, 5, 91, 0, 0, 104, 38, 1, 0, 0, 0, 105, 106, 5, 93, 0, - 0, 106, 40, 1, 0, 0, 0, 107, 108, 7, 4, 0, 0, 108, 109, 1, 0, 0, 0, - 109, 110, 6, 20, 0, 0, 110, 42, 1, 0, 0, 0, 7, 0, 68, 73, 79, 81, 89, - 97, 1, 6, 0, 0}; - staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, - sizeof(serializedATNSegment) - / sizeof(serializedATNSegment[0])); - - antlr4::atn::ATNDeserializer deserializer; - staticData->atn = deserializer.deserialize(staticData->serializedATN); - - const size_t count = staticData->atn->getNumberOfDecisions(); - staticData->decisionToDFA.reserve(count); - for (size_t i = 0; i < count; i++) - { - staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); + auto staticData = std::make_unique( + std::vector{ + "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", + "DIGIT", "CHAR", "CHAR_OR_DIGIT", "NUMBER", "TIME", "IDENTIFIER", + "COMPARISON", "ADDSUB", "MULDIV", "LBRACKET", "RBRACKET", "WS" + }, + std::vector{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }, + std::vector{ + "DEFAULT_MODE" + }, + std::vector{ + "", "'+'", "'-'", "'/'", "'*'", "'.'", "'('", "')'", "','", "'..'", + "", "'t'", "", "", "", "", "'['", "']'" + }, + std::vector{ + "", "", "", "", "", "", "", "", "", "", "NUMBER", "TIME", "IDENTIFIER", + "COMPARISON", "ADDSUB", "MULDIV", "LBRACKET", "RBRACKET", "WS" } - exprlexerLexerStaticData = staticData.release(); + ); + static const int32_t serializedATNSegment[] = { + 4,0,18,111,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14, + 7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20,7,20,1,0, + 1,0,1,1,1,1,1,2,1,2,1,3,1,3,1,4,1,4,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1,8,1, + 8,1,9,1,9,1,10,1,10,1,11,1,11,3,11,69,8,11,1,12,4,12,72,8,12,11,12,12, + 12,73,1,12,1,12,4,12,78,8,12,11,12,12,12,79,3,12,82,8,12,1,13,1,13,1, + 14,1,14,5,14,88,8,14,10,14,12,14,91,9,14,1,15,1,15,1,15,1,15,1,15,3,15, + 98,8,15,1,16,1,16,1,17,1,17,1,18,1,18,1,19,1,19,1,20,1,20,1,20,1,20,0, + 0,21,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,0,21,0,23,0,25,10,27, + 11,29,12,31,13,33,14,35,15,37,16,39,17,41,18,1,0,5,1,0,48,57,3,0,65,90, + 95,95,97,122,2,0,43,43,45,45,2,0,42,42,47,47,3,0,9,10,13,13,32,32,114, + 0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0, + 0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0, + 0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39, + 1,0,0,0,0,41,1,0,0,0,1,43,1,0,0,0,3,45,1,0,0,0,5,47,1,0,0,0,7,49,1,0, + 0,0,9,51,1,0,0,0,11,53,1,0,0,0,13,55,1,0,0,0,15,57,1,0,0,0,17,59,1,0, + 0,0,19,62,1,0,0,0,21,64,1,0,0,0,23,68,1,0,0,0,25,71,1,0,0,0,27,83,1,0, + 0,0,29,85,1,0,0,0,31,97,1,0,0,0,33,99,1,0,0,0,35,101,1,0,0,0,37,103,1, + 0,0,0,39,105,1,0,0,0,41,107,1,0,0,0,43,44,5,43,0,0,44,2,1,0,0,0,45,46, + 5,45,0,0,46,4,1,0,0,0,47,48,5,47,0,0,48,6,1,0,0,0,49,50,5,42,0,0,50,8, + 1,0,0,0,51,52,5,46,0,0,52,10,1,0,0,0,53,54,5,40,0,0,54,12,1,0,0,0,55, + 56,5,41,0,0,56,14,1,0,0,0,57,58,5,44,0,0,58,16,1,0,0,0,59,60,5,46,0,0, + 60,61,5,46,0,0,61,18,1,0,0,0,62,63,7,0,0,0,63,20,1,0,0,0,64,65,7,1,0, + 0,65,22,1,0,0,0,66,69,3,21,10,0,67,69,3,19,9,0,68,66,1,0,0,0,68,67,1, + 0,0,0,69,24,1,0,0,0,70,72,3,19,9,0,71,70,1,0,0,0,72,73,1,0,0,0,73,71, + 1,0,0,0,73,74,1,0,0,0,74,81,1,0,0,0,75,77,5,46,0,0,76,78,3,19,9,0,77, + 76,1,0,0,0,78,79,1,0,0,0,79,77,1,0,0,0,79,80,1,0,0,0,80,82,1,0,0,0,81, + 75,1,0,0,0,81,82,1,0,0,0,82,26,1,0,0,0,83,84,5,116,0,0,84,28,1,0,0,0, + 85,89,3,21,10,0,86,88,3,23,11,0,87,86,1,0,0,0,88,91,1,0,0,0,89,87,1,0, + 0,0,89,90,1,0,0,0,90,30,1,0,0,0,91,89,1,0,0,0,92,98,5,61,0,0,93,94,5, + 62,0,0,94,98,5,61,0,0,95,96,5,60,0,0,96,98,5,61,0,0,97,92,1,0,0,0,97, + 93,1,0,0,0,97,95,1,0,0,0,98,32,1,0,0,0,99,100,7,2,0,0,100,34,1,0,0,0, + 101,102,7,3,0,0,102,36,1,0,0,0,103,104,5,91,0,0,104,38,1,0,0,0,105,106, + 5,93,0,0,106,40,1,0,0,0,107,108,7,4,0,0,108,109,1,0,0,0,109,110,6,20, + 0,0,110,42,1,0,0,0,7,0,68,73,79,81,89,97,1,6,0,0 + }; + staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0])); + + antlr4::atn::ATNDeserializer deserializer; + staticData->atn = deserializer.deserialize(staticData->serializedATN); + + const size_t count = staticData->atn->getNumberOfDecisions(); + staticData->decisionToDFA.reserve(count); + for (size_t i = 0; i < count; i++) { + staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); + } + exprlexerLexerStaticData = staticData.release(); } -} // namespace +} -ExprLexer::ExprLexer(CharStream* input): - Lexer(input) -{ - ExprLexer::initialize(); - _interpreter = new atn::LexerATNSimulator(this, - *exprlexerLexerStaticData->atn, - exprlexerLexerStaticData->decisionToDFA, - exprlexerLexerStaticData->sharedContextCache); +ExprLexer::ExprLexer(CharStream *input) : Lexer(input) { + ExprLexer::initialize(); + _interpreter = new atn::LexerATNSimulator(this, *exprlexerLexerStaticData->atn, exprlexerLexerStaticData->decisionToDFA, exprlexerLexerStaticData->sharedContextCache); } -ExprLexer::~ExprLexer() -{ - delete _interpreter; +ExprLexer::~ExprLexer() { + delete _interpreter; } -std::string ExprLexer::getGrammarFileName() const -{ - return "Expr.g4"; +std::string ExprLexer::getGrammarFileName() const { + return "Expr.g4"; } -const std::vector& ExprLexer::getRuleNames() const -{ - return exprlexerLexerStaticData->ruleNames; +const std::vector& ExprLexer::getRuleNames() const { + return exprlexerLexerStaticData->ruleNames; } -const std::vector& ExprLexer::getChannelNames() const -{ - return exprlexerLexerStaticData->channelNames; +const std::vector& ExprLexer::getChannelNames() const { + return exprlexerLexerStaticData->channelNames; } -const std::vector& ExprLexer::getModeNames() const -{ - return exprlexerLexerStaticData->modeNames; +const std::vector& ExprLexer::getModeNames() const { + return exprlexerLexerStaticData->modeNames; } -const dfa::Vocabulary& ExprLexer::getVocabulary() const -{ - return exprlexerLexerStaticData->vocabulary; +const dfa::Vocabulary& ExprLexer::getVocabulary() const { + return exprlexerLexerStaticData->vocabulary; } -antlr4::atn::SerializedATNView ExprLexer::getSerializedATN() const -{ - return exprlexerLexerStaticData->serializedATN; +antlr4::atn::SerializedATNView ExprLexer::getSerializedATN() const { + return exprlexerLexerStaticData->serializedATN; } -const atn::ATN& ExprLexer::getATN() const -{ - return *exprlexerLexerStaticData->atn; +const atn::ATN& ExprLexer::getATN() const { + return *exprlexerLexerStaticData->atn; } -void ExprLexer::initialize() -{ + + + +void ExprLexer::initialize() { #if ANTLR4_USE_THREAD_LOCAL_CACHE - exprlexerLexerInitialize(); + exprlexerLexerInitialize(); #else - ::antlr4::internal::call_once(exprlexerLexerOnceFlag, exprlexerLexerInitialize); + ::antlr4::internal::call_once(exprlexerLexerOnceFlag, exprlexerLexerInitialize); #endif } diff --git a/src/libs/antares/antlr-interface/ExprLexer.h b/src/libs/antares/antlr-interface/ExprLexer.h index a569ec8d21..c7db2c5f77 100644 --- a/src/libs/antares/antlr-interface/ExprLexer.h +++ b/src/libs/antares/antlr-interface/ExprLexer.h @@ -3,58 +3,49 @@ #pragma once + #include "antlr4-runtime.h" -class ExprLexer: public antlr4::Lexer -{ + + + +class ExprLexer : public antlr4::Lexer { public: - enum - { - T__0 = 1, - T__1 = 2, - T__2 = 3, - T__3 = 4, - T__4 = 5, - T__5 = 6, - T__6 = 7, - T__7 = 8, - T__8 = 9, - NUMBER = 10, - TIME = 11, - IDENTIFIER = 12, - COMPARISON = 13, - ADDSUB = 14, - MULDIV = 15, - LBRACKET = 16, - RBRACKET = 17, - WS = 18 - }; + enum { + T__0 = 1, T__1 = 2, T__2 = 3, T__3 = 4, T__4 = 5, T__5 = 6, T__6 = 7, + T__7 = 8, T__8 = 9, NUMBER = 10, TIME = 11, IDENTIFIER = 12, COMPARISON = 13, + ADDSUB = 14, MULDIV = 15, LBRACKET = 16, RBRACKET = 17, WS = 18 + }; - explicit ExprLexer(antlr4::CharStream* input); + explicit ExprLexer(antlr4::CharStream *input); - ~ExprLexer() override; + ~ExprLexer() override; - std::string getGrammarFileName() const override; - const std::vector& getRuleNames() const override; + std::string getGrammarFileName() const override; - const std::vector& getChannelNames() const override; + const std::vector& getRuleNames() const override; - const std::vector& getModeNames() const override; + const std::vector& getChannelNames() const override; - const antlr4::dfa::Vocabulary& getVocabulary() const override; + const std::vector& getModeNames() const override; - antlr4::atn::SerializedATNView getSerializedATN() const override; + const antlr4::dfa::Vocabulary& getVocabulary() const override; - const antlr4::atn::ATN& getATN() const override; + antlr4::atn::SerializedATNView getSerializedATN() const override; - // By default the static state used to implement the lexer is lazily initialized during the - // first call to the constructor. You can call this function if you wish to initialize the - // static state ahead of time. - static void initialize(); + const antlr4::atn::ATN& getATN() const override; + + // By default the static state used to implement the lexer is lazily initialized during the first + // call to the constructor. You can call this function if you wish to initialize the static state + // ahead of time. + static void initialize(); private: - // Individual action functions triggered by action() above. - // Individual semantic predicate functions triggered by sempred() above. + // Individual action functions triggered by action() above. + + // Individual semantic predicate functions triggered by sempred() above. + }; + diff --git a/src/libs/antares/antlr-interface/ExprParser.cpp b/src/libs/antares/antlr-interface/ExprParser.cpp index 64335f4d82..3c688d96d3 100644 --- a/src/libs/antares/antlr-interface/ExprParser.cpp +++ b/src/libs/antares/antlr-interface/ExprParser.cpp @@ -1,1176 +1,884 @@ // Generated from Expr.g4 by ANTLR 4.13.1 -#include "ExprParser.h" #include "ExprVisitor.h" +#include "ExprParser.h" + + using namespace antlrcpp; using namespace antlr4; -namespace -{ +namespace { -struct ExprParserStaticData final -{ - ExprParserStaticData(std::vector ruleNames, - std::vector literalNames, - std::vector symbolicNames): - ruleNames(std::move(ruleNames)), - literalNames(std::move(literalNames)), +struct ExprParserStaticData final { + ExprParserStaticData(std::vector ruleNames, + std::vector literalNames, + std::vector symbolicNames) + : ruleNames(std::move(ruleNames)), literalNames(std::move(literalNames)), symbolicNames(std::move(symbolicNames)), - vocabulary(this->literalNames, this->symbolicNames) - { - } - - ExprParserStaticData(const ExprParserStaticData&) = delete; - ExprParserStaticData(ExprParserStaticData&&) = delete; - ExprParserStaticData& operator=(const ExprParserStaticData&) = delete; - ExprParserStaticData& operator=(ExprParserStaticData&&) = delete; - - std::vector decisionToDFA; - antlr4::atn::PredictionContextCache sharedContextCache; - const std::vector ruleNames; - const std::vector literalNames; - const std::vector symbolicNames; - const antlr4::dfa::Vocabulary vocabulary; - antlr4::atn::SerializedATNView serializedATN; - std::unique_ptr atn; + vocabulary(this->literalNames, this->symbolicNames) {} + + ExprParserStaticData(const ExprParserStaticData&) = delete; + ExprParserStaticData(ExprParserStaticData&&) = delete; + ExprParserStaticData& operator=(const ExprParserStaticData&) = delete; + ExprParserStaticData& operator=(ExprParserStaticData&&) = delete; + + std::vector decisionToDFA; + antlr4::atn::PredictionContextCache sharedContextCache; + const std::vector ruleNames; + const std::vector literalNames; + const std::vector symbolicNames; + const antlr4::dfa::Vocabulary vocabulary; + antlr4::atn::SerializedATNView serializedATN; + std::unique_ptr atn; }; ::antlr4::internal::OnceFlag exprParserOnceFlag; #if ANTLR4_USE_THREAD_LOCAL_CACHE static thread_local #endif - ExprParserStaticData* exprParserStaticData - = nullptr; +ExprParserStaticData *exprParserStaticData = nullptr; -void exprParserInitialize() -{ +void exprParserInitialize() { #if ANTLR4_USE_THREAD_LOCAL_CACHE - if (exprParserStaticData != nullptr) - { - return; - } + if (exprParserStaticData != nullptr) { + return; + } #else - assert(exprParserStaticData == nullptr); + assert(exprParserStaticData == nullptr); #endif - auto staticData = std::make_unique(std::vector{"fullexpr", - "shift", - "expr"}, - std::vector{"", - "'+'", - "'-'", - "'/'", - "'*'", - "'.'", - "'('", - "')'", - "','", - "'..'", - "", - "'t'", - "", - "", - "", - "", - "'['", - "']'"}, - std::vector{"", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "NUMBER", - "TIME", - "IDENTIFIER", - "COMPARISON", - "ADDSUB", - "MULDIV", - "LBRACKET", - "RBRACKET", - "WS"}); - static const int32_t serializedATNSegment[] = { - 4, 1, 18, 86, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 1, 0, 1, 0, 1, 0, 1, 1, - 1, 1, 1, 1, 3, 1, 13, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 5, 2, 37, 8, 2, 10, 2, 12, 2, 40, 9, 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 5, 2, 49, 8, 2, 10, 2, 12, 2, 52, 9, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 3, 2, 70, 8, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, - 1, 2, 5, 2, 81, 8, 2, 10, 2, 12, 2, 84, 9, 2, 1, 2, 0, 1, 4, 3, 0, 2, 4, 0, - 2, 1, 0, 1, 2, 1, 0, 3, 4, 97, 0, 6, 1, 0, 0, 0, 2, 9, 1, 0, 0, 0, 4, 69, - 1, 0, 0, 0, 6, 7, 3, 4, 2, 0, 7, 8, 5, 0, 0, 1, 8, 1, 1, 0, 0, 0, 9, 12, - 5, 11, 0, 0, 10, 11, 7, 0, 0, 0, 11, 13, 3, 4, 2, 0, 12, 10, 1, 0, 0, 0, 12, 13, - 1, 0, 0, 0, 13, 3, 1, 0, 0, 0, 14, 15, 6, 2, -1, 0, 15, 16, 5, 2, 0, 0, 16, 70, - 3, 4, 2, 13, 17, 70, 5, 12, 0, 0, 18, 19, 5, 12, 0, 0, 19, 20, 5, 5, 0, 0, 20, 70, - 5, 12, 0, 0, 21, 70, 5, 10, 0, 0, 22, 23, 5, 6, 0, 0, 23, 24, 3, 4, 2, 0, 24, 25, - 5, 7, 0, 0, 25, 70, 1, 0, 0, 0, 26, 27, 5, 12, 0, 0, 27, 28, 5, 6, 0, 0, 28, 29, - 3, 4, 2, 0, 29, 30, 5, 7, 0, 0, 30, 70, 1, 0, 0, 0, 31, 32, 5, 12, 0, 0, 32, 33, - 5, 16, 0, 0, 33, 38, 3, 2, 1, 0, 34, 35, 5, 8, 0, 0, 35, 37, 3, 2, 1, 0, 36, 34, - 1, 0, 0, 0, 37, 40, 1, 0, 0, 0, 38, 36, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, - 1, 0, 0, 0, 40, 38, 1, 0, 0, 0, 41, 42, 5, 17, 0, 0, 42, 70, 1, 0, 0, 0, 43, 44, - 5, 12, 0, 0, 44, 45, 5, 16, 0, 0, 45, 50, 3, 4, 2, 0, 46, 47, 5, 8, 0, 0, 47, 49, - 3, 4, 2, 0, 48, 46, 1, 0, 0, 0, 49, 52, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 51, - 1, 0, 0, 0, 51, 53, 1, 0, 0, 0, 52, 50, 1, 0, 0, 0, 53, 54, 5, 17, 0, 0, 54, 70, - 1, 0, 0, 0, 55, 56, 5, 12, 0, 0, 56, 57, 5, 16, 0, 0, 57, 58, 3, 2, 1, 0, 58, 59, - 5, 9, 0, 0, 59, 60, 3, 2, 1, 0, 60, 61, 5, 17, 0, 0, 61, 70, 1, 0, 0, 0, 62, 63, - 5, 12, 0, 0, 63, 64, 5, 16, 0, 0, 64, 65, 3, 4, 2, 0, 65, 66, 5, 9, 0, 0, 66, 67, - 3, 4, 2, 0, 67, 68, 5, 17, 0, 0, 68, 70, 1, 0, 0, 0, 69, 14, 1, 0, 0, 0, 69, 17, - 1, 0, 0, 0, 69, 18, 1, 0, 0, 0, 69, 21, 1, 0, 0, 0, 69, 22, 1, 0, 0, 0, 69, 26, - 1, 0, 0, 0, 69, 31, 1, 0, 0, 0, 69, 43, 1, 0, 0, 0, 69, 55, 1, 0, 0, 0, 69, 62, - 1, 0, 0, 0, 70, 82, 1, 0, 0, 0, 71, 72, 10, 12, 0, 0, 72, 73, 7, 1, 0, 0, 73, 81, - 3, 4, 2, 13, 74, 75, 10, 11, 0, 0, 75, 76, 7, 0, 0, 0, 76, 81, 3, 4, 2, 12, 77, 78, - 10, 10, 0, 0, 78, 79, 5, 13, 0, 0, 79, 81, 3, 4, 2, 11, 80, 71, 1, 0, 0, 0, 80, 74, - 1, 0, 0, 0, 80, 77, 1, 0, 0, 0, 81, 84, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, - 1, 0, 0, 0, 83, 5, 1, 0, 0, 0, 84, 82, 1, 0, 0, 0, 6, 12, 38, 50, 69, 80, 82}; - staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, - sizeof(serializedATNSegment) - / sizeof(serializedATNSegment[0])); - - antlr4::atn::ATNDeserializer deserializer; - staticData->atn = deserializer.deserialize(staticData->serializedATN); - - const size_t count = staticData->atn->getNumberOfDecisions(); - staticData->decisionToDFA.reserve(count); - for (size_t i = 0; i < count; i++) - { - staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); + auto staticData = std::make_unique( + std::vector{ + "fullexpr", "shift", "expr" + }, + std::vector{ + "", "'+'", "'-'", "'/'", "'*'", "'.'", "'('", "')'", "','", "'..'", + "", "'t'", "", "", "", "", "'['", "']'" + }, + std::vector{ + "", "", "", "", "", "", "", "", "", "", "NUMBER", "TIME", "IDENTIFIER", + "COMPARISON", "ADDSUB", "MULDIV", "LBRACKET", "RBRACKET", "WS" } - exprParserStaticData = staticData.release(); -} + ); + static const int32_t serializedATNSegment[] = { + 4,1,18,86,2,0,7,0,2,1,7,1,2,2,7,2,1,0,1,0,1,0,1,1,1,1,1,1,3,1,13,8,1, + 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1, + 2,1,2,1,2,1,2,1,2,5,2,37,8,2,10,2,12,2,40,9,2,1,2,1,2,1,2,1,2,1,2,1,2, + 1,2,5,2,49,8,2,10,2,12,2,52,9,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1, + 2,1,2,1,2,1,2,1,2,1,2,1,2,3,2,70,8,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2, + 1,2,5,2,81,8,2,10,2,12,2,84,9,2,1,2,0,1,4,3,0,2,4,0,2,1,0,1,2,1,0,3,4, + 97,0,6,1,0,0,0,2,9,1,0,0,0,4,69,1,0,0,0,6,7,3,4,2,0,7,8,5,0,0,1,8,1,1, + 0,0,0,9,12,5,11,0,0,10,11,7,0,0,0,11,13,3,4,2,0,12,10,1,0,0,0,12,13,1, + 0,0,0,13,3,1,0,0,0,14,15,6,2,-1,0,15,16,5,2,0,0,16,70,3,4,2,13,17,70, + 5,12,0,0,18,19,5,12,0,0,19,20,5,5,0,0,20,70,5,12,0,0,21,70,5,10,0,0,22, + 23,5,6,0,0,23,24,3,4,2,0,24,25,5,7,0,0,25,70,1,0,0,0,26,27,5,12,0,0,27, + 28,5,6,0,0,28,29,3,4,2,0,29,30,5,7,0,0,30,70,1,0,0,0,31,32,5,12,0,0,32, + 33,5,16,0,0,33,38,3,2,1,0,34,35,5,8,0,0,35,37,3,2,1,0,36,34,1,0,0,0,37, + 40,1,0,0,0,38,36,1,0,0,0,38,39,1,0,0,0,39,41,1,0,0,0,40,38,1,0,0,0,41, + 42,5,17,0,0,42,70,1,0,0,0,43,44,5,12,0,0,44,45,5,16,0,0,45,50,3,4,2,0, + 46,47,5,8,0,0,47,49,3,4,2,0,48,46,1,0,0,0,49,52,1,0,0,0,50,48,1,0,0,0, + 50,51,1,0,0,0,51,53,1,0,0,0,52,50,1,0,0,0,53,54,5,17,0,0,54,70,1,0,0, + 0,55,56,5,12,0,0,56,57,5,16,0,0,57,58,3,2,1,0,58,59,5,9,0,0,59,60,3,2, + 1,0,60,61,5,17,0,0,61,70,1,0,0,0,62,63,5,12,0,0,63,64,5,16,0,0,64,65, + 3,4,2,0,65,66,5,9,0,0,66,67,3,4,2,0,67,68,5,17,0,0,68,70,1,0,0,0,69,14, + 1,0,0,0,69,17,1,0,0,0,69,18,1,0,0,0,69,21,1,0,0,0,69,22,1,0,0,0,69,26, + 1,0,0,0,69,31,1,0,0,0,69,43,1,0,0,0,69,55,1,0,0,0,69,62,1,0,0,0,70,82, + 1,0,0,0,71,72,10,12,0,0,72,73,7,1,0,0,73,81,3,4,2,13,74,75,10,11,0,0, + 75,76,7,0,0,0,76,81,3,4,2,12,77,78,10,10,0,0,78,79,5,13,0,0,79,81,3,4, + 2,11,80,71,1,0,0,0,80,74,1,0,0,0,80,77,1,0,0,0,81,84,1,0,0,0,82,80,1, + 0,0,0,82,83,1,0,0,0,83,5,1,0,0,0,84,82,1,0,0,0,6,12,38,50,69,80,82 + }; + staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0])); + + antlr4::atn::ATNDeserializer deserializer; + staticData->atn = deserializer.deserialize(staticData->serializedATN); -} // namespace + const size_t count = staticData->atn->getNumberOfDecisions(); + staticData->decisionToDFA.reserve(count); + for (size_t i = 0; i < count; i++) { + staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); + } + exprParserStaticData = staticData.release(); +} -ExprParser::ExprParser(TokenStream* input): - ExprParser(input, antlr4::atn::ParserATNSimulatorOptions()) -{ } -ExprParser::ExprParser(TokenStream* input, const antlr4::atn::ParserATNSimulatorOptions& options): - Parser(input) -{ - ExprParser::initialize(); - _interpreter = new atn::ParserATNSimulator(this, - *exprParserStaticData->atn, - exprParserStaticData->decisionToDFA, - exprParserStaticData->sharedContextCache, - options); +ExprParser::ExprParser(TokenStream *input) : ExprParser(input, antlr4::atn::ParserATNSimulatorOptions()) {} + +ExprParser::ExprParser(TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options) : Parser(input) { + ExprParser::initialize(); + _interpreter = new atn::ParserATNSimulator(this, *exprParserStaticData->atn, exprParserStaticData->decisionToDFA, exprParserStaticData->sharedContextCache, options); } -ExprParser::~ExprParser() -{ - delete _interpreter; +ExprParser::~ExprParser() { + delete _interpreter; } -const atn::ATN& ExprParser::getATN() const -{ - return *exprParserStaticData->atn; +const atn::ATN& ExprParser::getATN() const { + return *exprParserStaticData->atn; } -std::string ExprParser::getGrammarFileName() const -{ - return "Expr.g4"; +std::string ExprParser::getGrammarFileName() const { + return "Expr.g4"; } -const std::vector& ExprParser::getRuleNames() const -{ - return exprParserStaticData->ruleNames; +const std::vector& ExprParser::getRuleNames() const { + return exprParserStaticData->ruleNames; } -const dfa::Vocabulary& ExprParser::getVocabulary() const -{ - return exprParserStaticData->vocabulary; +const dfa::Vocabulary& ExprParser::getVocabulary() const { + return exprParserStaticData->vocabulary; } -antlr4::atn::SerializedATNView ExprParser::getSerializedATN() const -{ - return exprParserStaticData->serializedATN; +antlr4::atn::SerializedATNView ExprParser::getSerializedATN() const { + return exprParserStaticData->serializedATN; } -//----------------- FullexprContext -//------------------------------------------------------------------ -ExprParser::FullexprContext::FullexprContext(ParserRuleContext* parent, size_t invokingState): - ParserRuleContext(parent, invokingState) -{ +//----------------- FullexprContext ------------------------------------------------------------------ + +ExprParser::FullexprContext::FullexprContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { } -ExprParser::ExprContext* ExprParser::FullexprContext::expr() -{ - return getRuleContext(0); +ExprParser::ExprContext* ExprParser::FullexprContext::expr() { + return getRuleContext(0); } -tree::TerminalNode* ExprParser::FullexprContext::EOF() -{ - return getToken(ExprParser::EOF, 0); +tree::TerminalNode* ExprParser::FullexprContext::EOF() { + return getToken(ExprParser::EOF, 0); } -size_t ExprParser::FullexprContext::getRuleIndex() const -{ - return ExprParser::RuleFullexpr; + +size_t ExprParser::FullexprContext::getRuleIndex() const { + return ExprParser::RuleFullexpr; } -std::any ExprParser::FullexprContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitFullexpr(this); - } - else - { - return visitor->visitChildren(this); - } + +std::any ExprParser::FullexprContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitFullexpr(this); + else + return visitor->visitChildren(this); } -ExprParser::FullexprContext* ExprParser::fullexpr() -{ - FullexprContext* _localctx = _tracker.createInstance(_ctx, getState()); - enterRule(_localctx, 0, ExprParser::RuleFullexpr); +ExprParser::FullexprContext* ExprParser::fullexpr() { + FullexprContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 0, ExprParser::RuleFullexpr); #if __cplusplus > 201703L - auto onExit = finally( - [=, this] - { + auto onExit = finally([=, this] { #else - auto onExit = finally( - [=] - { + auto onExit = finally([=] { #endif - exitRule(); - }); - try - { - enterOuterAlt(_localctx, 1); - setState(6); - expr(0); - setState(7); - match(ExprParser::EOF); - } - catch (RecognitionException& e) - { - _errHandler->reportError(this, e); - _localctx->exception = std::current_exception(); - _errHandler->recover(this, _localctx->exception); - } - - return _localctx; + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(6); + expr(0); + setState(7); + match(ExprParser::EOF); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; } //----------------- ShiftContext ------------------------------------------------------------------ -ExprParser::ShiftContext::ShiftContext(ParserRuleContext* parent, size_t invokingState): - ParserRuleContext(parent, invokingState) -{ +ExprParser::ShiftContext::ShiftContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { } -tree::TerminalNode* ExprParser::ShiftContext::TIME() -{ - return getToken(ExprParser::TIME, 0); +tree::TerminalNode* ExprParser::ShiftContext::TIME() { + return getToken(ExprParser::TIME, 0); } -ExprParser::ExprContext* ExprParser::ShiftContext::expr() -{ - return getRuleContext(0); +ExprParser::ExprContext* ExprParser::ShiftContext::expr() { + return getRuleContext(0); } -size_t ExprParser::ShiftContext::getRuleIndex() const -{ - return ExprParser::RuleShift; + +size_t ExprParser::ShiftContext::getRuleIndex() const { + return ExprParser::RuleShift; } -std::any ExprParser::ShiftContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitShift(this); - } - else - { - return visitor->visitChildren(this); - } + +std::any ExprParser::ShiftContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitShift(this); + else + return visitor->visitChildren(this); } -ExprParser::ShiftContext* ExprParser::shift() -{ - ShiftContext* _localctx = _tracker.createInstance(_ctx, getState()); - enterRule(_localctx, 2, ExprParser::RuleShift); - size_t _la = 0; +ExprParser::ShiftContext* ExprParser::shift() { + ShiftContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 2, ExprParser::RuleShift); + size_t _la = 0; #if __cplusplus > 201703L - auto onExit = finally( - [=, this] - { + auto onExit = finally([=, this] { #else - auto onExit = finally( - [=] - { + auto onExit = finally([=] { #endif - exitRule(); - }); - try - { - enterOuterAlt(_localctx, 1); - setState(9); - match(ExprParser::TIME); - setState(12); - _errHandler->sync(this); - - _la = _input->LA(1); - if (_la == ExprParser::T__0 - - || _la == ExprParser::T__1) - { - setState(10); - antlrcpp::downCast(_localctx)->op = _input->LT(1); - _la = _input->LA(1); - if (!(_la == ExprParser::T__0 - - || _la == ExprParser::T__1)) - { - antlrcpp::downCast(_localctx)->op = _errHandler->recoverInline(this); - } - else - { - _errHandler->reportMatch(this); - consume(); - } - setState(11); - expr(0); - } - } - catch (RecognitionException& e) - { - _errHandler->reportError(this, e); - _localctx->exception = std::current_exception(); - _errHandler->recover(this, _localctx->exception); - } - - return _localctx; + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(9); + match(ExprParser::TIME); + setState(12); + _errHandler->sync(this); + + _la = _input->LA(1); + if (_la == ExprParser::T__0 + + || _la == ExprParser::T__1) { + setState(10); + antlrcpp::downCast(_localctx)->op = _input->LT(1); + _la = _input->LA(1); + if (!(_la == ExprParser::T__0 + + || _la == ExprParser::T__1)) { + antlrcpp::downCast(_localctx)->op = _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + setState(11); + expr(0); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; } //----------------- ExprContext ------------------------------------------------------------------ -ExprParser::ExprContext::ExprContext(ParserRuleContext* parent, size_t invokingState): - ParserRuleContext(parent, invokingState) -{ +ExprParser::ExprContext::ExprContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { } -size_t ExprParser::ExprContext::getRuleIndex() const -{ - return ExprParser::RuleExpr; -} -void ExprParser::ExprContext::copyFrom(ExprContext* ctx) -{ - ParserRuleContext::copyFrom(ctx); +size_t ExprParser::ExprContext::getRuleIndex() const { + return ExprParser::RuleExpr; } -//----------------- IdentifierContext -//------------------------------------------------------------------ - -tree::TerminalNode* ExprParser::IdentifierContext::IDENTIFIER() -{ - return getToken(ExprParser::IDENTIFIER, 0); +void ExprParser::ExprContext::copyFrom(ExprContext *ctx) { + ParserRuleContext::copyFrom(ctx); } -ExprParser::IdentifierContext::IdentifierContext(ExprContext* ctx) -{ - copyFrom(ctx); -} +//----------------- IdentifierContext ------------------------------------------------------------------ -std::any ExprParser::IdentifierContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitIdentifier(this); - } - else - { - return visitor->visitChildren(this); - } +tree::TerminalNode* ExprParser::IdentifierContext::IDENTIFIER() { + return getToken(ExprParser::IDENTIFIER, 0); } -//----------------- NegationContext -//------------------------------------------------------------------ +ExprParser::IdentifierContext::IdentifierContext(ExprContext *ctx) { copyFrom(ctx); } -ExprParser::ExprContext* ExprParser::NegationContext::expr() -{ - return getRuleContext(0); -} -ExprParser::NegationContext::NegationContext(ExprContext* ctx) -{ - copyFrom(ctx); +std::any ExprParser::IdentifierContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitIdentifier(this); + else + return visitor->visitChildren(this); } +//----------------- NegationContext ------------------------------------------------------------------ -std::any ExprParser::NegationContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitNegation(this); - } - else - { - return visitor->visitChildren(this); - } +ExprParser::ExprContext* ExprParser::NegationContext::expr() { + return getRuleContext(0); } -//----------------- ExpressionContext -//------------------------------------------------------------------ +ExprParser::NegationContext::NegationContext(ExprContext *ctx) { copyFrom(ctx); } -ExprParser::ExprContext* ExprParser::ExpressionContext::expr() -{ - return getRuleContext(0); -} -ExprParser::ExpressionContext::ExpressionContext(ExprContext* ctx) -{ - copyFrom(ctx); +std::any ExprParser::NegationContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitNegation(this); + else + return visitor->visitChildren(this); } +//----------------- ExpressionContext ------------------------------------------------------------------ -std::any ExprParser::ExpressionContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitExpression(this); - } - else - { - return visitor->visitChildren(this); - } +ExprParser::ExprContext* ExprParser::ExpressionContext::expr() { + return getRuleContext(0); } -//----------------- ComparisonContext -//------------------------------------------------------------------ +ExprParser::ExpressionContext::ExpressionContext(ExprContext *ctx) { copyFrom(ctx); } -std::vector ExprParser::ComparisonContext::expr() -{ - return getRuleContexts(); -} -ExprParser::ExprContext* ExprParser::ComparisonContext::expr(size_t i) -{ - return getRuleContext(i); +std::any ExprParser::ExpressionContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitExpression(this); + else + return visitor->visitChildren(this); } +//----------------- ComparisonContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::ComparisonContext::COMPARISON() -{ - return getToken(ExprParser::COMPARISON, 0); +std::vector ExprParser::ComparisonContext::expr() { + return getRuleContexts(); } -ExprParser::ComparisonContext::ComparisonContext(ExprContext* ctx) -{ - copyFrom(ctx); +ExprParser::ExprContext* ExprParser::ComparisonContext::expr(size_t i) { + return getRuleContext(i); } -std::any ExprParser::ComparisonContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitComparison(this); - } - else - { - return visitor->visitChildren(this); - } +tree::TerminalNode* ExprParser::ComparisonContext::COMPARISON() { + return getToken(ExprParser::COMPARISON, 0); } -//----------------- AddsubContext ------------------------------------------------------------------ +ExprParser::ComparisonContext::ComparisonContext(ExprContext *ctx) { copyFrom(ctx); } -std::vector ExprParser::AddsubContext::expr() -{ - return getRuleContexts(); -} -ExprParser::ExprContext* ExprParser::AddsubContext::expr(size_t i) -{ - return getRuleContext(i); +std::any ExprParser::ComparisonContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitComparison(this); + else + return visitor->visitChildren(this); } +//----------------- AddsubContext ------------------------------------------------------------------ -ExprParser::AddsubContext::AddsubContext(ExprContext* ctx) -{ - copyFrom(ctx); +std::vector ExprParser::AddsubContext::expr() { + return getRuleContexts(); } -std::any ExprParser::AddsubContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitAddsub(this); - } - else - { - return visitor->visitChildren(this); - } +ExprParser::ExprContext* ExprParser::AddsubContext::expr(size_t i) { + return getRuleContext(i); } -//----------------- PortFieldContext -//------------------------------------------------------------------ +ExprParser::AddsubContext::AddsubContext(ExprContext *ctx) { copyFrom(ctx); } -std::vector ExprParser::PortFieldContext::IDENTIFIER() -{ - return getTokens(ExprParser::IDENTIFIER); -} -tree::TerminalNode* ExprParser::PortFieldContext::IDENTIFIER(size_t i) -{ - return getToken(ExprParser::IDENTIFIER, i); +std::any ExprParser::AddsubContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitAddsub(this); + else + return visitor->visitChildren(this); } +//----------------- PortFieldContext ------------------------------------------------------------------ -ExprParser::PortFieldContext::PortFieldContext(ExprContext* ctx) -{ - copyFrom(ctx); +std::vector ExprParser::PortFieldContext::IDENTIFIER() { + return getTokens(ExprParser::IDENTIFIER); } -std::any ExprParser::PortFieldContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitPortField(this); - } - else - { - return visitor->visitChildren(this); - } +tree::TerminalNode* ExprParser::PortFieldContext::IDENTIFIER(size_t i) { + return getToken(ExprParser::IDENTIFIER, i); } -//----------------- MuldivContext ------------------------------------------------------------------ +ExprParser::PortFieldContext::PortFieldContext(ExprContext *ctx) { copyFrom(ctx); } -std::vector ExprParser::MuldivContext::expr() -{ - return getRuleContexts(); -} -ExprParser::ExprContext* ExprParser::MuldivContext::expr(size_t i) -{ - return getRuleContext(i); +std::any ExprParser::PortFieldContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitPortField(this); + else + return visitor->visitChildren(this); } +//----------------- MuldivContext ------------------------------------------------------------------ -ExprParser::MuldivContext::MuldivContext(ExprContext* ctx) -{ - copyFrom(ctx); +std::vector ExprParser::MuldivContext::expr() { + return getRuleContexts(); } -std::any ExprParser::MuldivContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitMuldiv(this); - } - else - { - return visitor->visitChildren(this); - } +ExprParser::ExprContext* ExprParser::MuldivContext::expr(size_t i) { + return getRuleContext(i); } -//----------------- NumberContext ------------------------------------------------------------------ +ExprParser::MuldivContext::MuldivContext(ExprContext *ctx) { copyFrom(ctx); } -tree::TerminalNode* ExprParser::NumberContext::NUMBER() -{ - return getToken(ExprParser::NUMBER, 0); -} -ExprParser::NumberContext::NumberContext(ExprContext* ctx) -{ - copyFrom(ctx); +std::any ExprParser::MuldivContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitMuldiv(this); + else + return visitor->visitChildren(this); } +//----------------- NumberContext ------------------------------------------------------------------ -std::any ExprParser::NumberContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitNumber(this); - } - else - { - return visitor->visitChildren(this); - } +tree::TerminalNode* ExprParser::NumberContext::NUMBER() { + return getToken(ExprParser::NUMBER, 0); } -//----------------- TimeIndexContext -//------------------------------------------------------------------ +ExprParser::NumberContext::NumberContext(ExprContext *ctx) { copyFrom(ctx); } -tree::TerminalNode* ExprParser::TimeIndexContext::IDENTIFIER() -{ - return getToken(ExprParser::IDENTIFIER, 0); -} -tree::TerminalNode* ExprParser::TimeIndexContext::LBRACKET() -{ - return getToken(ExprParser::LBRACKET, 0); +std::any ExprParser::NumberContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitNumber(this); + else + return visitor->visitChildren(this); } +//----------------- TimeIndexContext ------------------------------------------------------------------ -std::vector ExprParser::TimeIndexContext::expr() -{ - return getRuleContexts(); +tree::TerminalNode* ExprParser::TimeIndexContext::IDENTIFIER() { + return getToken(ExprParser::IDENTIFIER, 0); } -ExprParser::ExprContext* ExprParser::TimeIndexContext::expr(size_t i) -{ - return getRuleContext(i); +tree::TerminalNode* ExprParser::TimeIndexContext::LBRACKET() { + return getToken(ExprParser::LBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeIndexContext::RBRACKET() -{ - return getToken(ExprParser::RBRACKET, 0); +std::vector ExprParser::TimeIndexContext::expr() { + return getRuleContexts(); } -ExprParser::TimeIndexContext::TimeIndexContext(ExprContext* ctx) -{ - copyFrom(ctx); +ExprParser::ExprContext* ExprParser::TimeIndexContext::expr(size_t i) { + return getRuleContext(i); } -std::any ExprParser::TimeIndexContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitTimeIndex(this); - } - else - { - return visitor->visitChildren(this); - } +tree::TerminalNode* ExprParser::TimeIndexContext::RBRACKET() { + return getToken(ExprParser::RBRACKET, 0); } -//----------------- TimeShiftContext -//------------------------------------------------------------------ +ExprParser::TimeIndexContext::TimeIndexContext(ExprContext *ctx) { copyFrom(ctx); } -tree::TerminalNode* ExprParser::TimeShiftContext::IDENTIFIER() -{ - return getToken(ExprParser::IDENTIFIER, 0); -} -tree::TerminalNode* ExprParser::TimeShiftContext::LBRACKET() -{ - return getToken(ExprParser::LBRACKET, 0); +std::any ExprParser::TimeIndexContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitTimeIndex(this); + else + return visitor->visitChildren(this); } +//----------------- TimeShiftContext ------------------------------------------------------------------ -std::vector ExprParser::TimeShiftContext::shift() -{ - return getRuleContexts(); +tree::TerminalNode* ExprParser::TimeShiftContext::IDENTIFIER() { + return getToken(ExprParser::IDENTIFIER, 0); } -ExprParser::ShiftContext* ExprParser::TimeShiftContext::shift(size_t i) -{ - return getRuleContext(i); +tree::TerminalNode* ExprParser::TimeShiftContext::LBRACKET() { + return getToken(ExprParser::LBRACKET, 0); } -tree::TerminalNode* ExprParser::TimeShiftContext::RBRACKET() -{ - return getToken(ExprParser::RBRACKET, 0); +std::vector ExprParser::TimeShiftContext::shift() { + return getRuleContexts(); } -ExprParser::TimeShiftContext::TimeShiftContext(ExprContext* ctx) -{ - copyFrom(ctx); +ExprParser::ShiftContext* ExprParser::TimeShiftContext::shift(size_t i) { + return getRuleContext(i); } -std::any ExprParser::TimeShiftContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitTimeShift(this); - } - else - { - return visitor->visitChildren(this); - } +tree::TerminalNode* ExprParser::TimeShiftContext::RBRACKET() { + return getToken(ExprParser::RBRACKET, 0); } -//----------------- FunctionContext -//------------------------------------------------------------------ +ExprParser::TimeShiftContext::TimeShiftContext(ExprContext *ctx) { copyFrom(ctx); } -tree::TerminalNode* ExprParser::FunctionContext::IDENTIFIER() -{ - return getToken(ExprParser::IDENTIFIER, 0); -} -ExprParser::ExprContext* ExprParser::FunctionContext::expr() -{ - return getRuleContext(0); +std::any ExprParser::TimeShiftContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitTimeShift(this); + else + return visitor->visitChildren(this); } +//----------------- FunctionContext ------------------------------------------------------------------ -ExprParser::FunctionContext::FunctionContext(ExprContext* ctx) -{ - copyFrom(ctx); +tree::TerminalNode* ExprParser::FunctionContext::IDENTIFIER() { + return getToken(ExprParser::IDENTIFIER, 0); } -std::any ExprParser::FunctionContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitFunction(this); - } - else - { - return visitor->visitChildren(this); - } +ExprParser::ExprContext* ExprParser::FunctionContext::expr() { + return getRuleContext(0); } -//----------------- TimeShiftRangeContext -//------------------------------------------------------------------ +ExprParser::FunctionContext::FunctionContext(ExprContext *ctx) { copyFrom(ctx); } -tree::TerminalNode* ExprParser::TimeShiftRangeContext::IDENTIFIER() -{ - return getToken(ExprParser::IDENTIFIER, 0); -} -tree::TerminalNode* ExprParser::TimeShiftRangeContext::LBRACKET() -{ - return getToken(ExprParser::LBRACKET, 0); +std::any ExprParser::FunctionContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitFunction(this); + else + return visitor->visitChildren(this); } +//----------------- TimeShiftRangeContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::TimeShiftRangeContext::RBRACKET() -{ - return getToken(ExprParser::RBRACKET, 0); +tree::TerminalNode* ExprParser::TimeShiftRangeContext::IDENTIFIER() { + return getToken(ExprParser::IDENTIFIER, 0); } -std::vector ExprParser::TimeShiftRangeContext::shift() -{ - return getRuleContexts(); +tree::TerminalNode* ExprParser::TimeShiftRangeContext::LBRACKET() { + return getToken(ExprParser::LBRACKET, 0); } -ExprParser::ShiftContext* ExprParser::TimeShiftRangeContext::shift(size_t i) -{ - return getRuleContext(i); +tree::TerminalNode* ExprParser::TimeShiftRangeContext::RBRACKET() { + return getToken(ExprParser::RBRACKET, 0); } -ExprParser::TimeShiftRangeContext::TimeShiftRangeContext(ExprContext* ctx) -{ - copyFrom(ctx); +std::vector ExprParser::TimeShiftRangeContext::shift() { + return getRuleContexts(); } -std::any ExprParser::TimeShiftRangeContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitTimeShiftRange(this); - } - else - { - return visitor->visitChildren(this); - } +ExprParser::ShiftContext* ExprParser::TimeShiftRangeContext::shift(size_t i) { + return getRuleContext(i); } -//----------------- TimeRangeContext -//------------------------------------------------------------------ +ExprParser::TimeShiftRangeContext::TimeShiftRangeContext(ExprContext *ctx) { copyFrom(ctx); } -tree::TerminalNode* ExprParser::TimeRangeContext::IDENTIFIER() -{ - return getToken(ExprParser::IDENTIFIER, 0); + +std::any ExprParser::TimeShiftRangeContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitTimeShiftRange(this); + else + return visitor->visitChildren(this); } +//----------------- TimeRangeContext ------------------------------------------------------------------ -tree::TerminalNode* ExprParser::TimeRangeContext::LBRACKET() -{ - return getToken(ExprParser::LBRACKET, 0); +tree::TerminalNode* ExprParser::TimeRangeContext::IDENTIFIER() { + return getToken(ExprParser::IDENTIFIER, 0); } -std::vector ExprParser::TimeRangeContext::expr() -{ - return getRuleContexts(); +tree::TerminalNode* ExprParser::TimeRangeContext::LBRACKET() { + return getToken(ExprParser::LBRACKET, 0); } -ExprParser::ExprContext* ExprParser::TimeRangeContext::expr(size_t i) -{ - return getRuleContext(i); +std::vector ExprParser::TimeRangeContext::expr() { + return getRuleContexts(); } -tree::TerminalNode* ExprParser::TimeRangeContext::RBRACKET() -{ - return getToken(ExprParser::RBRACKET, 0); +ExprParser::ExprContext* ExprParser::TimeRangeContext::expr(size_t i) { + return getRuleContext(i); } -ExprParser::TimeRangeContext::TimeRangeContext(ExprContext* ctx) -{ - copyFrom(ctx); +tree::TerminalNode* ExprParser::TimeRangeContext::RBRACKET() { + return getToken(ExprParser::RBRACKET, 0); } -std::any ExprParser::TimeRangeContext::accept(tree::ParseTreeVisitor* visitor) -{ - if (auto parserVisitor = dynamic_cast(visitor)) - { - return parserVisitor->visitTimeRange(this); - } - else - { - return visitor->visitChildren(this); - } +ExprParser::TimeRangeContext::TimeRangeContext(ExprContext *ctx) { copyFrom(ctx); } + + +std::any ExprParser::TimeRangeContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitTimeRange(this); + else + return visitor->visitChildren(this); } -ExprParser::ExprContext* ExprParser::expr() -{ - return expr(0); +ExprParser::ExprContext* ExprParser::expr() { + return expr(0); } -ExprParser::ExprContext* ExprParser::expr(int precedence) -{ - ParserRuleContext* parentContext = _ctx; - size_t parentState = getState(); - ExprParser::ExprContext* _localctx = _tracker.createInstance(_ctx, parentState); - ExprParser::ExprContext* previousContext = _localctx; - (void)previousContext; // Silence compiler, in case the context is not used by generated code. - size_t startState = 4; - enterRecursionRule(_localctx, 4, ExprParser::RuleExpr, precedence); +ExprParser::ExprContext* ExprParser::expr(int precedence) { + ParserRuleContext *parentContext = _ctx; + size_t parentState = getState(); + ExprParser::ExprContext *_localctx = _tracker.createInstance(_ctx, parentState); + ExprParser::ExprContext *previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. + size_t startState = 4; + enterRecursionRule(_localctx, 4, ExprParser::RuleExpr, precedence); size_t _la = 0; #if __cplusplus > 201703L - auto onExit = finally( - [=, this] - { + auto onExit = finally([=, this] { #else - auto onExit = finally( - [=] - { + auto onExit = finally([=] { #endif - unrollRecursionContexts(parentContext); - }); - try - { - size_t alt; - enterOuterAlt(_localctx, 1); - setState(69); + unrollRecursionContexts(parentContext); + }); + try { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(69); + _errHandler->sync(this); + switch (getInterpreter()->adaptivePredict(_input, 3, _ctx)) { + case 1: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + + setState(15); + match(ExprParser::T__1); + setState(16); + expr(13); + break; + } + + case 2: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(17); + match(ExprParser::IDENTIFIER); + break; + } + + case 3: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(18); + match(ExprParser::IDENTIFIER); + setState(19); + match(ExprParser::T__4); + setState(20); + match(ExprParser::IDENTIFIER); + break; + } + + case 4: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(21); + match(ExprParser::NUMBER); + break; + } + + case 5: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(22); + match(ExprParser::T__5); + setState(23); + expr(0); + setState(24); + match(ExprParser::T__6); + break; + } + + case 6: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(26); + match(ExprParser::IDENTIFIER); + setState(27); + match(ExprParser::T__5); + setState(28); + expr(0); + setState(29); + match(ExprParser::T__6); + break; + } + + case 7: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(31); + match(ExprParser::IDENTIFIER); + setState(32); + match(ExprParser::LBRACKET); + setState(33); + shift(); + setState(38); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == ExprParser::T__7) { + setState(34); + match(ExprParser::T__7); + setState(35); + shift(); + setState(40); _errHandler->sync(this); - switch (getInterpreter()->adaptivePredict(_input, 3, _ctx)) - { - case 1: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - - setState(15); - match(ExprParser::T__1); - setState(16); - expr(13); - break; - } - - case 2: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(17); - match(ExprParser::IDENTIFIER); - break; - } - - case 3: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(18); - match(ExprParser::IDENTIFIER); - setState(19); - match(ExprParser::T__4); - setState(20); - match(ExprParser::IDENTIFIER); - break; - } - - case 4: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(21); - match(ExprParser::NUMBER); - break; - } - - case 5: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(22); - match(ExprParser::T__5); - setState(23); - expr(0); - setState(24); - match(ExprParser::T__6); - break; - } - - case 6: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(26); - match(ExprParser::IDENTIFIER); - setState(27); - match(ExprParser::T__5); - setState(28); - expr(0); - setState(29); - match(ExprParser::T__6); - break; - } - - case 7: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(31); - match(ExprParser::IDENTIFIER); - setState(32); - match(ExprParser::LBRACKET); - setState(33); - shift(); - setState(38); - _errHandler->sync(this); - _la = _input->LA(1); - while (_la == ExprParser::T__7) - { - setState(34); - match(ExprParser::T__7); - setState(35); - shift(); - setState(40); - _errHandler->sync(this); - _la = _input->LA(1); - } - setState(41); - match(ExprParser::RBRACKET); - break; - } + _la = _input->LA(1); + } + setState(41); + match(ExprParser::RBRACKET); + break; + } + + case 8: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(43); + match(ExprParser::IDENTIFIER); + setState(44); + match(ExprParser::LBRACKET); + setState(45); + expr(0); + setState(50); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == ExprParser::T__7) { + setState(46); + match(ExprParser::T__7); + setState(47); + expr(0); + setState(52); + _errHandler->sync(this); + _la = _input->LA(1); + } + setState(53); + match(ExprParser::RBRACKET); + break; + } + + case 9: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(55); + match(ExprParser::IDENTIFIER); + setState(56); + match(ExprParser::LBRACKET); + setState(57); + antlrcpp::downCast(_localctx)->shift1 = shift(); + setState(58); + match(ExprParser::T__8); + setState(59); + antlrcpp::downCast(_localctx)->shift2 = shift(); + setState(60); + match(ExprParser::RBRACKET); + break; + } + + case 10: { + _localctx = _tracker.createInstance(_localctx); + _ctx = _localctx; + previousContext = _localctx; + setState(62); + match(ExprParser::IDENTIFIER); + setState(63); + match(ExprParser::LBRACKET); + setState(64); + expr(0); + setState(65); + match(ExprParser::T__8); + setState(66); + expr(0); + setState(67); + match(ExprParser::RBRACKET); + break; + } - case 8: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(43); - match(ExprParser::IDENTIFIER); - setState(44); - match(ExprParser::LBRACKET); - setState(45); - expr(0); - setState(50); - _errHandler->sync(this); - _la = _input->LA(1); - while (_la == ExprParser::T__7) - { - setState(46); - match(ExprParser::T__7); - setState(47); - expr(0); - setState(52); - _errHandler->sync(this); - _la = _input->LA(1); - } - setState(53); - match(ExprParser::RBRACKET); - break; + default: + break; + } + _ctx->stop = _input->LT(-1); + setState(82); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 5, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1) { + if (!_parseListeners.empty()) + triggerExitRuleEvent(); + previousContext = _localctx; + setState(80); + _errHandler->sync(this); + switch (getInterpreter()->adaptivePredict(_input, 4, _ctx)) { + case 1: { + auto newContext = _tracker.createInstance(_tracker.createInstance(parentContext, parentState)); + _localctx = newContext; + pushNewRecursionContext(newContext, startState, RuleExpr); + setState(71); + + if (!(precpred(_ctx, 12))) throw FailedPredicateException(this, "precpred(_ctx, 12)"); + setState(72); + antlrcpp::downCast(_localctx)->op = _input->LT(1); + _la = _input->LA(1); + if (!(_la == ExprParser::T__2 + + || _la == ExprParser::T__3)) { + antlrcpp::downCast(_localctx)->op = _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + setState(73); + expr(13); + break; } - case 9: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(55); - match(ExprParser::IDENTIFIER); - setState(56); - match(ExprParser::LBRACKET); - setState(57); - antlrcpp::downCast(_localctx)->shift1 = shift(); - setState(58); - match(ExprParser::T__8); - setState(59); - antlrcpp::downCast(_localctx)->shift2 = shift(); - setState(60); - match(ExprParser::RBRACKET); - break; + case 2: { + auto newContext = _tracker.createInstance(_tracker.createInstance(parentContext, parentState)); + _localctx = newContext; + pushNewRecursionContext(newContext, startState, RuleExpr); + setState(74); + + if (!(precpred(_ctx, 11))) throw FailedPredicateException(this, "precpred(_ctx, 11)"); + setState(75); + antlrcpp::downCast(_localctx)->op = _input->LT(1); + _la = _input->LA(1); + if (!(_la == ExprParser::T__0 + + || _la == ExprParser::T__1)) { + antlrcpp::downCast(_localctx)->op = _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + setState(76); + expr(12); + break; } - case 10: - { - _localctx = _tracker.createInstance(_localctx); - _ctx = _localctx; - previousContext = _localctx; - setState(62); - match(ExprParser::IDENTIFIER); - setState(63); - match(ExprParser::LBRACKET); - setState(64); - expr(0); - setState(65); - match(ExprParser::T__8); - setState(66); - expr(0); - setState(67); - match(ExprParser::RBRACKET); - break; + case 3: { + auto newContext = _tracker.createInstance(_tracker.createInstance(parentContext, parentState)); + _localctx = newContext; + pushNewRecursionContext(newContext, startState, RuleExpr); + setState(77); + + if (!(precpred(_ctx, 10))) throw FailedPredicateException(this, "precpred(_ctx, 10)"); + setState(78); + match(ExprParser::COMPARISON); + setState(79); + expr(11); + break; } default: - break; - } - _ctx->stop = _input->LT(-1); - setState(82); - _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 5, _ctx); - while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) - { - if (alt == 1) - { - if (!_parseListeners.empty()) - { - triggerExitRuleEvent(); - } - previousContext = _localctx; - setState(80); - _errHandler->sync(this); - switch (getInterpreter()->adaptivePredict(_input, 4, _ctx)) - { - case 1: - { - auto newContext = _tracker.createInstance( - _tracker.createInstance(parentContext, parentState)); - _localctx = newContext; - pushNewRecursionContext(newContext, startState, RuleExpr); - setState(71); - - if (!(precpred(_ctx, 12))) - { - throw FailedPredicateException(this, "precpred(_ctx, 12)"); - } - setState(72); - antlrcpp::downCast(_localctx)->op = _input->LT(1); - _la = _input->LA(1); - if (!(_la == ExprParser::T__2 - - || _la == ExprParser::T__3)) - { - antlrcpp::downCast(_localctx)->op = _errHandler - ->recoverInline(this); - } - else - { - _errHandler->reportMatch(this); - consume(); - } - setState(73); - expr(13); - break; - } - - case 2: - { - auto newContext = _tracker.createInstance( - _tracker.createInstance(parentContext, parentState)); - _localctx = newContext; - pushNewRecursionContext(newContext, startState, RuleExpr); - setState(74); - - if (!(precpred(_ctx, 11))) - { - throw FailedPredicateException(this, "precpred(_ctx, 11)"); - } - setState(75); - antlrcpp::downCast(_localctx)->op = _input->LT(1); - _la = _input->LA(1); - if (!(_la == ExprParser::T__0 - - || _la == ExprParser::T__1)) - { - antlrcpp::downCast(_localctx)->op = _errHandler - ->recoverInline(this); - } - else - { - _errHandler->reportMatch(this); - consume(); - } - setState(76); - expr(12); - break; - } - - case 3: - { - auto newContext = _tracker.createInstance( - _tracker.createInstance(parentContext, parentState)); - _localctx = newContext; - pushNewRecursionContext(newContext, startState, RuleExpr); - setState(77); - - if (!(precpred(_ctx, 10))) - { - throw FailedPredicateException(this, "precpred(_ctx, 10)"); - } - setState(78); - match(ExprParser::COMPARISON); - setState(79); - expr(11); - break; - } - - default: - break; - } - } - setState(84); - _errHandler->sync(this); - alt = getInterpreter()->adaptivePredict(_input, 5, _ctx); - } - } - catch (RecognitionException& e) - { - _errHandler->reportError(this, e); - _localctx->exception = std::current_exception(); - _errHandler->recover(this, _localctx->exception); + break; + } + } + setState(84); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 5, _ctx); } - return _localctx; + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + return _localctx; } -bool ExprParser::sempred(RuleContext* context, size_t ruleIndex, size_t predicateIndex) -{ - switch (ruleIndex) - { - case 2: - return exprSempred(antlrcpp::downCast(context), predicateIndex); +bool ExprParser::sempred(RuleContext *context, size_t ruleIndex, size_t predicateIndex) { + switch (ruleIndex) { + case 2: return exprSempred(antlrcpp::downCast(context), predicateIndex); - default: - break; - } - return true; + default: + break; + } + return true; } -bool ExprParser::exprSempred(ExprContext* _localctx, size_t predicateIndex) -{ - switch (predicateIndex) - { - case 0: - return precpred(_ctx, 12); - case 1: - return precpred(_ctx, 11); - case 2: - return precpred(_ctx, 10); +bool ExprParser::exprSempred(ExprContext *_localctx, size_t predicateIndex) { + switch (predicateIndex) { + case 0: return precpred(_ctx, 12); + case 1: return precpred(_ctx, 11); + case 2: return precpred(_ctx, 10); - default: - break; - } - return true; + default: + break; + } + return true; } -void ExprParser::initialize() -{ +void ExprParser::initialize() { #if ANTLR4_USE_THREAD_LOCAL_CACHE - exprParserInitialize(); + exprParserInitialize(); #else - ::antlr4::internal::call_once(exprParserOnceFlag, exprParserInitialize); + ::antlr4::internal::call_once(exprParserOnceFlag, exprParserInitialize); #endif } diff --git a/src/libs/antares/antlr-interface/ExprParser.h b/src/libs/antares/antlr-interface/ExprParser.h index 6573ea2b2d..aa1c8b6f09 100644 --- a/src/libs/antares/antlr-interface/ExprParser.h +++ b/src/libs/antares/antlr-interface/ExprParser.h @@ -3,266 +3,242 @@ #pragma once + #include "antlr4-runtime.h" -class ExprParser: public antlr4::Parser -{ + + + +class ExprParser : public antlr4::Parser { public: - enum - { - T__0 = 1, - T__1 = 2, - T__2 = 3, - T__3 = 4, - T__4 = 5, - T__5 = 6, - T__6 = 7, - T__7 = 8, - T__8 = 9, - NUMBER = 10, - TIME = 11, - IDENTIFIER = 12, - COMPARISON = 13, - ADDSUB = 14, - MULDIV = 15, - LBRACKET = 16, - RBRACKET = 17, - WS = 18 - }; - - enum - { - RuleFullexpr = 0, - RuleShift = 1, - RuleExpr = 2 - }; - - explicit ExprParser(antlr4::TokenStream* input); + enum { + T__0 = 1, T__1 = 2, T__2 = 3, T__3 = 4, T__4 = 5, T__5 = 6, T__6 = 7, + T__7 = 8, T__8 = 9, NUMBER = 10, TIME = 11, IDENTIFIER = 12, COMPARISON = 13, + ADDSUB = 14, MULDIV = 15, LBRACKET = 16, RBRACKET = 17, WS = 18 + }; + + enum { + RuleFullexpr = 0, RuleShift = 1, RuleExpr = 2 + }; + + explicit ExprParser(antlr4::TokenStream *input); + + ExprParser(antlr4::TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options); + + ~ExprParser() override; + + std::string getGrammarFileName() const override; + + const antlr4::atn::ATN& getATN() const override; + + const std::vector& getRuleNames() const override; - ExprParser(antlr4::TokenStream* input, const antlr4::atn::ParserATNSimulatorOptions& options); - - ~ExprParser() override; + const antlr4::dfa::Vocabulary& getVocabulary() const override; - std::string getGrammarFileName() const override; - - const antlr4::atn::ATN& getATN() const override; + antlr4::atn::SerializedATNView getSerializedATN() const override; - const std::vector& getRuleNames() const override; - - const antlr4::dfa::Vocabulary& getVocabulary() const override; - antlr4::atn::SerializedATNView getSerializedATN() const override; - - class FullexprContext; - class ShiftContext; - class ExprContext; - - class FullexprContext: public antlr4::ParserRuleContext - { - public: - FullexprContext(antlr4::ParserRuleContext* parent, size_t invokingState); - virtual size_t getRuleIndex() const override; - ExprContext* expr(); - antlr4::tree::TerminalNode* EOF(); - - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; - - FullexprContext* fullexpr(); + class FullexprContext; + class ShiftContext; + class ExprContext; - class ShiftContext: public antlr4::ParserRuleContext - { - public: - antlr4::Token* op = nullptr; - ShiftContext(antlr4::ParserRuleContext* parent, size_t invokingState); - virtual size_t getRuleIndex() const override; - antlr4::tree::TerminalNode* TIME(); - ExprContext* expr(); + class FullexprContext : public antlr4::ParserRuleContext { + public: + FullexprContext(antlr4::ParserRuleContext *parent, size_t invokingState); + virtual size_t getRuleIndex() const override; + ExprContext *expr(); + antlr4::tree::TerminalNode *EOF(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; - ShiftContext* shift(); + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + + }; - class ExprContext: public antlr4::ParserRuleContext - { - public: - ExprContext(antlr4::ParserRuleContext* parent, size_t invokingState); + FullexprContext* fullexpr(); - ExprContext() = default; - void copyFrom(ExprContext* context); - using antlr4::ParserRuleContext::copyFrom; - - virtual size_t getRuleIndex() const override; - }; - - class IdentifierContext: public ExprContext - { - public: - IdentifierContext(ExprContext* ctx); - - antlr4::tree::TerminalNode* IDENTIFIER(); + class ShiftContext : public antlr4::ParserRuleContext { + public: + antlr4::Token *op = nullptr; + ShiftContext(antlr4::ParserRuleContext *parent, size_t invokingState); + virtual size_t getRuleIndex() const override; + antlr4::tree::TerminalNode *TIME(); + ExprContext *expr(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; - - class NegationContext: public ExprContext - { - public: - NegationContext(ExprContext* ctx); - ExprContext* expr(); + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + + }; - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + ShiftContext* shift(); - class ExpressionContext: public ExprContext - { - public: - ExpressionContext(ExprContext* ctx); + class ExprContext : public antlr4::ParserRuleContext { + public: + ExprContext(antlr4::ParserRuleContext *parent, size_t invokingState); + + ExprContext() = default; + void copyFrom(ExprContext *context); + using antlr4::ParserRuleContext::copyFrom; - ExprContext* expr(); + virtual size_t getRuleIndex() const override; - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + + }; - class ComparisonContext: public ExprContext - { - public: - ComparisonContext(ExprContext* ctx); + class IdentifierContext : public ExprContext { + public: + IdentifierContext(ExprContext *ctx); - std::vector expr(); - ExprContext* expr(size_t i); - antlr4::tree::TerminalNode* COMPARISON(); + antlr4::tree::TerminalNode *IDENTIFIER(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class AddsubContext: public ExprContext - { - public: - AddsubContext(ExprContext* ctx); + class NegationContext : public ExprContext { + public: + NegationContext(ExprContext *ctx); - antlr4::Token* op = nullptr; - std::vector expr(); - ExprContext* expr(size_t i); + ExprContext *expr(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class PortFieldContext: public ExprContext - { - public: - PortFieldContext(ExprContext* ctx); + class ExpressionContext : public ExprContext { + public: + ExpressionContext(ExprContext *ctx); - std::vector IDENTIFIER(); - antlr4::tree::TerminalNode* IDENTIFIER(size_t i); + ExprContext *expr(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class MuldivContext: public ExprContext - { - public: - MuldivContext(ExprContext* ctx); + class ComparisonContext : public ExprContext { + public: + ComparisonContext(ExprContext *ctx); - antlr4::Token* op = nullptr; - std::vector expr(); - ExprContext* expr(size_t i); + std::vector expr(); + ExprContext* expr(size_t i); + antlr4::tree::TerminalNode *COMPARISON(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class NumberContext: public ExprContext - { - public: - NumberContext(ExprContext* ctx); + class AddsubContext : public ExprContext { + public: + AddsubContext(ExprContext *ctx); - antlr4::tree::TerminalNode* NUMBER(); + antlr4::Token *op = nullptr; + std::vector expr(); + ExprContext* expr(size_t i); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class TimeIndexContext: public ExprContext - { - public: - TimeIndexContext(ExprContext* ctx); + class PortFieldContext : public ExprContext { + public: + PortFieldContext(ExprContext *ctx); - antlr4::tree::TerminalNode* IDENTIFIER(); - antlr4::tree::TerminalNode* LBRACKET(); - std::vector expr(); - ExprContext* expr(size_t i); - antlr4::tree::TerminalNode* RBRACKET(); + std::vector IDENTIFIER(); + antlr4::tree::TerminalNode* IDENTIFIER(size_t i); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class TimeShiftContext: public ExprContext - { - public: - TimeShiftContext(ExprContext* ctx); + class MuldivContext : public ExprContext { + public: + MuldivContext(ExprContext *ctx); - antlr4::tree::TerminalNode* IDENTIFIER(); - antlr4::tree::TerminalNode* LBRACKET(); - std::vector shift(); - ShiftContext* shift(size_t i); - antlr4::tree::TerminalNode* RBRACKET(); + antlr4::Token *op = nullptr; + std::vector expr(); + ExprContext* expr(size_t i); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class FunctionContext: public ExprContext - { - public: - FunctionContext(ExprContext* ctx); + class NumberContext : public ExprContext { + public: + NumberContext(ExprContext *ctx); - antlr4::tree::TerminalNode* IDENTIFIER(); - ExprContext* expr(); + antlr4::tree::TerminalNode *NUMBER(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class TimeShiftRangeContext: public ExprContext - { - public: - TimeShiftRangeContext(ExprContext* ctx); + class TimeIndexContext : public ExprContext { + public: + TimeIndexContext(ExprContext *ctx); - ExprParser::ShiftContext* shift1 = nullptr; - ExprParser::ShiftContext* shift2 = nullptr; - antlr4::tree::TerminalNode* IDENTIFIER(); - antlr4::tree::TerminalNode* LBRACKET(); - antlr4::tree::TerminalNode* RBRACKET(); - std::vector shift(); - ShiftContext* shift(size_t i); + antlr4::tree::TerminalNode *IDENTIFIER(); + antlr4::tree::TerminalNode *LBRACKET(); + std::vector expr(); + ExprContext* expr(size_t i); + antlr4::tree::TerminalNode *RBRACKET(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - class TimeRangeContext: public ExprContext - { - public: - TimeRangeContext(ExprContext* ctx); + class TimeShiftContext : public ExprContext { + public: + TimeShiftContext(ExprContext *ctx); - antlr4::tree::TerminalNode* IDENTIFIER(); - antlr4::tree::TerminalNode* LBRACKET(); - std::vector expr(); - ExprContext* expr(size_t i); - antlr4::tree::TerminalNode* RBRACKET(); + antlr4::tree::TerminalNode *IDENTIFIER(); + antlr4::tree::TerminalNode *LBRACKET(); + std::vector shift(); + ShiftContext* shift(size_t i); + antlr4::tree::TerminalNode *RBRACKET(); - virtual std::any accept(antlr4::tree::ParseTreeVisitor* visitor) override; - }; + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - ExprContext* expr(); - ExprContext* expr(int precedence); + class FunctionContext : public ExprContext { + public: + FunctionContext(ExprContext *ctx); - bool sempred(antlr4::RuleContext* _localctx, size_t ruleIndex, size_t predicateIndex) override; + antlr4::tree::TerminalNode *IDENTIFIER(); + ExprContext *expr(); - bool exprSempred(ExprContext* _localctx, size_t predicateIndex); + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; - // By default the static state used to implement the parser is lazily initialized during the - // first call to the constructor. You can call this function if you wish to initialize the - // static state ahead of time. - static void initialize(); + class TimeShiftRangeContext : public ExprContext { + public: + TimeShiftRangeContext(ExprContext *ctx); + + ExprParser::ShiftContext *shift1 = nullptr; + ExprParser::ShiftContext *shift2 = nullptr; + antlr4::tree::TerminalNode *IDENTIFIER(); + antlr4::tree::TerminalNode *LBRACKET(); + antlr4::tree::TerminalNode *RBRACKET(); + std::vector shift(); + ShiftContext* shift(size_t i); + + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; + + class TimeRangeContext : public ExprContext { + public: + TimeRangeContext(ExprContext *ctx); + + antlr4::tree::TerminalNode *IDENTIFIER(); + antlr4::tree::TerminalNode *LBRACKET(); + std::vector expr(); + ExprContext* expr(size_t i); + antlr4::tree::TerminalNode *RBRACKET(); + + virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override; + }; + + ExprContext* expr(); + ExprContext* expr(int precedence); + + bool sempred(antlr4::RuleContext *_localctx, size_t ruleIndex, size_t predicateIndex) override; + + bool exprSempred(ExprContext *_localctx, size_t predicateIndex); + + // By default the static state used to implement the parser is lazily initialized during the first + // call to the constructor. You can call this function if you wish to initialize the static state + // ahead of time. + static void initialize(); private: }; + diff --git a/src/libs/antares/antlr-interface/ExprVisitor.cpp b/src/libs/antares/antlr-interface/ExprVisitor.cpp index bf0de76765..c214f0f76f 100644 --- a/src/libs/antares/antlr-interface/ExprVisitor.cpp +++ b/src/libs/antares/antlr-interface/ExprVisitor.cpp @@ -1,4 +1,7 @@ // Generated from Expr.g4 by ANTLR 4.13.1 + #include "ExprVisitor.h" + + diff --git a/src/libs/antares/antlr-interface/ExprVisitor.h b/src/libs/antares/antlr-interface/ExprVisitor.h index 6caed416f5..c064d6d54a 100644 --- a/src/libs/antares/antlr-interface/ExprVisitor.h +++ b/src/libs/antares/antlr-interface/ExprVisitor.h @@ -3,46 +3,52 @@ #pragma once -#include "ExprParser.h" + #include "antlr4-runtime.h" +#include "ExprParser.h" + + /** * This class defines an abstract visitor for a parse tree * produced by ExprParser. */ -class ExprVisitor: public antlr4::tree::AbstractParseTreeVisitor -{ +class ExprVisitor : public antlr4::tree::AbstractParseTreeVisitor { public: - /** - * Visit parse trees produced by ExprParser. - */ - virtual std::any visitFullexpr(ExprParser::FullexprContext* context) = 0; - virtual std::any visitShift(ExprParser::ShiftContext* context) = 0; + /** + * Visit parse trees produced by ExprParser. + */ + virtual std::any visitFullexpr(ExprParser::FullexprContext *context) = 0; - virtual std::any visitIdentifier(ExprParser::IdentifierContext* context) = 0; + virtual std::any visitShift(ExprParser::ShiftContext *context) = 0; - virtual std::any visitNegation(ExprParser::NegationContext* context) = 0; + virtual std::any visitIdentifier(ExprParser::IdentifierContext *context) = 0; - virtual std::any visitExpression(ExprParser::ExpressionContext* context) = 0; + virtual std::any visitNegation(ExprParser::NegationContext *context) = 0; - virtual std::any visitComparison(ExprParser::ComparisonContext* context) = 0; + virtual std::any visitExpression(ExprParser::ExpressionContext *context) = 0; - virtual std::any visitAddsub(ExprParser::AddsubContext* context) = 0; + virtual std::any visitComparison(ExprParser::ComparisonContext *context) = 0; - virtual std::any visitPortField(ExprParser::PortFieldContext* context) = 0; + virtual std::any visitAddsub(ExprParser::AddsubContext *context) = 0; - virtual std::any visitMuldiv(ExprParser::MuldivContext* context) = 0; + virtual std::any visitPortField(ExprParser::PortFieldContext *context) = 0; - virtual std::any visitNumber(ExprParser::NumberContext* context) = 0; + virtual std::any visitMuldiv(ExprParser::MuldivContext *context) = 0; - virtual std::any visitTimeIndex(ExprParser::TimeIndexContext* context) = 0; + virtual std::any visitNumber(ExprParser::NumberContext *context) = 0; - virtual std::any visitTimeShift(ExprParser::TimeShiftContext* context) = 0; + virtual std::any visitTimeIndex(ExprParser::TimeIndexContext *context) = 0; - virtual std::any visitFunction(ExprParser::FunctionContext* context) = 0; + virtual std::any visitTimeShift(ExprParser::TimeShiftContext *context) = 0; + + virtual std::any visitFunction(ExprParser::FunctionContext *context) = 0; + + virtual std::any visitTimeShiftRange(ExprParser::TimeShiftRangeContext *context) = 0; + + virtual std::any visitTimeRange(ExprParser::TimeRangeContext *context) = 0; - virtual std::any visitTimeShiftRange(ExprParser::TimeShiftRangeContext* context) = 0; - virtual std::any visitTimeRange(ExprParser::TimeRangeContext* context) = 0; }; + diff --git a/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h b/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h index 62352390bc..113451410f 100644 --- a/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h +++ b/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h @@ -28,6 +28,7 @@ void checkOrtoolsUsage(Antares::Data::UnitCommitmentMode ucMode, bool ortoolsUsed, const std::string& solverName); + void checkStudyVersion(const AnyString& optStudyFolder); void checkSimplexRangeHydroPricing(Antares::Data::SimplexOptimization optRange, diff --git a/src/libs/antares/exception/include/antares/exception/LoadingError.hpp b/src/libs/antares/exception/include/antares/exception/LoadingError.hpp index c79b1a791e..ab1ae664d8 100644 --- a/src/libs/antares/exception/include/antares/exception/LoadingError.hpp +++ b/src/libs/antares/exception/include/antares/exception/LoadingError.hpp @@ -130,14 +130,13 @@ class InvalidSolver: public LoadingError explicit InvalidSolver(const std::string& solver, const std::string& availableSolverList); }; -class InvalidSolverSpecificParameters: public LoadingError +class InvalidSolverSpecificParameters : public LoadingError { public: - explicit InvalidSolverSpecificParameters(const std::string& solver, - const std::string& specificParameters); + explicit InvalidSolverSpecificParameters(const std::string& solver, const std::string& specificParameters); }; -class InvalidStudy: public LoadingError +class InvalidStudy : public LoadingError { public: explicit InvalidStudy(const Yuni::String& study); diff --git a/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h b/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h index 7b46a95c3a..687afa12ae 100644 --- a/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h +++ b/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h @@ -31,7 +31,6 @@ namespace Data { class Study; } - /** * @class FileTreeStudyLoader * @brief A class to load studies from the file tree. diff --git a/src/libs/antares/inifile/include/antares/inifile/inifile.hxx b/src/libs/antares/inifile/include/antares/inifile/inifile.hxx index 20498c3ee2..64785d1ece 100644 --- a/src/libs/antares/inifile/include/antares/inifile/inifile.hxx +++ b/src/libs/antares/inifile/include/antares/inifile/inifile.hxx @@ -32,8 +32,7 @@ inline bool IniFile::empty() const return not firstSection; } -inline IniFile::Section::Section(const AnyString& name): - name(name) +inline IniFile::Section::Section(const AnyString& name): name(name) { } diff --git a/src/libs/antares/inifile/inifile.cpp b/src/libs/antares/inifile/inifile.cpp index 8cfa6b9607..67190a0654 100644 --- a/src/libs/antares/inifile/inifile.cpp +++ b/src/libs/antares/inifile/inifile.cpp @@ -65,8 +65,9 @@ void IniFile::Section::saveToStream(std::ostream& stream_out, uint64_t& written) stream_out << '[' << name << "]\n"; written += 4 /* []\n\n */ + name.size(); - each([&stream_out, &written](const IniFile::Property& p) - { p.saveToStream(stream_out, written); }); + each([&stream_out, &written](const IniFile::Property& p) { + p.saveToStream(stream_out, written); + }); stream_out << '\n'; } @@ -248,7 +249,7 @@ bool IniFile::open(const fs::path& filename, bool warnings) if (std::ifstream file(filename); file.is_open()) { - if (!readStream(file)) + if (! readStream(file)) { logs.error() << "Invalid INI file : " << filename; return false; @@ -265,8 +266,9 @@ bool IniFile::open(const fs::path& filename, bool warnings) void IniFile::saveToStream(std::ostream& stream_out, uint64_t& written) const { - each([&stream_out, &written](const IniFile::Section& s) - { s.saveToStream(stream_out, written); }); + each([&stream_out, &written](const IniFile::Section& s) { + s.saveToStream(stream_out, written); + }); if (written != 0) { diff --git a/src/libs/antares/io/file.cpp b/src/libs/antares/io/file.cpp index 8ef66b3a3d..10bf5b30b9 100644 --- a/src/libs/antares/io/file.cpp +++ b/src/libs/antares/io/file.cpp @@ -27,13 +27,13 @@ #ifdef YUNI_OS_WINDOWS #include - #include #else #include #include #endif #include + #include #include diff --git a/src/libs/antares/io/include/antares/io/file.h b/src/libs/antares/io/include/antares/io/file.h index b401b1cece..e9fd0e91dc 100644 --- a/src/libs/antares/io/include/antares/io/file.h +++ b/src/libs/antares/io/include/antares/io/file.h @@ -21,10 +21,10 @@ #ifndef __LIBS_ANTARES_IO_FILE_H__ #define __LIBS_ANTARES_IO_FILE_H__ -#include - #include +#include + namespace Antares::IO { /*! diff --git a/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h b/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h index 7d6f25373b..9b4c710ed4 100644 --- a/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h +++ b/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h @@ -29,7 +29,6 @@ namespace Data { class Study; } - /** * @class IStudyLoader * @brief The IStudyLoader class is an interface for loading studies. diff --git a/src/libs/antares/study/area/area.cpp b/src/libs/antares/study/area/area.cpp index fe2b2b7b75..da99f973ae 100644 --- a/src/libs/antares/study/area/area.cpp +++ b/src/libs/antares/study/area/area.cpp @@ -52,20 +52,19 @@ Area::Area(): internalInitialize(); } -Area::Area(const AnyString& name): - Area() +Area::Area(const AnyString& name) : Area() { internalInitialize(); this->name = name; this->id = Antares::transformNameIntoID(this->name); } -Area::Area(const AnyString& name, const AnyString& id): - Area() +Area::Area(const AnyString& name, const AnyString& id) : Area() { internalInitialize(); this->name = name; this->id = Antares::transformNameIntoID(id); + } Area::~Area() diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 3523643328..40da9df149 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -142,8 +142,8 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { const std::string idprepro = std::string(from->id) + "/" + std::string(with->id); - tsGeneration.prepro = std::make_unique(idprepro, - tsGeneration.unitCount); + tsGeneration.prepro = + std::make_unique(idprepro, tsGeneration.unitCount); bool anyFileWasLoaded = false; @@ -157,10 +157,10 @@ bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { anyFileWasLoaded = true; tsGeneration.valid = tsGeneration.prepro->data.loadFromCSVFile( - filepath.string(), - Antares::Data::PreproAvailability::preproAvailabilityMax, - DAYS_PER_YEAR) - && tsGeneration.prepro->validate(); + filepath.string(), + Antares::Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && tsGeneration.prepro->validate(); } // Modulation @@ -170,7 +170,7 @@ bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { anyFileWasLoaded = true; tsGeneration.valid &= tsGeneration.modulationCapacityDirect - .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); } filepath = preproFile; @@ -179,7 +179,7 @@ bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { anyFileWasLoaded = true; tsGeneration.valid &= tsGeneration.modulationCapacityIndirect - .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); } if (anyFileWasLoaded) @@ -506,8 +506,11 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) return false; } -bool handleTSGenKey(Data::LinkTsGeneration& out, const std::string& key, const String& value) +bool handleTSGenKey(Data::LinkTsGeneration& out, + const std::string& key, + const String& value) { + if (key == "unitcount") { return value.to(out.unitCount); @@ -569,11 +572,7 @@ bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const } } // anonymous namespace -bool AreaLinksLoadFromFolder(Study& study, - AreaList* l, - Area* area, - const fs::path& folder, - bool loadTSGen) +bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::path& folder, bool loadTSGen) { // Assert assert(area); diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index 181159933b..f76afb5686 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -968,9 +968,8 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, ret = hydroSeries->LoadMaxPower(area.id, buffer) && ret; } - hydroSeries->resizeTSinDeratedMode(study.parameters.derated, - studyVersion, - study.usedByTheSolver); + hydroSeries->resizeTSinDeratedMode( + study.parameters.derated, studyVersion, study.usedByTheSolver); } // Wind @@ -1279,7 +1278,7 @@ Area* AreaList::findFromPosition(const int x, const int y) const { auto lastArea = i->second; if (lastArea->ui && std::abs(lastArea->ui->x - x) < nearestDistance - && std::abs(lastArea->ui->y - y) < nearestDistance) + && std::abs(lastArea->ui->y - y) < nearestDistance) { nearestItem = lastArea; } @@ -1327,14 +1326,12 @@ void AreaListEnsureDataLoadPrepro(AreaList* l) /* Asserts */ assert(l); - l->each( - [](Data::Area& area) - { - if (!area.load.prepro) - { - area.load.prepro = new Antares::Data::Load::Prepro(); - } - }); + l->each([](Data::Area& area) { + if (!area.load.prepro) + { + area.load.prepro = new Antares::Data::Load::Prepro(); + } + }); } void AreaListEnsureDataSolarPrepro(AreaList* l) diff --git a/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp b/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp index b29ad4fba2..ff181e7ed8 100644 --- a/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp +++ b/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp @@ -60,9 +60,7 @@ bool BindingConstraintGroupRepository::buildFrom(const BindingConstraintsReposit bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const { - bool allConsistent = !std::ranges::any_of( - groups_, - [](const auto& group) + bool allConsistent = !std::ranges::any_of(groups_, [](const auto& group) { const auto& constraints = group->constraints(); if (constraints.empty()) @@ -70,8 +68,7 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const return false; } auto width = (*constraints.begin())->RHSTimeSeries().width; - bool isConsistent = std::ranges::all_of( - constraints, + bool isConsistent = std::ranges::all_of(constraints, [&width](const std::shared_ptr& bc) { bool sameWidth = bc->RHSTimeSeries().width == width; @@ -92,16 +89,15 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const void BindingConstraintGroupRepository::resizeAllTimeseriesNumbers(unsigned int nb_years) { - std::ranges::for_each(groups_, - [&nb_years](auto& group) { group->timeseriesNumbers.reset(nb_years); }); + std::ranges::for_each(groups_, [&nb_years](auto& group) + { group->timeseriesNumbers.reset(nb_years); }); } BindingConstraintGroup* BindingConstraintGroupRepository::operator[](const std::string& name) const { - if (auto group = std::ranges::find_if(groups_, - [&name](auto& group_of_constraint) - { return group_of_constraint->name() == name; }); - group != groups_.end()) + if (auto group = std::ranges::find_if(groups_, [&name](auto& group_of_constraint) + { return group_of_constraint->name() == name; }); + group != groups_.end()) { return group->get(); } diff --git a/src/libs/antares/study/cleaner/cleaner-v20.cpp b/src/libs/antares/study/cleaner/cleaner-v20.cpp index 3fa46cf4b5..7d1aadf58e 100644 --- a/src/libs/antares/study/cleaner/cleaner-v20.cpp +++ b/src/libs/antares/study/cleaner/cleaner-v20.cpp @@ -391,6 +391,7 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) buffer.clear() << infos->folder << "/input/bindingconstraints/bindingconstraints.ini"; if (ini.open(buffer)) { + ini.each( [&e](const IniFile::Section& section) { diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index 1eacc026bb..791e20f865 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -504,7 +504,8 @@ class Parameters final private: //! Load data from an INI file - bool loadFromINI(const IniFile& ini, const StudyVersion& version); + bool loadFromINI(const IniFile& ini, + const StudyVersion& version); void resetPlayedYears(uint nbOfYears); diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index 9d80ce4369..e09970b79c 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -22,7 +22,6 @@ #define __ANTARES_LIBS_STUDY_PARTS_HYDRO_CONTAINER_H__ #include - #include "../../fwd.h" #include "allocation.h" #include "prepro.h" @@ -179,7 +178,9 @@ class PartHydro // As this function can be called a lot of times, we pass working variables and returned variables // as arguments, so that we don't have to create them locally (as in a classical function) each // time. -double getWaterValue(const double& level, const Matrix& waterValues, const uint day); +double getWaterValue(const double& level, + const Matrix& waterValues, + const uint day); // Interpolates a rate from the credit modulation table according to a level double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */, diff --git a/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h index b5cb21073d..42aff6336a 100644 --- a/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h +++ b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h @@ -21,9 +21,8 @@ #ifndef __LIBS_STUDY_SCENARIO_BUILDER_DATA_HYDRO_LEVELS_H__ #define __LIBS_STUDY_SCENARIO_BUILDER_DATA_HYDRO_LEVELS_H__ -#include - #include "scBuilderDataInterface.h" +#include namespace Antares { diff --git a/src/libs/antares/study/include/antares/study/sets.hxx b/src/libs/antares/study/include/antares/study/sets.hxx index df1f9cff93..d2976252cc 100644 --- a/src/libs/antares/study/include/antares/study/sets.hxx +++ b/src/libs/antares/study/include/antares/study/sets.hxx @@ -288,8 +288,8 @@ bool Sets::loadFromFile(const std::filesystem::path& filename) continue; } - logs.warning() << "sets: `" << filename << "`: Invalid property `" << p->key - << '\''; + logs.warning() << "sets: `" << filename << "`: Invalid property `" + << p->key << '\''; } // Add the new group diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index 2f4c0b30b1..7337b9c8b0 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -1109,16 +1109,10 @@ static bool SGDIntLoadFamily_Legacy(Parameters& d, if (key == "initial-reservoir-levels") // ignored since 9.2 { - if (version >= StudyVersion(9, 2)) - { - logs.warning() - << "Option initial-reservoir-levels is deprecated, please remove it from the study"; - } + if (version >= StudyVersion(9,2)) + logs.warning() << "Option initial-reservoir-levels is deprecated, please remove it from the study"; else if (value == "hot start") - { - logs.warning() - << "Hydro hot start not supported with this solver, please use a version < 9.2"; - } + logs.warning() << "Hydro hot start not supported with this solver, please use a version < 9.2"; return true; } @@ -1131,7 +1125,8 @@ bool firstKeyLetterIsValid(const String& name) return (firstLetter >= 'a' && firstLetter <= 'z'); } -bool Parameters::loadFromINI(const IniFile& ini, const StudyVersion& version) +bool Parameters::loadFromINI(const IniFile& ini, + const StudyVersion& version) { // Reset inner data reset(); @@ -1297,9 +1292,7 @@ void Parameters::fixBadValues() } if (simulationDays.first == 0) - { simulationDays.first = 1; - } else { simulationDays.first = std::clamp(simulationDays.first, 1u, 365u); diff --git a/src/libs/antares/study/parts/common/cluster_list.cpp b/src/libs/antares/study/parts/common/cluster_list.cpp index 9c39ca7c8b..9be5c2ca57 100644 --- a/src/libs/antares/study/parts/common/cluster_list.cpp +++ b/src/libs/antares/study/parts/common/cluster_list.cpp @@ -263,9 +263,8 @@ bool ClusterList::saveDataSeriesToFolder(const AnyString& folder) cons template bool ClusterList::loadDataSeriesFromFolder(Study& s, const AnyString& folder) { - return std::ranges::all_of(allClusters_, - [&s, &folder](auto c) - { return c->loadDataSeriesFromFolder(s, folder); }); + return std::ranges::all_of(allClusters_, [&s, &folder](auto c) + { return c->loadDataSeriesFromFolder(s, folder); }); } template diff --git a/src/libs/antares/study/parts/hydro/allocation.cpp b/src/libs/antares/study/parts/hydro/allocation.cpp index 052bc3411d..597264cf20 100644 --- a/src/libs/antares/study/parts/hydro/allocation.cpp +++ b/src/libs/antares/study/parts/hydro/allocation.cpp @@ -164,7 +164,8 @@ void HydroAllocation::clear() #endif } -bool HydroAllocation::loadFromFile(const AreaName& referencearea, const fs::path& filename) +bool HydroAllocation::loadFromFile(const AreaName& referencearea, + const fs::path& filename) { clear(); @@ -176,24 +177,21 @@ bool HydroAllocation::loadFromFile(const AreaName& referencearea, const fs::path } if (ini.empty()) - { return true; - } - ini.each( - [this](const IniFile::Section& section) - { - for (auto* p = section.firstProperty; p; p = p->next) - { - double coeff = p->value.to(); - if (!Utils::isZero(coeff)) - { - AreaName areaname = p->key; - areaname.toLower(); - pValues[areaname] = coeff; - } - } - }); + ini.each([this](const IniFile::Section& section) + { + for (auto* p = section.firstProperty; p; p = p->next) + { + double coeff = p->value.to(); + if (!Utils::isZero(coeff)) + { + AreaName areaname = p->key; + areaname.toLower(); + pValues[areaname] = coeff; + } + } + }); return true; } diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index e98d94bee4..c9dc476de5 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -32,7 +32,7 @@ using namespace Yuni; namespace Antares::Data { -PartHydro::PartHydro(const Data::Area& area): +PartHydro::PartHydro(const Data::Area& area) : interDailyBreakdown(0.), intraDailyModulation(2.), intermonthlyBreakdown(0), @@ -113,9 +113,7 @@ static bool loadProperties(Study& study, T PartHydro::*ptr) { if (!property) - { return false; - } bool ret = true; @@ -244,74 +242,52 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if (IniFile::Section* section = ini.find("inter-daily-breakdown")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::interDailyBreakdown) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::interDailyBreakdown) && ret; } if (IniFile::Section* section = ini.find("intra-daily-modulation")) { - ret = loadProperties(study, - section->firstProperty, - buffer, - &PartHydro::intraDailyModulation) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::intraDailyModulation) && ret; } if (IniFile::Section* section = ini.find("reservoir")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirManagement) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirManagement) && ret; } if (IniFile::Section* section = ini.find("reservoir capacity")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirCapacity) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirCapacity) && ret; } if (IniFile::Section* section = ini.find("follow load")) { - ret = loadProperties(study, - section->firstProperty, - buffer, - &PartHydro::followLoadModulations) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::followLoadModulations) && ret; } if (IniFile::Section* section = ini.find("use water")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useWaterValue) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useWaterValue) && ret; } if (IniFile::Section* section = ini.find("hard bounds")) { - ret = loadProperties(study, - section->firstProperty, - buffer, - &PartHydro::hardBoundsOnRuleCurves) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::hardBoundsOnRuleCurves) && ret; } if (IniFile::Section* section = ini.find("use heuristic")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useHeuristicTarget) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useHeuristicTarget) && ret; } if (IniFile::Section* section = ini.find("power to level")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::powerToLevel) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::powerToLevel) && ret; } if (IniFile::Section* section = ini.find("initialize reservoir date")) { - ret = loadProperties(study, - section->firstProperty, - buffer, - &PartHydro::initializeReservoirLevelDate) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::initializeReservoirLevelDate) && ret; } if (IniFile::Section* section = ini.find("use leeway")) @@ -321,20 +297,17 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if (IniFile::Section* section = ini.find("leeway low")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayLowerBound) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayLowerBound) && ret; } if (IniFile::Section* section = ini.find("leeway up")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayUpperBound) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayUpperBound) && ret; } if (IniFile::Section* section = ini.find("pumping efficiency")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) - && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) && ret; } return ret; @@ -344,12 +317,10 @@ bool PartHydro::checkReservoirLevels(const Study& study) { bool ret = true; - for (const auto& [areaName, area]: study.areas) + for (const auto& [areaName, area] : study.areas) { if (!study.usedByTheSolver) - { return true; - } auto& col = area->hydro.inflowPattern[0]; bool errorInflow = false; @@ -369,8 +340,8 @@ bool PartHydro::checkReservoirLevels(const Study& study) for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) { if (!errorLevels - && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] - || colAvg[day] > 100 || colMax[day] > 100)) + && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] + || colAvg[day] > 100 || colMax[day] > 100)) { logs.error() << areaName << ": invalid reservoir level value"; errorLevels = true; @@ -381,7 +352,7 @@ bool PartHydro::checkReservoirLevels(const Study& study) for (int i = 0; i < 101; i++) { if ((area->hydro.creditModulation[i][0] < 0) - || (area->hydro.creditModulation[i][1] < 0)) + || (area->hydro.creditModulation[i][1] < 0)) { logs.error() << areaName << ": invalid credit modulation value"; ret = false; @@ -401,73 +372,75 @@ bool PartHydro::checkProperties(Study& study) // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and // capacity = 0 because of further division by capacity. reservoir management = no and capacity // = 0 is possible (no use of capacity further) - study.areas.each( - [&ret](Data::Area& area) - { - if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) - { - logs.error() << area.name - << ": reservoir capacity not defined. Impossible to manage."; - ret = false; - } + study.areas.each([&ret](Data::Area& area) + { + if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) + { + logs.error() << area.name + << ": reservoir capacity not defined. Impossible to manage."; + ret = false; + } - if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) - { - logs.error() << area.name - << " : use water value = no conflicts with use heuristic target = no"; - ret = false; - } + if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) + { + logs.error() << area.name + << " : use water value = no conflicts with use heuristic target = no"; + ret = false; + } - if (area.hydro.intraDailyModulation < 1.) - { - logs.error() << area.id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " - << area.hydro.intraDailyModulation << " (truncated to 1)"; - area.hydro.intraDailyModulation = 1.; - } + if (area.hydro.intraDailyModulation < 1.) + { + logs.error() + << area.id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " + << area.hydro.intraDailyModulation << " (truncated to 1)"; + area.hydro.intraDailyModulation = 1.; + } - if (area.hydro.reservoirCapacity < 0) - { - logs.error() << area.id << ": Invalid reservoir capacity."; - area.hydro.reservoirCapacity = 0.; - } + if (area.hydro.reservoirCapacity < 0) + { + logs.error() << area.id << ": Invalid reservoir capacity."; + area.hydro.reservoirCapacity = 0.; + } - if (area.hydro.intermonthlyBreakdown < 0) - { - logs.error() << area.id << ": Invalid intermonthly breakdown"; - area.hydro.intermonthlyBreakdown = 0.; - } + if (area.hydro.intermonthlyBreakdown < 0) + { + logs.error() << area.id << ": Invalid intermonthly breakdown"; + area.hydro.intermonthlyBreakdown = 0.; + } - if (area.hydro.initializeReservoirLevelDate < 0) - { - logs.error() << area.id << ": Invalid initialize reservoir date"; - area.hydro.initializeReservoirLevelDate = 0; - } + if (area.hydro.initializeReservoirLevelDate < 0) + { + logs.error() << area.id << ": Invalid initialize reservoir date"; + area.hydro.initializeReservoirLevelDate = 0; + } - if (area.hydro.leewayLowerBound < 0.) - { - logs.error() << area.id << ": Invalid leeway lower bound. It must be >= 0.0, Got " - << area.hydro.leewayLowerBound; - area.hydro.leewayLowerBound = 0.; - } + if (area.hydro.leewayLowerBound < 0.) + { + logs.error() + << area.id << ": Invalid leeway lower bound. It must be >= 0.0, Got " + << area.hydro.leewayLowerBound; + area.hydro.leewayLowerBound = 0.; + } - if (area.hydro.leewayUpperBound < 0.) - { - logs.error() << area.id << ": Invalid leeway upper bound. It must be >= 0.0, Got " - << area.hydro.leewayUpperBound; - area.hydro.leewayUpperBound = 0.; - } + if (area.hydro.leewayUpperBound < 0.) + { + logs.error() + << area.id << ": Invalid leeway upper bound. It must be >= 0.0, Got " + << area.hydro.leewayUpperBound; + area.hydro.leewayUpperBound = 0.; + } - if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) - { + if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) + { logs.error() << area.id << ": Leeway lower bound greater than leeway upper bound."; - } + } - if (area.hydro.pumpingEfficiency < 0) - { - logs.error() << area.id << ": Invalid pumping efficiency"; - area.hydro.pumpingEfficiency = 0.; - } - }); + if (area.hydro.pumpingEfficiency < 0) + { + logs.error() << area.id << ": Invalid pumping efficiency"; + area.hydro.pumpingEfficiency = 0.; + } + }); return ret; } @@ -492,40 +465,40 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) struct AllSections { - IniFile::Section* s; - IniFile::Section* smod; - IniFile::Section* sIMB; - IniFile::Section* sreservoir; - IniFile::Section* sreservoirCapacity; - IniFile::Section* sFollowLoad; - IniFile::Section* sUseWater; - IniFile::Section* sHardBounds; - IniFile::Section* sInitializeReservoirDate; - IniFile::Section* sUseHeuristic; - IniFile::Section* sUseLeeway; - IniFile::Section* sPowerToLevel; - IniFile::Section* sLeewayLow; - IniFile::Section* sLeewayUp; - IniFile::Section* spumpingEfficiency; - - AllSections(IniFile& ini): - s(ini.addSection("inter-daily-breakdown")), - smod(ini.addSection("intra-daily-modulation")), - sIMB(ini.addSection("inter-monthly-breakdown")), - sreservoir(ini.addSection("reservoir")), - sreservoirCapacity(ini.addSection("reservoir capacity")), - sFollowLoad(ini.addSection("follow load")), - sUseWater(ini.addSection("use water")), - sHardBounds(ini.addSection("hard bounds")), - sInitializeReservoirDate(ini.addSection("initialize reservoir date")), - sUseHeuristic(ini.addSection("use heuristic")), - sUseLeeway(ini.addSection("use leeway")), - sPowerToLevel(ini.addSection("power to level")), - sLeewayLow(ini.addSection("leeway low")), - sLeewayUp(ini.addSection("leeway up")), - spumpingEfficiency(ini.addSection("pumping efficiency")) + IniFile::Section* s; + IniFile::Section* smod; + IniFile::Section* sIMB; + IniFile::Section* sreservoir; + IniFile::Section* sreservoirCapacity; + IniFile::Section* sFollowLoad; + IniFile::Section* sUseWater; + IniFile::Section* sHardBounds; + IniFile::Section* sInitializeReservoirDate; + IniFile::Section* sUseHeuristic; + IniFile::Section* sUseLeeway; + IniFile::Section* sPowerToLevel; + IniFile::Section* sLeewayLow; + IniFile::Section* sLeewayUp; + IniFile::Section* spumpingEfficiency; + + AllSections(IniFile& ini) : + s(ini.addSection("inter-daily-breakdown")), + smod(ini.addSection("intra-daily-modulation")), + sIMB(ini.addSection("inter-monthly-breakdown")), + sreservoir(ini.addSection("reservoir")), + sreservoirCapacity(ini.addSection("reservoir capacity")), + sFollowLoad(ini.addSection("follow load")), + sUseWater(ini.addSection("use water")), + sHardBounds(ini.addSection("hard bounds")), + sInitializeReservoirDate(ini.addSection("initialize reservoir date")), + sUseHeuristic(ini.addSection("use heuristic")), + sUseLeeway(ini.addSection("use leeway")), + sPowerToLevel(ini.addSection("power to level")), + sLeewayLow(ini.addSection("leeway low")), + sLeewayUp(ini.addSection("leeway up")), + spumpingEfficiency(ini.addSection("pumping efficiency")) { - } + } }; // Init @@ -542,8 +515,7 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) allSections.s->add(area.id, area.hydro.interDailyBreakdown); allSections.smod->add(area.id, area.hydro.intraDailyModulation); allSections.sIMB->add(area.id, area.hydro.intermonthlyBreakdown); - allSections.sInitializeReservoirDate->add(area.id, - area.hydro.initializeReservoirLevelDate); + allSections.sInitializeReservoirDate->add(area.id, area.hydro.initializeReservoirLevelDate); allSections.sLeewayLow->add(area.id, area.hydro.leewayLowerBound); allSections.sLeewayUp->add(area.id, area.hydro.leewayUpperBound); allSections.spumpingEfficiency->add(area.id, area.hydro.pumpingEfficiency); @@ -768,8 +740,8 @@ bool PartHydro::CheckDailyMaxEnergy(const AnyString& areaName) } double getWaterValue(const double& level /* format : in % of reservoir capacity */, - const Matrix& waterValues, - const uint day) + const Matrix& waterValues, + const uint day) { assert((level >= 0. && level <= 100.) && "getWaterValue function : invalid level"); double levelUp = ceil(level); @@ -780,7 +752,7 @@ double getWaterValue(const double& level /* format : in % of reservoir capacity return waterValues[(int)(levelUp)][day]; } return waterValues[(int)(levelUp)][day] * (level - levelDown) - + waterValues[(int)(levelDown)][day] * (levelUp - level); + + waterValues[(int)(levelDown)][day] * (levelUp - level); } double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */, diff --git a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp index 5aa233fedb..2229f75f97 100644 --- a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp +++ b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp @@ -37,8 +37,8 @@ FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, double finalLevel, const unsigned int year, const unsigned int lastSimulationDay, - const unsigned int firstMonthOfSimulation): - hydro_(hydro), + const unsigned int firstMonthOfSimulation) + : hydro_(hydro), areaName_(areaName), areaIndex_(areaIndex), initialLevel_(initialLevel), @@ -52,46 +52,36 @@ FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, bool FinalLevelValidator::check() { if (skippingFinalLevelUse()) - { return true; - } - if (!checkForInfeasibility()) - { + if (! checkForInfeasibility()) return false; - } finalLevelFineForUse_ = true; return true; } bool FinalLevelValidator::skippingFinalLevelUse() { - if (!wasSetInScenarioBuilder()) - { + if(! wasSetInScenarioBuilder()) return true; - } - if (!compatibleWithReservoirProperties()) - { + if (! compatibleWithReservoirProperties()) return true; - } return false; } bool FinalLevelValidator::wasSetInScenarioBuilder() { - return !isnan(finalLevel_); + return ! isnan(finalLevel_); } bool FinalLevelValidator::compatibleWithReservoirProperties() { if (hydro_.reservoirManagement && !hydro_.useWaterValue) - { return true; - } - logs.warning() - << "Final reservoir level not applicable! Year:" << year_ + 1 << ", Area:" << areaName_ - << ". Check: Reservoir management = Yes, Use water values = No and proper initial " - "reservoir level is provided "; + logs.warning() << "Final reservoir level not applicable! Year:" << year_ + 1 + << ", Area:" << areaName_ + << ". Check: Reservoir management = Yes, Use water values = No and proper initial " + "reservoir level is provided "; return false; } @@ -108,12 +98,10 @@ bool FinalLevelValidator::hydroAllocationStartMatchesSimulation() const { int initReservoirLvlMonth = hydro_.initializeReservoirLevelDate; // month [0-11] if (lastSimulationDay_ == DAYS_PER_YEAR && initReservoirLvlMonth == firstMonthOfSimulation_) - { return true; - } - logs.error() << "Year " << year_ + 1 << ", area '" << areaName_ - << "' : " << "Hydro allocation must start on the 1st simulation month and " + logs.error() << "Year " << year_ + 1 << ", area '" << areaName_ << "' : " + << "Hydro allocation must start on the 1st simulation month and " << "simulation last a whole year"; return false; } @@ -127,8 +115,8 @@ bool FinalLevelValidator::isFinalLevelReachable() const { logs.error() << "Year: " << year_ + 1 << ". Area: " << areaName_ << ". Incompatible total inflows: " << totalYearInflows - << " with initial: " << initialLevel_ << " and final: " << finalLevel_ - << " reservoir levels."; + << " with initial: " << initialLevel_ + << " and final: " << finalLevel_ << " reservoir levels."; return false; } return true; @@ -137,19 +125,17 @@ bool FinalLevelValidator::isFinalLevelReachable() const double FinalLevelValidator::calculateTotalInflows() const { // calculate yearly inflows - const auto& srcinflows = hydro_.series->storage.getColumn(year_); + auto const& srcinflows = hydro_.series->storage.getColumn(year_); double totalYearInflows = 0.0; for (unsigned int day = 0; day < DAYS_PER_YEAR; ++day) - { totalYearInflows += srcinflows[day]; - } return totalYearInflows; } bool FinalLevelValidator::isBetweenRuleCurves() const { - double lowLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::minimum][DAYS_PER_YEAR - 1]; + double lowLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::minimum][DAYS_PER_YEAR - 1]; double highLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::maximum][DAYS_PER_YEAR - 1]; if (finalLevel_ < lowLevelLastDay || finalLevel_ > highLevelLastDay) diff --git a/src/libs/antares/study/parts/hydro/prepro.cpp b/src/libs/antares/study/parts/hydro/prepro.cpp index 13711759f4..9370c562fa 100644 --- a/src/libs/antares/study/parts/hydro/prepro.cpp +++ b/src/libs/antares/study/parts/hydro/prepro.cpp @@ -151,7 +151,6 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::st { mtrxOption = Matrix<>::optFixedSize | Matrix<>::optImmediate, }; - constexpr int maxNbOfLineToLoad = 12; data.resize(hydroPreproMax, 12, true); @@ -161,8 +160,7 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::st bool ret = PreproHydroLoadSettings(this, buffer); buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; - ret = data.loadFromCSVFile(buffer, hydroPreproMax, maxNbOfLineToLoad, mtrxOption, &s.dataBuffer) - && ret; + ret = data.loadFromCSVFile(buffer, hydroPreproMax, maxNbOfLineToLoad, mtrxOption, &s.dataBuffer) && ret; return ret; } @@ -205,8 +203,8 @@ bool PreproHydro::validate(const std::string& areaID) { ret = false; logs.error() << "Hydro: Prepro: `" << areaID - << "`: minimum energy: At least one value is negative (line: " << (i + 1) - << ')'; + << "`: minimum energy: At least one value is negative (line: " + << (i + 1) << ')'; continue; } if (colMin[i] > colMax[i]) diff --git a/src/libs/antares/study/parts/hydro/series.cpp b/src/libs/antares/study/parts/hydro/series.cpp index 8c73772565..3eda6d5fc3 100644 --- a/src/libs/antares/study/parts/hydro/series.cpp +++ b/src/libs/antares/study/parts/hydro/series.cpp @@ -54,7 +54,7 @@ static void ConvertDailyTSintoHourlyTS(const Matrix::ColumnType& dailyCo { uint hour = 0; uint day = 0; - + while (hour < HOURS_PER_YEAR && day < DAYS_PER_YEAR) { for (uint i = 0; i < HOURS_PER_DAY; ++i) diff --git a/src/libs/antares/study/parts/renewable/cluster_list.cpp b/src/libs/antares/study/parts/renewable/cluster_list.cpp index aa1c915a75..62db61a900 100644 --- a/src/libs/antares/study/parts/renewable/cluster_list.cpp +++ b/src/libs/antares/study/parts/renewable/cluster_list.cpp @@ -223,7 +223,7 @@ bool RenewableClusterList::loadFromFolder(const AnyString& folder, Area* area) bool RenewableClusterList::validateClusters() const { bool ret = true; - for (const auto& cluster: allClusters_) + for (const auto& cluster : allClusters_) { ret = cluster->integrityCheck() && ret; } diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 9a27233064..749613a14b 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -37,7 +37,8 @@ namespace Antares::Data::ShortTermStorage { bool STStorageInput::validate() const { - return std::ranges::all_of(storagesByIndex, [](auto& cluster) { return cluster.validate(); }); + return std::ranges::all_of(storagesByIndex, [](auto& cluster) + { return cluster.validate(); }); } bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) @@ -67,9 +68,8 @@ bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) storagesByIndex.push_back(cluster); } - std::ranges::sort(storagesByIndex, - [](const auto& a, const auto& b) - { return a.properties.name < b.properties.name; }); + std::ranges::sort(storagesByIndex, [](const auto& a, const auto& b) + { return a.properties.name < b.properties.name; }); return true; } @@ -100,8 +100,8 @@ bool STStorageInput::saveToFolder(const std::string& folder) const IniFile ini; logs.debug() << "saving file " << pathIni; - std::ranges::for_each(storagesByIndex, - [&ini](auto& storage) { return storage.saveProperties(ini); }); + std::ranges::for_each(storagesByIndex, [&ini](auto& storage) + { return storage.saveProperties(ini); }); return ini.save(pathIni); } @@ -109,20 +109,20 @@ bool STStorageInput::saveToFolder(const std::string& folder) const bool STStorageInput::saveDataSeriesToFolder(const std::string& folder) const { Yuni::IO::Directory::Create(folder); - return std::ranges::all_of(storagesByIndex, - [&folder](auto& storage) - { return storage.saveSeries(folder + SEP + storage.id); }); + return std::ranges::all_of(storagesByIndex, [&folder](auto& storage) + { return storage.saveSeries(folder + SEP + storage.id); }); } std::size_t STStorageInput::count() const { - return std::ranges::count_if(storagesByIndex, - [](const STStorageCluster& st) { return st.properties.enabled; }); + return std::ranges::count_if(storagesByIndex, [](const STStorageCluster& st) + { return st.properties.enabled; }); } uint STStorageInput::removeDisabledClusters() { - return std::erase_if(storagesByIndex, [](const auto& c) { return !c.enabled(); }); + return std::erase_if(storagesByIndex, [](const auto& c) + { return !c.enabled(); }); } } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/parts/thermal/cluster_list.cpp b/src/libs/antares/study/parts/thermal/cluster_list.cpp index 8435870d0a..4bf2e042c2 100644 --- a/src/libs/antares/study/parts/thermal/cluster_list.cpp +++ b/src/libs/antares/study/parts/thermal/cluster_list.cpp @@ -162,8 +162,7 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A ret = cluster->modulation.loadFromCSVFile(modulationFile, thermalModulationMax, HOURS_PER_YEAR, - options) - && ret; + options) && ret; // Check the data integrity of the cluster addToCompleteList(cluster); @@ -175,11 +174,12 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A return ret; } + bool ThermalClusterList::validateClusters(const Parameters& parameters) const { bool ret = true; - for (const auto& cluster: allClusters_) + for (const auto& cluster : allClusters_) { cluster->minUpTime = std::clamp(cluster->minUpTime, 1u, 168u); cluster->minDownTime = std::clamp(cluster->minDownTime, 1u, 168u); @@ -206,6 +206,7 @@ bool ThermalClusterList::validateClusters(const Parameters& parameters) const cluster->nominalCapacityWithSpinning = cluster->nominalCapacity; ret = cluster->integrityCheck() && ret; + } return ret; @@ -376,7 +377,7 @@ void ThermalClusterList::reverseCalculationOfSpinning() void ThermalClusterList::enableMustrunForEveryone() { - for (const auto& c: allClusters_) + for (const auto& c : allClusters_) { c->mustrun = true; } @@ -540,6 +541,7 @@ bool ThermalClusterList::saveToFolder(const AnyString& folder) const { ret = false; } + } // Write the ini file @@ -596,32 +598,27 @@ bool ThermalClusterList::loadPreproFromFolder(Study& study, const AnyString& fol return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), loadPrepro); } -bool ThermalClusterList::validatePrepro(const Study& study) -{ +bool ThermalClusterList::validatePrepro(const Study& study) { auto hasPrepro = [](auto c) { return (bool)c->prepro; }; - const bool globalThermalTSgeneration = study.parameters.timeSeriesToGenerate - & timeSeriesThermal; + const bool globalThermalTSgeneration = + study.parameters.timeSeriesToGenerate & timeSeriesThermal; if (!study.usedByTheSolver) - { return true; - } - return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), - [&globalThermalTSgeneration](auto& c) - { - if (globalThermalTSgeneration && !c->prepro->validate()) - { - return false; - } - - if (c->doWeGenerateTS(globalThermalTSgeneration)) - { - return c->prepro->normalizeAndCheckNPO(); - } - return true; - }); + return std::ranges::all_of( + allClusters_ | std::views::filter(hasPrepro), + [&globalThermalTSgeneration](auto& c) { + if (globalThermalTSgeneration && !c->prepro->validate()) { + return false; + } + + if (c->doWeGenerateTS(globalThermalTSgeneration)) { + return c->prepro->normalizeAndCheckNPO(); + } + return true; + }); } bool ThermalClusterList::loadEconomicCosts(Study& study, const AnyString& folder) diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index c094450243..035faf86ac 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -213,7 +213,8 @@ void StudyRuntimeInfos::initializeRangeLimits(const Study& study, StudyRangeLimi } else { - simulationDaysPerMonth[ca.month] = study.calendar.months[ca.month].days - ca.dayMonth; + simulationDaysPerMonth[ca.month] = study.calendar.months[ca.month].days + - ca.dayMonth; simulationDaysPerMonth[cb.month] = cb.dayMonth + 1; for (uint i = ca.month + 1; i < cb.month; ++i) { @@ -440,8 +441,7 @@ void StudyRangeLimits::checkIntegrity() const void StudyRuntimeInfos::disableAllFilters(Study& study) { - study.areas.each( - [](Data::Area& area) + study.areas.each([](Data::Area& area) { area.filterSynthesis = filterAll; area.filterYearByYear = filterAll; diff --git a/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp b/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp index 5ffef13e98..46a0694a58 100644 --- a/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp +++ b/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp @@ -81,11 +81,11 @@ bool BindingConstraintsTSNumberData::reset(const Study& study) { const uint nbYears = study.parameters.nbYears; std::ranges::for_each(study.bindingConstraintsGroups, - [this, &nbYears](const auto& group) - { - auto& ts_numbers = rules_[group->name()]; - ts_numbers.reset(1, nbYears); - }); + [this, &nbYears](const auto& group) + { + auto& ts_numbers = rules_[group->name()]; + ts_numbers.reset(1, nbYears); + }); return true; } diff --git a/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp b/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp index 8d0575b96a..3295df4503 100644 --- a/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp +++ b/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp @@ -29,9 +29,9 @@ namespace Antares::Data::ScenarioBuilder { hydroLevelsData::hydroLevelsData(const std::string& iniFilePrefix, - std::function applyToTarget): - addToPrefix_(iniFilePrefix), - applyToTarget_(applyToTarget) + std::function applyToTarget) : + addToPrefix_(iniFilePrefix), + applyToTarget_(applyToTarget) { } diff --git a/src/libs/antares/study/scenario-builder/rules.cpp b/src/libs/antares/study/scenario-builder/rules.cpp index 2037eede6b..fd79f07f7c 100644 --- a/src/libs/antares/study/scenario-builder/rules.cpp +++ b/src/libs/antares/study/scenario-builder/rules.cpp @@ -288,9 +288,7 @@ bool Rules::readFinalHydroLevels(const AreaName::Vector& splitKey, String value, const Data::Area* area = getArea(areaname, updaterMode); if (!area) - { return false; - } double finalLevel = fromStringToHydroLevel(value, 1.); hydroFinalLevels.setTSnumber(area->index, year, finalLevel); @@ -452,7 +450,8 @@ bool Rules::apply() void Rules::sendWarningsForDisabledClusters() { - for (auto it = disabledClustersOnRuleActive.begin(); it != disabledClustersOnRuleActive.end(); + for (auto it = disabledClustersOnRuleActive.begin(); + it != disabledClustersOnRuleActive.end(); it++) { std::vector& scenariiForCurrentCluster = it->second; diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 5b1dde8c5f..511e61a592 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -856,8 +856,7 @@ void Study::areaDelete(Area::Vector& arealist) << area.name; // Updating all hydro allocation - areas.each([&area](Data::Area& areait) - { areait.hydro.allocation.remove(area.id); }); + areas.each([&area](Data::Area& areait) { areait.hydro.allocation.remove(area.id); }); // Remove all binding constraints attached to the area bindingConstraints.remove(*i); @@ -957,7 +956,7 @@ bool Study::areaRename(Area* area, AreaName newName) // Updating all hydro allocation areas.each([&oldid, &newid](Data::Area& areait) - { areait.hydro.allocation.rename(oldid, newid); }); + { areait.hydro.allocation.rename(oldid, newid); }); ScenarioBuilderUpdater updaterSB(*this); bool ret = true; @@ -1110,14 +1109,13 @@ void Study::destroyAllWindTSGeneratorData() void Study::destroyAllThermalTSGeneratorData() { - areas.each( - [](const Data::Area& area) - { - for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) - { - FreeAndNil(cluster->prepro); - } - }); + areas.each([](const Data::Area& area) + { + for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) + { + FreeAndNil(cluster->prepro); + } + }); } void Study::ensureDataAreLoadedForAllBindingConstraints() @@ -1360,6 +1358,7 @@ bool Study::checkForFilenameLimits(bool output, const String& chfolder) const areas.each( [&output, &linkname, &areaname](const Area& area) { + if (areaname.size() < area.id.size()) { areaname = area.id; diff --git a/src/libs/antares/study/study.importprepro.cpp b/src/libs/antares/study/study.importprepro.cpp index f7c8082050..3b8263eadf 100644 --- a/src/libs/antares/study/study.importprepro.cpp +++ b/src/libs/antares/study/study.importprepro.cpp @@ -50,7 +50,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesLoad)) { logs.info() << "Importing load timeseries..."; - for (const auto& [areaName, area]: areas) + for (const auto& [areaName, area] : areas) { logs.info() << "Importing load timeseries : " << areaName; buffer.clear() << folderInput << SEP << "load" << SEP << "series"; @@ -63,7 +63,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesSolar)) { logs.info() << "Importing solar timeseries..."; - for (const auto& [areaName, area]: areas) + for (const auto& [areaName, area] : areas) { logs.info() << "Importing solar timeseries : " << areaName; buffer.clear() << folderInput << SEP << "solar" << SEP << "series"; @@ -76,7 +76,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesHydro)) { logs.info() << "Importing hydro timeseries..."; - for (const auto& [areaName, area]: areas) + for (const auto& [areaName, area] : areas) { logs.info() << "Importing hydro timeseries : " << areaName; buffer.clear() << folderInput << SEP << "hydro" << SEP << "series"; @@ -89,7 +89,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesWind)) { logs.info() << "Importing wind timeseries..."; - for (const auto& [areaName, area]: areas) + for (const auto& [areaName, area] : areas) { logs.info() << "Importing wind timeseries : " << areaName; buffer.clear() << folderInput << SEP << "wind" << SEP << "series"; @@ -104,7 +104,7 @@ bool Study::importTimeseriesIntoInput() logs.info() << "Importing thermal timeseries..."; String msg; - for (const auto& [areaName, area]: areas) + for (const auto& [areaName, area] : areas) { msg.clear() << "Importing thermal timeseries : " << areaName; diff --git a/src/libs/antares/study/xcast/xcast.cpp b/src/libs/antares/study/xcast/xcast.cpp index 0f2e05956b..51ed1624b0 100644 --- a/src/libs/antares/study/xcast/xcast.cpp +++ b/src/libs/antares/study/xcast/xcast.cpp @@ -207,8 +207,7 @@ bool XCast::loadFromFolder(const AnyString& folder) // For each property if (section.name == "general") { - for (const IniFile::Property* p = section.firstProperty; p != nullptr; - p = p->next) + for (const IniFile::Property* p = section.firstProperty; p != nullptr; p = p->next) { CString<30, false> key = p->key; key.toLower(); diff --git a/src/libs/antares/writer/in_memory_writer.cpp b/src/libs/antares/writer/in_memory_writer.cpp index 182fee1927..e3e643a74f 100644 --- a/src/libs/antares/writer/in_memory_writer.cpp +++ b/src/libs/antares/writer/in_memory_writer.cpp @@ -24,9 +24,9 @@ #include #include -#include #include #include +#include namespace fs = std::filesystem; diff --git a/src/libs/antares/writer/zip_writer.cpp b/src/libs/antares/writer/zip_writer.cpp index 6359460f8a..362d0e730e 100644 --- a/src/libs/antares/writer/zip_writer.cpp +++ b/src/libs/antares/writer/zip_writer.cpp @@ -51,6 +51,7 @@ static void logErrorAndThrow [[noreturn]] (const std::string& errorMessage) throw std::runtime_error(errorMessage); } + // Class ZipWriteJob template ZipWriteJob::ZipWriteJob(ZipWriter& writer, diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index 9ec3ce3e14..d222ad88c0 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -337,14 +337,10 @@ void Application::prepare(int argc, char* argv[]) // don't de-allocate these. if (!parseCommandLine(options)) // --help - { return; - } if (!handleOptions(options)) // --version, --list-solvers - { - return; - } + return; // Perform some checks checkAndCorrectSettingsAndOptions(pSettings, options); diff --git a/src/solver/constraints-builder/cbuilder.cpp b/src/solver/constraints-builder/cbuilder.cpp index 0b37556347..a49806ff16 100644 --- a/src/solver/constraints-builder/cbuilder.cpp +++ b/src/solver/constraints-builder/cbuilder.cpp @@ -364,7 +364,8 @@ bool CBuilder::saveCBuilderToFile(const String& filename) const if (filename == "") { - fs::path path = fs::path(pStudy.folder.c_str()) / "settings" / "constraintbuilder.ini"; + fs::path path = fs::path(pStudy.folder.c_str()) / "settings" + / "constraintbuilder.ini"; return ini.save(path.string()); } diff --git a/src/solver/hydro/include/antares/solver/hydro/management/management.h b/src/solver/hydro/include/antares/solver/hydro/management/management.h index 30528d92d2..b642e441c2 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -152,7 +152,8 @@ class HydroManagement final // \return The total inflow for the whole year double prepareMonthlyTargetGenerations(Data::Area& area, TmpDataByArea& data); - void prepareDailyOptimalGenerations(uint y, Antares::Data::Area::ScratchMap& scratchmap); + void prepareDailyOptimalGenerations(uint y, + Antares::Data::Area::ScratchMap& scratchmap); void prepareDailyOptimalGenerations(Data::Area& area, uint y, diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index d9651a1197..f7e4665159 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -219,9 +219,9 @@ struct DebugData }; inline void HydroManagement::prepareDailyOptimalGenerations( - Data::Area& area, - uint y, - Antares::Data::Area::ScratchMap& scratchmap) + Data::Area& area, + uint y, + Antares::Data::Area::ScratchMap& scratchmap) { const auto srcinflows = area.hydro.series->storage.getColumn(y); diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index a863668f64..703235fc61 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -385,31 +385,23 @@ bool HydroManagement::checkMinGeneration(uint year) const void HydroManagement::changeInflowsToAccommodateFinalLevels(uint year) { - areas_.each( - [this, &year](Data::Area& area) - { - auto& data = tmpDataByArea_[&area]; - - if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) - { - return; - } - - // Must be done before prepareMonthlyTargetGenerations - double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); - if (delta < 0) - { - data.inflows[0] -= delta; - } - else if (delta > 0) - { - data.inflows[11] -= delta; - } - }); + areas_.each([this, &year](Data::Area& area) + { + auto& data = tmpDataByArea_[&area]; + + if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) + return; + + // Must be done before prepareMonthlyTargetGenerations + double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); + if (delta < 0) + data.inflows[0] -= delta; + else if (delta > 0) + data.inflows[11] -= delta; + }); } -void HydroManagement::prepareNetDemand(uint year, - Data::SimulationMode mode, +void HydroManagement::prepareNetDemand(uint year, Data::SimulationMode mode, const Antares::Data::Area::ScratchMap& scratchmap) { areas_.each( diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index 37c2085e3c..aa10b7c10e 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -290,22 +290,22 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ auto monthName = calendar_.text.months[simulationMonth].name; - buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; - buffer << '\t'; - buffer << data.inflows[realmonth] << '\t'; - buffer << data.MTG[realmonth] << '\t'; - buffer << data.MOG[realmonth] / area.hydro.reservoirCapacity << '\t'; - buffer << data.MOL[realmonth] << '\t'; - buffer << minLvl[firstDay] << '\t'; - buffer << maxLvl[firstDay] << '\t'; - buffer << '\n'; - } - auto content = buffer.str(); - resultWriter_.addEntryFromBuffer(path.str(), content); - } + buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; + buffer << '\t'; + buffer << data.inflows[realmonth] << '\t'; + buffer << data.MTG[realmonth] << '\t'; + buffer << data.MOG[realmonth] / area.hydro.reservoirCapacity << '\t'; + buffer << data.MOL[realmonth] << '\t'; + buffer << minLvl[firstDay] << '\t'; + buffer << maxLvl[firstDay] << '\t'; + buffer << '\n'; + } + auto content = buffer.str(); + resultWriter_.addEntryFromBuffer(path.str(), content); + } - indexArea++; - }); + indexArea++; + }); } } // namespace Antares diff --git a/src/solver/misc/include/antares/solver/misc/options.h b/src/solver/misc/include/antares/solver/misc/options.h index 00daf5aec7..2560a74d1c 100644 --- a/src/solver/misc/include/antares/solver/misc/options.h +++ b/src/solver/misc/include/antares/solver/misc/options.h @@ -27,8 +27,8 @@ #include #include -#include #include +#include /*! ** \brief Command line settings for launching the simulation diff --git a/src/solver/misc/options.cpp b/src/solver/misc/options.cpp index 458ae2fa06..9429b50e79 100644 --- a/src/solver/misc/options.cpp +++ b/src/solver/misc/options.cpp @@ -22,8 +22,8 @@ #include "antares/solver/misc/options.h" #include -#include #include +#include #include #include diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index fa4a292902..2b03f7bcdc 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -68,10 +68,7 @@ bool Adequacy::simulationBegin() pProblemesHebdo.resize(pNbMaxPerformedYearsInParallel); for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) { - SIM_InitialisationProblemeHebdo(study, - pProblemesHebdo[numSpace], - nbHoursInAWeek, - numSpace); + SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], nbHoursInAWeek, numSpace); } } diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index 8095cc85bb..1f56235499 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -395,23 +395,21 @@ void PrepareRandomNumbers(Data::Study& study, }); } + void SetInitialHydroLevel(Data::Study& study, PROBLEME_HEBDO& problem, const HYDRO_VENTILATION_RESULTS& hydroVentilationResults) { uint firstDaySimu = study.parameters.simulationDays.first; - study.areas.each( - [&problem, &firstDaySimu, &hydroVentilationResults](const Data::Area& area) - { - if (area.hydro.reservoirManagement) - { - double capacity = area.hydro.reservoirCapacity; - problem.previousSimulationFinalLevel[area.index] = hydroVentilationResults[area.index] - .NiveauxReservoirsDebutJours - [firstDaySimu] - * capacity; - } - }); + study.areas.each([&problem, &firstDaySimu, &hydroVentilationResults](const Data::Area& area) + { + if (area.hydro.reservoirManagement) + { + double capacity = area.hydro.reservoirCapacity; + problem.previousSimulationFinalLevel[area.index] = + hydroVentilationResults[area.index].NiveauxReservoirsDebutJours[firstDaySimu] * capacity; + } + }); } void BuildThermalPartOfWeeklyProblem(Data::Study& study, diff --git a/src/solver/simulation/common-hydro-levels.cpp b/src/solver/simulation/common-hydro-levels.cpp index b0ba258b0e..81602073a1 100644 --- a/src/solver/simulation/common-hydro-levels.cpp +++ b/src/solver/simulation/common-hydro-levels.cpp @@ -33,7 +33,7 @@ void computingHydroLevels(const Data::AreaList& areas, bool remixWasRun, bool computeAnyway) { - for (const auto& [_, area]: areas) + for (const auto& [_, area] : areas) { if (!area->hydro.reservoirManagement) { @@ -50,7 +50,7 @@ void computingHydroLevels(const Data::AreaList& areas, double reservoirCapacity = area->hydro.reservoirCapacity; std::vector& inflows = problem.CaracteristiquesHydrauliques[index] - .ApportNaturelHoraire; + .ApportNaturelHoraire; RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; @@ -65,7 +65,7 @@ void computingHydroLevels(const Data::AreaList& areas, std::vector& ovf = weeklyResults.debordementsHoraires; computeTimeStepLevel - computeLvlObj(nivInit, inflows, ovf, turb, pumpingRatio, pump, reservoirCapacity); + computeLvlObj(nivInit, inflows, ovf, turb, pumpingRatio, pump, reservoirCapacity); for (uint h = 0; h < nbHoursInAWeek - 1; h++) { @@ -94,7 +94,7 @@ void interpolateWaterValue(const Data::AreaList& areas, daysOfWeek[d] = weekFirstDay + d; } - for (const auto& [_, area]: areas) + for (const auto& [_, area] : areas) { uint index = area->index; @@ -118,22 +118,22 @@ void interpolateWaterValue(const Data::AreaList& areas, std::vector& niv = weeklyResults.niveauxHoraires; waterVal[0] = Data::getWaterValue(problem.previousSimulationFinalLevel[index] * 100 - / reservoirCapacity, - area->hydro.waterValues, - weekFirstDay); + / reservoirCapacity, + area->hydro.waterValues, + weekFirstDay); for (uint h = 1; h < nbHoursInAWeek; h++) { waterVal[h] = Data::getWaterValue(niv[h - 1], - area->hydro.waterValues, - daysOfWeek[h / 24]); + area->hydro.waterValues, + daysOfWeek[h / 24]); } } } void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& problem) { - for (const auto& [_, area]: areas) + for (const auto& [_, area] : areas) { if (!area->hydro.reservoirManagement) { @@ -149,7 +149,7 @@ void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& std::vector& niv = weeklyResults.niveauxHoraires; problem.previousSimulationFinalLevel[index] = niv[nbHoursInAWeek - 1] * reservoirCapacity - / 100; + / 100; } } diff --git a/src/solver/simulation/common-hydro-remix.cpp b/src/solver/simulation/common-hydro-remix.cpp index de8e3f5328..dcf39052ce 100644 --- a/src/solver/simulation/common-hydro-remix.cpp +++ b/src/solver/simulation/common-hydro-remix.cpp @@ -51,7 +51,8 @@ static bool Remix(const Data::AreaList& areas, bool status = true; areas.each( - [&HE, &DE, &remix, &G, &status, &problem, &numSpace, &hourInYear](const Data::Area& area) + [&HE, &DE, &remix, &G, &status, &problem, &numSpace, &hourInYear] + (const Data::Area& area) { auto index = area.index; diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index ac40117b2c..934ebc4c2c 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -73,10 +73,7 @@ bool Economy::simulationBegin() for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) { - SIM_InitialisationProblemeHebdo(study, - pProblemesHebdo[numSpace], - nbHoursInAWeek, - numSpace); + SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], nbHoursInAWeek, numSpace); auto options = createOptimizationOptions(study); weeklyOptProblems_[numSpace] = Antares::Solver::Optimization::WeeklyOptimization:: diff --git a/src/solver/simulation/hydro-final-reservoir-level-functions.cpp b/src/solver/simulation/hydro-final-reservoir-level-functions.cpp index 225a0e2be9..32f2d4dfa2 100644 --- a/src/solver/simulation/hydro-final-reservoir-level-functions.cpp +++ b/src/solver/simulation/hydro-final-reservoir-level-functions.cpp @@ -26,47 +26,43 @@ */ #include "antares/solver/simulation/hydro-final-reservoir-level-functions.h" - -#include #include "antares/study/parts/hydro/finalLevelValidator.h" +#include namespace Antares::Solver { void CheckFinalReservoirLevelsConfiguration(const Data::Study& study) { - study.areas.each( - [&study](Data::Area& area) - { - uint nbYears = study.parameters.nbYears; - for (uint year = 0; year != nbYears; ++year) - { - if (!study.parameters.yearsFilter.at(year)) - { - continue; - } + study.areas.each([&study](Data::Area &area) + { + uint nbYears = study.parameters.nbYears; + for (uint year = 0; year != nbYears; ++year) + { + if (! study.parameters.yearsFilter.at(year)) + continue; - double initialLevel = study.scenarioInitialHydroLevels.entry[area.index][year]; - double finalLevel = study.scenarioFinalHydroLevels.entry[area.index][year]; + double initialLevel = study.scenarioInitialHydroLevels.entry[area.index][year]; + double finalLevel = study.scenarioFinalHydroLevels.entry[area.index][year]; - Data::FinalLevelValidator validator(area.hydro, - area.index, - area.name, - initialLevel, - finalLevel, - year, - study.parameters.simulationDays.end, - study.parameters.firstMonthInYear); - if (!validator.check()) - { - throw FatalError("hydro final level : infeasibility"); - } - if (validator.finalLevelFineForUse()) - { - area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; - } - } - }); + Data::FinalLevelValidator validator(area.hydro, + area.index, + area.name, + initialLevel, + finalLevel, + year, + study.parameters.simulationDays.end, + study.parameters.firstMonthInYear); + if (! validator.check()) + { + throw FatalError("hydro final level : infeasibility"); + } + if (validator.finalLevelFineForUse()) + { + area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; + } + } + }); } // End function CheckFinalReservoirLevelsConfiguration -} // namespace Antares::Solver +} // namespace Antares::Solver \ No newline at end of file diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index cd6bcb5f62..232fa520fc 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -39,6 +39,7 @@ #include "antares/solver/simulation/timeseries-numbers.h" #include "antares/solver/ts-generator/generator.h" + #include "hydro-final-reservoir-level-functions.h" namespace Antares::Solver::Simulation @@ -74,7 +75,10 @@ public: yearByYear(pYearByYear), pDurationCollector(durationCollector), pResultWriter(resultWriter), - hydroManagement(study.areas, study.parameters, study.calendar, resultWriter) + hydroManagement(study.areas, + study.parameters, + study.calendar, + resultWriter) { scratchmap = study.areas.buildScratchMap(numSpace); } @@ -158,8 +162,11 @@ public: simulation_->prepareClustersInMustRunMode(scratchmap, y); // 4 - Hydraulic ventilation - pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] - { hydroManagement.makeVentilation(randomReservoirLevel, y, scratchmap); }; + pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] { + hydroManagement.makeVentilation(randomReservoirLevel, + y, + scratchmap); + }; // Updating the state state.year = y; @@ -741,15 +748,15 @@ void ISimulation::computeRandomNumbers( max[firstDayOfMonth], randomHydroGenerator); - // Possibly update the intial level from scenario builder - if (study.parameters.useCustomScenario) - { - double levelFromScenarioBuilder = study.scenarioInitialHydroLevels[areaIndex][y]; - if (levelFromScenarioBuilder >= 0.) - { - randomLevel = levelFromScenarioBuilder; - } - } + // Possibly update the intial level from scenario builder + if (study.parameters.useCustomScenario) + { + double levelFromScenarioBuilder = study.scenarioInitialHydroLevels[areaIndex][y]; + if (levelFromScenarioBuilder >= 0.) + { + randomLevel = levelFromScenarioBuilder; + } + } // Current area's hydro starting (or initial) level computation // (no matter if the year is performed or not, we always draw a random initial @@ -773,12 +780,7 @@ void ISimulation::computeRandomNumbers( bool SpilledEnergySeedIsDefault = (currentSpilledEnergySeed == defaultSpilledEnergySeed); areaIndex = 0; study.areas.each( - [&isPerformed, - &areaIndex, - &randomUnsupplied, - &randomSpilled, - &randomForYears, - &indexYear, + [&isPerformed, &areaIndex, &randomUnsupplied, &randomSpilled, &randomForYears, &indexYear, &SpilledEnergySeedIsDefault](Data::Area& area) { (void)area; // Avoiding warnings at compilation (unused variable) on linux @@ -1028,19 +1030,19 @@ void ISimulation::loopThroughYears(uint firstYear, // continue; auto task = std::make_shared>( - this, - y, - set_it->yearFailed, - set_it->isFirstPerformedYearOfASet, - pFirstSetParallelWithAPerformedYearWasRun, - numSpace, - randomForParallelYears, - performCalculations, - study, - state[numSpace], - pYearByYear, - pDurationCollector, - pResultWriter); + this, + y, + set_it->yearFailed, + set_it->isFirstPerformedYearOfASet, + pFirstSetParallelWithAPerformedYearWasRun, + numSpace, + randomForParallelYears, + performCalculations, + study, + state[numSpace], + pYearByYear, + pDurationCollector, + pResultWriter); results.add(Concurrency::AddTask(*pQueueService, task)); } // End loop over years of the current set of parallel years diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 7fb3336599..ed13d54fe1 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -513,11 +513,11 @@ void SIM_RenseignementProblemeHebdo(const Study& study, if (area.hydro.useWaterValue) { - problem.CaracteristiquesHydrauliques[k].WeeklyWaterValueStateRegular - = getWaterValue(problem.previousSimulationFinalLevel[k] * 100 - / area.hydro.reservoirCapacity, - area.hydro.waterValues, - weekFirstDay); + problem.CaracteristiquesHydrauliques[k].WeeklyWaterValueStateRegular = + getWaterValue( + problem.previousSimulationFinalLevel[k] * 100 / area.hydro.reservoirCapacity, + area.hydro.waterValues, + weekFirstDay); } if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable > 0) diff --git a/src/solver/simulation/timeseries-numbers.cpp b/src/solver/simulation/timeseries-numbers.cpp index 446a0efa08..52b1213ada 100644 --- a/src/solver/simulation/timeseries-numbers.cpp +++ b/src/solver/simulation/timeseries-numbers.cpp @@ -329,7 +329,8 @@ bool checkInterModalConsistencyForArea(const Area& area, { logs.error() << "Inter-modal correlation: time-series numbers of inter-modal modes in area '" - << area.name << "'" << " are not identical"; + << area.name << "'" + << " are not identical"; return false; } diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index dfb2d8c1f4..69f62a10a1 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -99,9 +99,7 @@ class GeneratorTempData final const T& duration) const; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, - unsigned nbOfSeriesToGen, - MersenneTwister& rndGenerator): +GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen, MersenneTwister& rndGenerator): derated(study.parameters.derated), nbOfSeriesToGen_(nbOfSeriesToGen), rndgenerator(rndGenerator) @@ -618,13 +616,10 @@ listOfLinks getAllLinksToGen(Data::AreaList& areas) areas.each( [&links](const Data::Area& area) { - std::ranges::for_each(area.links, - [&links](auto& l) + std::ranges::for_each(area.links, [&links](auto& l) { if (!l.second->tsGeneration.forceNoGeneration) - { links.push_back(l.second); - } }); }); @@ -703,10 +698,7 @@ bool generateLinkTimeSeries(Data::Study& study, } // DIRECT - AvailabilityTSGeneratorData tsConfigDataDirect(tsGenStruct, - ts, - tsGenStruct.modulationCapacityDirect, - link->with->name); + AvailabilityTSGeneratorData tsConfigDataDirect(tsGenStruct, ts, tsGenStruct.modulationCapacityDirect, link->with->name); generator.generateTS(*link->from, tsConfigDataDirect); @@ -715,14 +707,12 @@ bool generateLinkTimeSeries(Data::Study& study, writeResultsToDisk(study, writer, ts.timeSeries, filePath); // INDIRECT - AvailabilityTSGeneratorData tsConfigDataIndirect(tsGenStruct, - ts, - tsGenStruct.modulationCapacityIndirect, - link->with->name); + AvailabilityTSGeneratorData tsConfigDataIndirect(tsGenStruct, ts, tsGenStruct.modulationCapacityIndirect, link->with->name); generator.generateTS(*link->from, tsConfigDataIndirect); - filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + "_indirect.txt"; + filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + + "_indirect.txt"; writeResultsToDisk(study, writer, ts.timeSeries, filePath); } diff --git a/src/solver/ts-generator/xcast/xcast.cpp b/src/solver/ts-generator/xcast/xcast.cpp index 56f7234119..ca0c96087a 100644 --- a/src/solver/ts-generator/xcast/xcast.cpp +++ b/src/solver/ts-generator/xcast/xcast.cpp @@ -593,8 +593,7 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi if (study.parameters.derated) { - study.areas.each([&predicate](Data::Area& area) - { predicate.matrix(area).averageTimeseries(); }); + study.areas.each([&predicate](Data::Area& area) { predicate.matrix(area).averageTimeseries(); }); } if (study.parameters.timeSeriesToArchive & timeSeriesType) diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index 2cc81b80fa..1f2f5e4169 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -56,9 +56,10 @@ static void checkSetSolverSpecificParameters(bool status, } } -static void TuneSolverSpecificOptions(MPSolver* solver, - const std::string& solverName, - const std::string& solverParameters) +static void TuneSolverSpecificOptions( + MPSolver* solver, + const std::string& solverName, + const std::string& solverParameters) { if (!solver) { @@ -134,6 +135,7 @@ MPSolver* ProblemSimplexeNommeConverter::Convert() return solver; } + void ProblemSimplexeNommeConverter::CopyMatrix(const MPSolver* solver) const { auto variables = solver->variables(); diff --git a/src/solver/variable/include/antares/solver/variable/economy/all.h b/src/solver/variable/include/antares/solver/variable/economy/all.h index b7a62eb6bf..a3c637c43f 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/all.h +++ b/src/solver/variable/include/antares/solver/variable/economy/all.h @@ -248,8 +248,8 @@ typedef Variable::Join< Variable::Areas, // Variables for each set of areas Variable::Join, - // Variables for each binding constraint - Variable::BindingConstraints>> + // Variables for each binding constraint + Variable::BindingConstraints>> ItemList; /*! diff --git a/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h b/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h index 8a1f97676f..6d7e02fa3e 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h +++ b/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h @@ -147,6 +147,7 @@ class BindingConstMarginCost NextType::simulationEnd(); } + void initializeFromStudy(Data::Study& study) { pNbYearsParallel = study.maxNbYearsInParallel; @@ -256,8 +257,8 @@ class BindingConstMarginCost for (int dayInTheWeek = 0; dayInTheWeek < 7; dayInTheWeek++) { pValuesForTheCurrentYear[numSpace].day[dayInTheYear] - -= state.problemeHebdo - ->ResultatsContraintesCouplantes[associatedBC_][dayInTheWeek]; + -= state.problemeHebdo + ->ResultatsContraintesCouplantes[associatedBC_][dayInTheWeek]; dayInTheYear++; } @@ -269,7 +270,7 @@ class BindingConstMarginCost { uint weekInTheYear = state.weekInTheYear; double weeklyValue = -state.problemeHebdo - ->ResultatsContraintesCouplantes[associatedBC_][0]; + ->ResultatsContraintesCouplantes[associatedBC_][0]; pValuesForTheCurrentYear[numSpace].week[weekInTheYear] = weeklyValue; diff --git a/src/solver/variable/include/antares/solver/variable/endoflist.h b/src/solver/variable/include/antares/solver/variable/endoflist.h index d8cb5dd69d..7c32c32ecb 100644 --- a/src/solver/variable/include/antares/solver/variable/endoflist.h +++ b/src/solver/variable/include/antares/solver/variable/endoflist.h @@ -254,6 +254,7 @@ class EndOfList static void computeSpatialAggregateWith(O&, const Data::Area*, uint numSpace) { UNUSED_VARIABLE(numSpace); + assert(false); } template diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index 96a66aef3e..bfad50326f 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -82,7 +82,7 @@ HydroMaxPowerStudy::HydroMaxPowerStudy() area = addAreaToStudy("Area"); area->thermal.unsuppliedEnergyCost = 1; - setNumberMCyears(1); + setNumberMCyears(1); TimeSeriesConfigurer loadTSconfig(area->load.series.timeSeries); loadTSconfig.setColumnCount(1).fillColumnWith(0, loadInArea); diff --git a/src/tests/end-to-end/utils/utils.cpp b/src/tests/end-to-end/utils/utils.cpp index fdba99c007..a42891ea45 100644 --- a/src/tests/end-to-end/utils/utils.cpp +++ b/src/tests/end-to-end/utils/utils.cpp @@ -219,8 +219,7 @@ void StudyBuilder::setNumberMCyears(unsigned int nbYears) { study->parameters.resetPlaylist(nbYears); study->areas.resizeAllTimeseriesNumbers(nbYears); - study->areas.each([&](Data::Area& area) - { area.hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); }); + study->areas.each([&](Data::Area& area) { area.hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); }); } void StudyBuilder::playOnlyYear(unsigned int year) diff --git a/src/tests/end-to-end/utils/utils.h b/src/tests/end-to-end/utils/utils.h index 84362bf2e0..1fa55efbff 100644 --- a/src/tests/end-to-end/utils/utils.h +++ b/src/tests/end-to-end/utils/utils.h @@ -164,17 +164,14 @@ class ScenarioBuilderRule { return rules_->load; } - BindingConstraintsTSNumberData& bcGroup() { return rules_->binding_constraints; } - hydroTSNumberData& hydro() { return rules_->hydro; } - private: Rules::Ptr rules_; }; diff --git a/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp b/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp index 04d1c7be9f..e97f4e3524 100644 --- a/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp +++ b/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp @@ -19,17 +19,15 @@ ** along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE antlr_interface tests -#include - -#include #include +#include +#include "antlr4-runtime.h" +#include #include "ExprLexer.h" #include "ExprParser.h" -#include "antlr4-runtime.h" using namespace antlr4; - BOOST_AUTO_TEST_CASE(test_antlr_interface) { const std::string my_input = "y = b + a*x"; diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp index de09d007d1..7879559fb0 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp @@ -355,12 +355,10 @@ BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_17__hydro_level_0_123_is_chosen__re AreaName::Vector splitKey = {"hl", "area 1", yearNumber}; my_rule.readLine(splitKey, level); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_1->index), - level.to()); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_1->index), level.to()); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_1->index][yearNumber.to()], - level.to()); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_1->index][yearNumber.to()], level.to()); } BOOST_FIXTURE_TEST_CASE( @@ -372,11 +370,10 @@ BOOST_FIXTURE_TEST_CASE( AreaName::Vector splitKey = {"hl", "area 2", yearNumber}; BOOST_CHECK(my_rule.readLine(splitKey, level)); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_2->index), - 1.); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_2->index), 1.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_2->index][yearNumber.to()], 1.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_2->index][yearNumber.to()], 1.); } BOOST_FIXTURE_TEST_CASE( @@ -388,11 +385,10 @@ BOOST_FIXTURE_TEST_CASE( AreaName::Vector splitKey = {"hl", "area 3", yearNumber}; BOOST_CHECK(my_rule.readLine(splitKey, level)); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_3->index), - 0.); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_3->index), 0.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_3->index][yearNumber.to()], 0.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_3->index][yearNumber.to()], 0.); } // ======================== @@ -400,47 +396,47 @@ BOOST_FIXTURE_TEST_CASE( // ======================== BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_8__hydro_level_0_342_is_chosen__reading_OK, Fixture) { - AreaName yearNumber = "8"; - String level = "0.342"; - AreaName::Vector splitKey = {"hfl", "area 1", yearNumber}; - my_rule.readLine(splitKey, level, false); + AreaName yearNumber = "8"; + String level = "0.342"; + AreaName::Vector splitKey = {"hfl", "area 1", yearNumber}; + my_rule.readLine(splitKey, level, false); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_1->index), - level.to()); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_1->index), + level.to()); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_1->index][yearNumber.to()], - level.to()); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_1->index][yearNumber.to()], + level.to()); } -BOOST_FIXTURE_TEST_CASE( - on_area2_and_on_year_1__hydro_level_2_4_is_chosen_level_lowered_to_1__reading_OK, - Fixture) +BOOST_FIXTURE_TEST_CASE(on_area2_and_on_year_1__hydro_level_2_4_is_chosen_level_lowered_to_1__reading_OK, Fixture) { - AreaName yearNumber = "1"; - String level = "2.4"; - AreaName::Vector splitKey = {"hfl", "area 2", yearNumber}; - BOOST_CHECK(my_rule.readLine(splitKey, level, false)); + AreaName yearNumber = "1"; + String level = "2.4"; + AreaName::Vector splitKey = {"hfl", "area 2", yearNumber}; + BOOST_CHECK(my_rule.readLine(splitKey, level, false)); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_2->index), 1.); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_2->index), + 1.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_2->index][yearNumber.to()], 1.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_2->index][yearNumber.to()], + 1.); } -BOOST_FIXTURE_TEST_CASE( - on_area3_and_on_year_3__hydro_level_neg_5_2_is_chosen__level_raised_to_0__reading_OK, - Fixture) +BOOST_FIXTURE_TEST_CASE(on_area3_and_on_year_3__hydro_level_neg_5_2_is_chosen__level_raised_to_0__reading_OK, Fixture) { - AreaName yearNumber = "3"; - String level = "-5.2"; - AreaName::Vector splitKey = {"hfl", "area 3", yearNumber}; - BOOST_CHECK(my_rule.readLine(splitKey, level, false)); + AreaName yearNumber = "3"; + String level = "-5.2"; + AreaName::Vector splitKey = {"hfl", "area 3", yearNumber}; + BOOST_CHECK(my_rule.readLine(splitKey, level, false)); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_3->index), 0.); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_3->index), + 0.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_3->index][yearNumber.to()], 0.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_3->index][yearNumber.to()], + 0.); } // ====================== diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp index 64813637fc..13d5a38b48 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp @@ -436,9 +436,7 @@ BOOST_FIXTURE_TEST_CASE( // ======================== // Tests on Hydro final levels // ======================== -BOOST_FIXTURE_TEST_CASE( - HYDRO_FINAL_LEVEL__TS_number_for_many_areas_and_years__generated_and_ref_sc_buider_files_are_identical, - saveFixture) +BOOST_FIXTURE_TEST_CASE(HYDRO_FINAL_LEVEL__TS_number_for_many_areas_and_years__generated_and_ref_sc_buider_files_are_identical, saveFixture) { my_rule->hydroFinalLevels.setTSnumber(area_1->index, 4, 8); my_rule->hydroFinalLevels.setTSnumber(area_2->index, 11, 3); diff --git a/src/tests/src/libs/antares/test_utils.cpp b/src/tests/src/libs/antares/test_utils.cpp index 5cb05e27c4..ad7e97d833 100644 --- a/src/tests/src/libs/antares/test_utils.cpp +++ b/src/tests/src/libs/antares/test_utils.cpp @@ -19,15 +19,15 @@ * along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE test utils -#include #include #include -#include - #include +#include +#include + namespace fs = std::filesystem; namespace @@ -99,8 +99,7 @@ BOOST_AUTO_TEST_CASE(yuni_normalize_vs_std_lexically_normal) { Yuni::String yuniNorm; Yuni::IO::Normalize(yuniNorm, path.string()); - BOOST_CHECK_MESSAGE(path.lexically_normal().string() == yuniNorm, - std::string("Check failed for ") + path.string()); + BOOST_CHECK_MESSAGE(path.lexically_normal().string() == yuniNorm, std::string("Check failed for ") + path.string()); }; helper(fs::path("a/./b/..")); helper(fs::path("a/.///b/../")); diff --git a/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp b/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp index 87978fbcaa..ebfbc4bba8 100644 --- a/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp +++ b/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp @@ -19,22 +19,19 @@ ** along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE yamlcpp tests -#include +#include +#include +#include "yaml-cpp/yaml.h" #include +#include #include #include -#include -#include - -#include "yaml-cpp/yaml.h" - // our data types struct Vec3 { float x, y, z; }; - struct Power { std::string name; @@ -47,7 +44,6 @@ struct Monster Vec3 position; std::vector powers; }; - namespace YAML { template<> @@ -75,7 +71,6 @@ struct convert return true; } }; - template<> struct convert { @@ -94,7 +89,6 @@ struct convert return true; } }; - template<> struct convert { @@ -114,7 +108,7 @@ struct convert rhs.name = node["name"].as(); rhs.position = node["position"].as(); const YAML::Node& powers = node["powers"]; - for (const auto power: powers) + for (const auto power : powers) { rhs.powers.push_back(power.as()); } diff --git a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp index a38d7ea12c..d4a6c3512b 100644 --- a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp +++ b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp @@ -6,24 +6,23 @@ #define WIN32_LEAN_AND_MEAN #include -#include - #include "include/antares/solver/simulation/hydro-final-reservoir-level-functions.h" #include "include/antares/study/parts/hydro/finalLevelValidator.h" +#include using namespace Antares::Solver; using namespace Antares::Data; + struct Fixture { Fixture(const Fixture& f) = delete; Fixture(const Fixture&& f) = delete; Fixture& operator=(const Fixture& f) = delete; Fixture& operator=(const Fixture&& f) = delete; - Fixture() { - // Simulation last day must be 365 so that final level checks succeeds + // Simulation last day must be 365 so that final level checks succeeds study->parameters.simulationDays.end = 365; study->parameters.firstMonthInYear = january; uint nbYears = study->parameters.nbYears = 2; @@ -57,6 +56,7 @@ struct Fixture area_1->hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); area_2->hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); + // Scenario builder for initial and final reservoir levels // ------------------------------------------------------- uint areasCount = study->areas.size(); @@ -96,7 +96,7 @@ struct Fixture // ... Area 2 : Inflows time series area_2->hydro.series->storage.resize(nbInflowTS, 365); area_2->hydro.series->storage.timeSeries.fill(300.); - area_2->hydro.series->storage[0][0] = 300. + 1.; // DAYS_PER_YEAR + area_2->hydro.series->storage[0][0] = 300. + 1.; //DAYS_PER_YEAR area_2->hydro.series->storage[0][DAYS_PER_YEAR - 1] = 300. + 2.; } @@ -178,8 +178,7 @@ BOOST_AUTO_TEST_CASE(final_level_not_set_by_user____check_succeeds_but_final_lev BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); } -BOOST_AUTO_TEST_CASE( - initial_level_month_and_simulation_first_month_different___check_fails_and_final_level_not_usable) +BOOST_AUTO_TEST_CASE(initial_level_month_and_simulation_first_month_different___check_fails_and_final_level_not_usable) { uint year = 0; area_1->hydro.initializeReservoirLevelDate = 3; // initialize reservoir level != January @@ -234,8 +233,7 @@ BOOST_AUTO_TEST_CASE(final_level_out_of_rule_curves___check_fails_and_final_leve BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); } -BOOST_AUTO_TEST_CASE( - final_level_unreachable_because_of_too_few_inflows___check_fails_and_final_level_not_usable) +BOOST_AUTO_TEST_CASE(final_level_unreachable_because_of_too_few_inflows___check_fails_and_final_level_not_usable) { area_1->hydro.reservoirCapacity = 185000; uint year = 0; @@ -274,4 +272,4 @@ BOOST_AUTO_TEST_CASE(check_all_areas_final_levels_when_config_is_ok___all_checks BOOST_CHECK_EQUAL(area_2->hydro.deltaBetweenFinalAndInitialLevels[1].value(), 4.3 - 2.4); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From fc04d70d459050a4385302b6b40b1c5c8693409b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 26 Jun 2024 11:43:50 +0200 Subject: [PATCH 037/127] Check formatting as part of the CI (workflow only) (#2198) --- .github/workflows/clang-format.yml | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/clang-format.yml diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 0000000000..9e00892851 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,36 @@ +name: Check cpp formatting + +on: + push: + branches: + - develop + - feature/* + - features/* + - fix/* + +jobs: + build: + name: clang-format + + runs-on: ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Print version + run: clang-format --version + + - name: clang-format + run: cd src && ./format-code.sh + + - name: git diff + run: | + DIFF=`git status --porcelain` + if [[ $DIFF ]]; then + echo "The following files are not well formatted" + echo "$DIFF" + exit 1 + else + echo "Code is well formatted, congrats !" + fi From 03481750724aa75f662f29ee5a4c428a2b64383f Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 27 Jun 2024 00:16:20 +0200 Subject: [PATCH 038/127] Remove some compile warnings (#2199) --- src/libs/antares/study/area/area.cpp | 3 +-- .../study/include/antares/study/parameters.h | 3 +-- .../antares/study/parts/hydro/container.h | 2 +- src/libs/antares/study/load.cpp | 2 +- src/libs/antares/study/parameters.cpp | 3 +-- src/libs/antares/study/parts/hydro/container.cpp | 2 +- .../study/parts/hydro/finalLevelValidator.cpp | 16 ++++++++-------- .../study/parameters/parameters-tests.cpp | 4 ++-- 8 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/libs/antares/study/area/area.cpp b/src/libs/antares/study/area/area.cpp index da99f973ae..929e8653c2 100644 --- a/src/libs/antares/study/area/area.cpp +++ b/src/libs/antares/study/area/area.cpp @@ -46,8 +46,7 @@ void Area::internalInitialize() Area::Area(): reserves(fhrMax, HOURS_PER_YEAR), - miscGen(fhhMax, HOURS_PER_YEAR), - hydro(*this) + miscGen(fhhMax, HOURS_PER_YEAR) { internalInitialize(); } diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index 791e20f865..73ba5b5f77 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -76,8 +76,7 @@ class Parameters final ** \return True if the settings have been loaded, false if at least one error has occured */ bool loadFromFile(const AnyString& filename, - const StudyVersion& version, - const StudyLoadOptions& options); + const StudyVersion& version); /*! ** \brief Prepare all settings for a simulation diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index e09970b79c..6748c830e7 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -81,7 +81,7 @@ class PartHydro /*! ** \brief Default Constructor */ - PartHydro(const Data::Area& area); + PartHydro(); //! Destructor ~PartHydro(); diff --git a/src/libs/antares/study/load.cpp b/src/libs/antares/study/load.cpp index 4175bc2305..749d0d81ff 100644 --- a/src/libs/antares/study/load.cpp +++ b/src/libs/antares/study/load.cpp @@ -83,7 +83,7 @@ bool Study::internalLoadIni(const String& path, const StudyLoadOptions& options) } // Load the general data buffer.clear() << folderSettings << SEP << "generaldata.ini"; - bool errorWhileLoading = !parameters.loadFromFile(buffer, header.version, options); + bool errorWhileLoading = !parameters.loadFromFile(buffer, header.version); parameters.validateOptions(options); diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index 7337b9c8b0..dbfb7f81e2 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -1958,8 +1958,7 @@ void Parameters::saveToINI(IniFile& ini) const } bool Parameters::loadFromFile(const AnyString& filename, - const StudyVersion& version, - const StudyLoadOptions& options) + const StudyVersion& version) { // Loading the INI file IniFile ini; diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index c9dc476de5..e09ae5a8fb 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -32,7 +32,7 @@ using namespace Yuni; namespace Antares::Data { -PartHydro::PartHydro(const Data::Area& area) : +PartHydro::PartHydro() : interDailyBreakdown(0.), intraDailyModulation(2.), intermonthlyBreakdown(0), diff --git a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp index 2229f75f97..c3ea96ca08 100644 --- a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp +++ b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp @@ -37,15 +37,15 @@ FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, double finalLevel, const unsigned int year, const unsigned int lastSimulationDay, - const unsigned int firstMonthOfSimulation) - : hydro_(hydro), - areaName_(areaName), - areaIndex_(areaIndex), - initialLevel_(initialLevel), - finalLevel_(finalLevel), + const unsigned int firstMonthOfSimulation) : year_(year), lastSimulationDay_(lastSimulationDay), - firstMonthOfSimulation_(firstMonthOfSimulation) + firstMonthOfSimulation_(firstMonthOfSimulation), + hydro_(hydro), + areaIndex_(areaIndex), + areaName_(areaName), + initialLevel_(initialLevel), + finalLevel_(finalLevel) { } @@ -96,7 +96,7 @@ bool FinalLevelValidator::checkForInfeasibility() bool FinalLevelValidator::hydroAllocationStartMatchesSimulation() const { - int initReservoirLvlMonth = hydro_.initializeReservoirLevelDate; // month [0-11] + unsigned initReservoirLvlMonth = hydro_.initializeReservoirLevelDate; // month [0-11] if (lastSimulationDay_ == DAYS_PER_YEAR && initReservoirLvlMonth == firstMonthOfSimulation_) return true; diff --git a/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp b/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp index 07c8e7fa1d..5e0da57a10 100644 --- a/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp +++ b/src/tests/src/libs/antares/study/parameters/parameters-tests.cpp @@ -69,7 +69,7 @@ BOOST_FIXTURE_TEST_CASE(loadValid, Fixture) options.optOptions.ortoolsSolver = "xpress"; writeValidFile(); - p.loadFromFile(path.string(), version, options); + p.loadFromFile(path.string(), version); p.validateOptions(options); p.fixBadValues(); @@ -94,7 +94,7 @@ BOOST_FIXTURE_TEST_CASE(fixBadValue, Fixture) BOOST_FIXTURE_TEST_CASE(invalidValues, Fixture) { writeInvalidFile(); - BOOST_CHECK(p.loadFromFile(path.string(), version, options)); + BOOST_CHECK(p.loadFromFile(path.string(), version)); p.validateOptions(options); p.fixBadValues(); From b8f1849561a9f0f5281d0643d49d7b97060bcf06 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 27 Jun 2024 00:23:08 +0200 Subject: [PATCH 039/127] Remove Antares::Memory::Array (#2187) --- .../array/include/antares/array/matrix.h | 9 - .../array/include/antares/array/matrix.hxx | 25 --- .../memory/include/antares/memory/memory.h | 48 ----- .../memory/include/antares/memory/memory.hxx | 48 ----- .../solver/variable/storage/minmax-data.h | 44 ++--- .../antares/solver/variable/storage/minmax.h | 20 +- .../solver/variable/storage/minmax.hxx | 1 - src/solver/variable/storage/minmax-data.cpp | 179 ++++-------------- 8 files changed, 54 insertions(+), 320 deletions(-) diff --git a/src/libs/antares/array/include/antares/array/matrix.h b/src/libs/antares/array/include/antares/array/matrix.h index f1d65c5a43..48eb27dd6f 100644 --- a/src/libs/antares/array/include/antares/array/matrix.h +++ b/src/libs/antares/array/include/antares/array/matrix.h @@ -339,15 +339,6 @@ class Matrix template void pasteToColumn(uint x, const U* data); - /*! - ** \brief Copy values into a given column in the matrix - ** - ** \param x The column index (zero-based) - ** \param data The data to copy - */ - template - void pasteToColumn(uint x, const Antares::Memory::Array& data); - /*! ** \brief Set a entire column with a given value ** diff --git a/src/libs/antares/array/include/antares/array/matrix.hxx b/src/libs/antares/array/include/antares/array/matrix.hxx index 7fabacba02..78fef9186a 100644 --- a/src/libs/antares/array/include/antares/array/matrix.hxx +++ b/src/libs/antares/array/include/antares/array/matrix.hxx @@ -488,31 +488,6 @@ void Matrix::pasteToColumn(uint x, const U* data) markAsModified(); } -template -template -void Matrix::pasteToColumn(uint x, const Antares::Memory::Array& data) -{ - assert(x < width and "Invalid column index (bigger than `this->width`)"); - ColumnType& column = entry[x]; - - // if the two types are strictly equal, we can perform some major - // optimisations - if (Yuni::Static::Type::StrictlyEqual::Yes) - { - (void)::memcpy(column, data, sizeof(T) * height); - } - else - { - // ...otherwise we have to copy each item by hand in any cases - for (uint y = 0; y != height; ++y) - { - column[y] = (T)data[y]; - } - } - - markAsModified(); -} - template void Matrix::fillColumn(uint x, const T& value) { diff --git a/src/libs/antares/memory/include/antares/memory/memory.h b/src/libs/antares/memory/include/antares/memory/memory.h index 89eb4815f4..42515c5fce 100644 --- a/src/libs/antares/memory/include/antares/memory/memory.h +++ b/src/libs/antares/memory/include/antares/memory/memory.h @@ -33,52 +33,6 @@ namespace Antares class Memory final: public Yuni::Policy::ObjectLevelLockable { public: - template - class Array final - { - public: - //! \name Constructors - //@{ - /*! - ** \brief Default constructor - */ - Array() = default; - - /*! - ** \brief Constructor from null - */ - explicit Array(const Yuni::NullPtr&); - - /*! - ** \brief Constructor with an initial allocation size - */ - explicit Array(size_t size); - - //! Copy constructor (must be empty) - Array(const Array& copy); - - template - Array(const Array&); - - /*! - ** \brief Destructor - */ - ~Array(); - //@} - - /*! - ** \brief - */ - void allocate(size_t size); - - T& operator[](uint i); - const T& operator[](uint i) const; - - private: - T* pPointer = nullptr; - - }; // class Array - template struct Stored final { @@ -101,7 +55,6 @@ class Memory final: public Yuni::Policy::ObjectLevelLockable template static void Assign(uint count, U* array, const U& value); -public: template static void Allocate(T*& out, size_t size); @@ -117,7 +70,6 @@ class Memory final: public Yuni::Policy::ObjectLevelLockable template static void Release(T*& pointer); -public: //! \name Constructor & Destructor //@{ /*! diff --git a/src/libs/antares/memory/include/antares/memory/memory.hxx b/src/libs/antares/memory/include/antares/memory/memory.hxx index 1b575150a5..aeb99b413d 100644 --- a/src/libs/antares/memory/include/antares/memory/memory.hxx +++ b/src/libs/antares/memory/include/antares/memory/memory.hxx @@ -28,54 +28,6 @@ inline uint64_t Memory::processID() const return pProcessID; } -template -Memory::Array::Array(const Yuni::NullPtr&) -{ -} - -template -Memory::Array::Array(const Memory::Array&) -{ -} - -template -template -Memory::Array::Array(const Memory::Array&) -{ -} - -template -inline Memory::Array::Array(size_t size) -{ - allocate(size); -} - -template -inline Memory::Array::~Array() -{ - delete[] pPointer; - pPointer = nullptr; -} - -template -void Memory::Array::allocate(size_t size) -{ - delete[] pPointer; - pPointer = new T[size]; -} - -template -T& Memory::Array::operator[](uint i) -{ - return (T&)pPointer[i]; -} - -template -const T& Memory::Array::operator[](uint i) const -{ - return (const T&)pPointer[i]; -} - template inline void Memory::Release(T*& pointer) { diff --git a/src/solver/variable/include/antares/solver/variable/storage/minmax-data.h b/src/solver/variable/include/antares/solver/variable/storage/minmax-data.h index c444ca73c9..156f53fec2 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/minmax-data.h +++ b/src/solver/variable/include/antares/solver/variable/storage/minmax-data.h @@ -21,19 +21,11 @@ #ifndef __SOLVER_VARIABLE_STORAGE_MINMAX_DATA_H__ #define __SOLVER_VARIABLE_STORAGE_MINMAX_DATA_H__ -#include -#include +#include + #include "antares/solver/variable/storage/intermediate.h" -namespace Antares -{ -namespace Solver -{ -namespace Variable -{ -namespace R -{ -namespace AllYears +namespace Antares::Solver::Variable::R::AllYears { class MinMaxData { @@ -44,17 +36,8 @@ class MinMaxData uint32_t indice; }; -public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Default constructor - */ - MinMaxData(); - //! Destructor - ~MinMaxData(); - - void initialize(); + MinMaxData() = default; + ~MinMaxData() = default; void resetInf(); void resetSup(); @@ -62,19 +45,14 @@ class MinMaxData void mergeInf(uint year, const IntermediateValues& rhs); void mergeSup(uint year, const IntermediateValues& rhs); -public: - Data annual; - Data monthly[maxMonths]; - Data weekly[maxWeeksInAYear]; - Data daily[maxDaysInAYear]; - Antares::Memory::Stored::Type hourly; + std::vector annual{1}; + std::vector monthly{maxMonths}; + std::vector weekly{maxWeeksInAYear}; + std::vector daily{maxDaysInAYear}; + std::vector hourly{maxHoursInAYear}; }; // class MinMaxData -} // namespace AllYears -} // namespace R -} // namespace Variable -} // namespace Solver -} // namespace Antares +} // namespace Antares::Solver::Variable::R::AllYears #endif // __SOLVER_VARIABLE_STORAGE_MINMAX_DATA_H__ diff --git a/src/solver/variable/include/antares/solver/variable/storage/minmax.h b/src/solver/variable/include/antares/solver/variable/storage/minmax.h index b9aaba7bc3..8e9603fa16 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/minmax.h +++ b/src/solver/variable/include/antares/solver/variable/storage/minmax.h @@ -84,20 +84,20 @@ struct MinMaxBase: public NextT { case Category::hourly: InternalExportIndices(report, - Memory::RawPointer(minmax.hourly), + Memory::RawPointer(minmax.hourly.data()), fileLevel); break; case Category::daily: - InternalExportIndices(report, minmax.daily, fileLevel); + InternalExportIndices(report, minmax.daily.data(), fileLevel); break; case Category::weekly: - InternalExportIndices(report, minmax.weekly, fileLevel); + InternalExportIndices(report, minmax.weekly.data(), fileLevel); break; case Category::monthly: - InternalExportIndices(report, minmax.monthly, fileLevel); + InternalExportIndices(report, minmax.monthly.data(), fileLevel); break; case Category::annual: - InternalExportIndices<1, VCardT>(report, &minmax.annual, fileLevel); + InternalExportIndices<1, VCardT>(report, minmax.annual.data(), fileLevel); break; } } @@ -107,19 +107,19 @@ struct MinMaxBase: public NextT { case Category::hourly: InternalExportValues(report, - Memory::RawPointer(minmax.hourly)); + Memory::RawPointer(minmax.hourly.data())); break; case Category::daily: - InternalExportValues(report, minmax.daily); + InternalExportValues(report, minmax.daily.data()); break; case Category::weekly: - InternalExportValues(report, minmax.weekly); + InternalExportValues(report, minmax.weekly.data()); break; case Category::monthly: - InternalExportValues(report, minmax.monthly); + InternalExportValues(report, minmax.monthly.data()); break; case Category::annual: - InternalExportValues<1, VCardT>(report, &minmax.annual); + InternalExportValues<1, VCardT>(report, minmax.annual.data()); break; } } diff --git a/src/solver/variable/include/antares/solver/variable/storage/minmax.hxx b/src/solver/variable/include/antares/solver/variable/storage/minmax.hxx index de94f1d571..741e56cbba 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/minmax.hxx +++ b/src/solver/variable/include/antares/solver/variable/storage/minmax.hxx @@ -36,7 +36,6 @@ namespace AllYears template inline void MinMaxBase::initializeFromStudy(Data::Study& study) { - minmax.initialize(); // Next NextType::initializeFromStudy(study); } diff --git a/src/solver/variable/storage/minmax-data.cpp b/src/solver/variable/storage/minmax-data.cpp index 7d6e3f0565..6d25480806 100644 --- a/src/solver/variable/storage/minmax-data.cpp +++ b/src/solver/variable/storage/minmax-data.cpp @@ -21,135 +21,40 @@ #include "antares/solver/variable/storage/minmax-data.h" -#include - -#include - #include "antares/solver/variable/storage/intermediate.h" -using namespace Yuni; - namespace Antares::Solver::Variable::R::AllYears { -namespace // anonymous -{ constexpr double eps = 1.e-7; -template -struct ArrayInitializer +static void initArray(bool opInferior, std::vector& array) { - static void Init(Antares::Memory::Array& array) - { - for (uint i = 0; i != Size; ++i) - { - MinMaxData::Data& data = array[i]; - data.value = DBL_MAX; // +inf - data.indice = (uint32_t)(-1); // invalid indice - } - } - - static void Init(MinMaxData::Data* array) + for (auto& data : array) { - for (uint i = 0; i != Size; ++i) - { - MinMaxData::Data& data = array[i]; - data.value = DBL_MAX; // +inf - data.indice = (uint32_t)(-1); // invalid indice - } + data.value = opInferior ? DBL_MAX : -DBL_MAX; // +inf or -inf + data.indice = (uint32_t)(-1); // invalid indice } +} -}; // class ArrayInitializer - -template -struct ArrayInitializer +static void mergeArray(bool opInferior, + unsigned year, + std::vector& results, + const double* values) { - static void Init(Antares::Memory::Array& array) - { - for (uint i = 0; i != Size; ++i) - { - // Contrary to what we could guess, DBL_MIN is not the smallest number - // you can hold in a double, but the smallest positive number you can - // hold in a double - MinMaxData::Data& data = array[i]; - data.value = -DBL_MAX; // -inf - data.indice = (uint32_t)(-1); // invalid indice - } - } - - static void Init(MinMaxData::Data* array) + for (unsigned i = 0; i != results.size(); ++i) { - for (uint i = 0; i != Size; ++i) - { - // Contrary to what we could guess, DBL_MIN is not the smallest number - // you can hold in a double, but the smallest positive number you can - // hold in a double - MinMaxData::Data& data = array[i]; - data.value = -DBL_MAX; // -inf - data.indice = (uint32_t)(-1); // invalid indice - } - } + MinMaxData::Data& data = results[i]; -}; // class ArrayInitializer - -template -struct MergeArray -{ - template - static void Do(const uint year, - Antares::Memory::Array& results, - const U& values) - { - for (uint i = 0; i != Size; ++i) + if (opInferior) { - MinMaxData::Data& data = results[i]; if (values[i] < data.value - eps) { data.value = values[i]; data.indice = year + 1; // The year is zero-based } } - } - - template - static void Do(const uint year, MinMaxData::Data* results, const U& values) - { - for (uint i = 0; i != Size; ++i) - { - if (values[i] < results[i].value - eps) - { - results[i].value = values[i]; - results[i].indice = year + 1; // The year is zero-based - } - } - } - -}; // class MergeArray - -template -struct MergeArray<0, Size> -{ - template - static void Do(const uint year, - Antares::Memory::Array& results, - const U& values) - { - for (uint i = 0; i != Size; ++i) - { - MinMaxData::Data& data = results[i]; - if (values[i] > data.value + eps) - { - data.value = values[i]; - data.indice = year + 1; // The year is zero-based - } - } - } - - template - static void Do(const uint year, MinMaxData::Data* results, const U& values) - { - for (uint i = 0; i != Size; ++i) + else { - MinMaxData::Data& data = results[i]; if (values[i] > data.value + eps) { data.value = values[i]; @@ -157,60 +62,42 @@ struct MergeArray<0, Size> } } } - -}; // class MergeArray - -} // anonymous namespace - -MinMaxData::MinMaxData(): - hourly(nullptr) -{ -} - -MinMaxData::~MinMaxData() -{ - Antares::Memory::Release(hourly); } void MinMaxData::resetInf() { - ArrayInitializer<1, true>::Init(&annual); - ArrayInitializer::Init(monthly); - ArrayInitializer::Init(weekly); - ArrayInitializer::Init(daily); - ArrayInitializer::Init(hourly); + initArray(true, annual); + initArray(true, monthly); + initArray(true, weekly); + initArray(true, daily); + initArray(true, hourly); } void MinMaxData::resetSup() { - ArrayInitializer<1, false>::Init(&annual); - ArrayInitializer::Init(monthly); - ArrayInitializer::Init(weekly); - ArrayInitializer::Init(daily); - ArrayInitializer::Init(hourly); -} - -void MinMaxData::initialize() -{ - Antares::Memory::Allocate(hourly, maxHoursInAYear); + initArray(false, annual); + initArray(false, monthly); + initArray(false, weekly); + initArray(false, daily); + initArray(false, hourly); } void MinMaxData::mergeInf(uint year, const IntermediateValues& rhs) { - MergeArray::Do(year, monthly, rhs.month); - MergeArray::Do(year, weekly, rhs.week); - MergeArray::Do(year, daily, rhs.day); - MergeArray::Do(year, hourly, rhs.hour); - MergeArray::Do(year, &annual, &rhs.year); + mergeArray(true, year, monthly, rhs.month); + mergeArray(true, year, weekly, rhs.week); + mergeArray(true, year, daily, rhs.day); + mergeArray(true, year, hourly, rhs.hour); + mergeArray(true, year, annual, &rhs.year); } void MinMaxData::mergeSup(uint year, const IntermediateValues& rhs) { - MergeArray::Do(year, monthly, rhs.month); - MergeArray::Do(year, weekly, rhs.week); - MergeArray::Do(year, daily, rhs.day); - MergeArray::Do(year, hourly, rhs.hour); - MergeArray::Do(year, &annual, &rhs.year); + mergeArray(false, year, monthly, rhs.month); + mergeArray(false, year, weekly, rhs.week); + mergeArray(false, year, daily, rhs.day); + mergeArray(false, year, hourly, rhs.hour); + mergeArray(false, year, annual, &rhs.year); } } // namespace Antares::Solver::Variable::R::AllYears From ea815a1f1a015b5228abb841891838b5cf0f4d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Thu, 27 Jun 2024 10:26:50 +0200 Subject: [PATCH 040/127] Simplify functions prepareClustersInMustRunMode (#2168) Spin-off from https://github.com/AntaresSimulatorTeam/Antares_Simulator/pull/2128 Credits @guilpier-code --------- Co-authored-by: Vincent Payet Co-authored-by: payetvin <113102157+payetvin@users.noreply.github.com> --- .../include/antares/study/area/scratchpad.h | 4 +- src/solver/simulation/adequacy.cpp | 30 +++++++++- src/solver/simulation/common-eco-adq.cpp | 59 ------------------- src/solver/simulation/economy.cpp | 18 +++++- .../solver/simulation/common-eco-adq.h | 7 --- 5 files changed, 47 insertions(+), 71 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/area/scratchpad.h b/src/libs/antares/study/include/antares/study/area/scratchpad.h index 3258b7423d..864d50a155 100644 --- a/src/libs/antares/study/include/antares/study/area/scratchpad.h +++ b/src/libs/antares/study/include/antares/study/area/scratchpad.h @@ -66,11 +66,11 @@ class AreaScratchpad final //! Sum of all 'must-run' clusters // This variable is initialized every MC-year - double mustrunSum[HOURS_PER_YEAR]; + std::array mustrunSum; //! Sum of all original 'must-run' clusters (adequacy only) // This variable is initialized every MC-year - double originalMustrunSum[HOURS_PER_YEAR]; + std::array originalMustrunSum; /*! ** \brief Dispatchable Generation Margin diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index 2b03f7bcdc..c2ac21dbea 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -402,7 +402,33 @@ void Adequacy::simulationEnd() void Adequacy::prepareClustersInMustRunMode(Data::Area::ScratchMap& scratchmap, uint year) { - PrepareDataFromClustersInMustrunMode(study, scratchmap, year); -} + for (uint i = 0; i < study.areas.size(); ++i) + { + auto &area = *study.areas[i]; + auto &scratchpad = scratchmap.at(&area); + + std::ranges::fill(scratchpad.mustrunSum, 0); + std::ranges::fill(scratchpad.originalMustrunSum, 0); + + auto& mrs = scratchpad.mustrunSum; + auto& adq = scratchpad.originalMustrunSum; + + for (const auto &cluster: area.thermal.list.each_mustrun_and_enabled()) + { + const auto &availableProduction = cluster->series.getColumn(year); + for (uint h = 0; h != cluster->series.timeSeries.height; ++h) + { + mrs[h] += availableProduction[h]; + } + if (cluster->mustrunOrigin) + { + for (uint h = 0; h != cluster->series.timeSeries.height; ++h) + { + adq[h] += 2 * availableProduction[h]; // Why do we add the available production twice ? + } + } + } + } +} } // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index 1f56235499..bc63e19708 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -113,65 +113,6 @@ static void RecalculDesEchangesMoyens(Data::Study& study, } } -void PrepareDataFromClustersInMustrunMode(Data::Study& study, - Data::Area::ScratchMap& scratchmap, - uint year) -{ - bool inAdequacy = (study.parameters.mode == Data::SimulationMode::Adequacy); - - for (uint i = 0; i < study.areas.size(); ++i) - { - auto& area = *study.areas[i]; - auto& scratchpad = scratchmap.at(&area); - - memset(scratchpad.mustrunSum, 0, sizeof(double) * HOURS_PER_YEAR); - if (inAdequacy) - { - memset(scratchpad.originalMustrunSum, 0, sizeof(double) * HOURS_PER_YEAR); - } - - double* mrs = scratchpad.mustrunSum; - double* adq = scratchpad.originalMustrunSum; - - for (const auto& cluster: area.thermal.list.each_mustrun_and_enabled()) - { - const auto& availableProduction = cluster->series.getColumn(year); - if (inAdequacy && cluster->mustrunOrigin) - { - for (uint h = 0; h != cluster->series.timeSeries.height; ++h) - { - mrs[h] += availableProduction[h]; - adq[h] += availableProduction[h]; - } - } - else - { - for (uint h = 0; h != cluster->series.timeSeries.height; ++h) - { - mrs[h] += availableProduction[h]; - } - } - } - - if (inAdequacy) - { - for (const auto& cluster: area.thermal.list.each_mustrun_and_enabled()) - { - if (!cluster->mustrunOrigin) - { - continue; - } - - const auto& availableProduction = cluster->series.getColumn(year); - for (uint h = 0; h != cluster->series.timeSeries.height; ++h) - { - adq[h] += availableProduction[h]; - } - } - } - } -} - bool ShouldUseQuadraticOptimisation(const Data::Study& study) { const bool flowQuadEnabled = study.parameters.variablesPrintInfo.isPrinted("FLOW QUAD."); diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 934ebc4c2c..4baef3d5b4 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -265,7 +265,23 @@ void Economy::simulationEnd() void Economy::prepareClustersInMustRunMode(Data::Area::ScratchMap& scratchmap, uint year) { - PrepareDataFromClustersInMustrunMode(study, scratchmap, year); + for (uint i = 0; i < study.areas.size(); ++i) + { + auto& area = *study.areas[i]; + auto& scratchpad = scratchmap.at(&area); + + std::ranges::fill(scratchpad.mustrunSum, 0); + + auto& mrs = scratchpad.mustrunSum; + for (const auto& cluster: area.thermal.list.each_mustrun_and_enabled()) + { + const auto& availableProduction = cluster->series.getColumn(year); + for (uint h = 0; h != cluster->series.timeSeries.height; ++h) + { + mrs[h] += availableProduction[h]; + } + } + } } } // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h index 6ea4a9e003..0bf24cd71d 100644 --- a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h +++ b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h @@ -66,13 +66,6 @@ void BuildThermalPartOfWeeklyProblem(Data::Study& study, double** thermalNoises, unsigned int year); -/*! -** \brief Prepare data from clusters in mustrun mode (eco+adq) -*/ -void PrepareDataFromClustersInMustrunMode(Data::Study& study, - Data::Area::ScratchMap& scratchmap, - uint year); - /*! ** \brief Get if the quadratic optimization should be used according ** to the input data (eco+adq) From 60977f667965ec4614a56feb0dcb9032ca3e98fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jason=20Mar=C3=A9chal?= <45510813+JasonMarechal25@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:38:21 +0200 Subject: [PATCH 041/127] Expose API [ANT-1158] (#1993) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose Antares Solver in a library. the library and target are called AntaresAPI. This API expose one entry point to run a simulation on a study. The return value of this is a data structure with the path to the simulation and the weekly problems. - New component API - Create a new project "api_client" and corresponding tests to detect API lib install regressions - rename "utils" project in tests as "in-memory-study" - promote this project at top level in tests. This allow in-memory-study to be used for any tests - create SimulationObserver. Object passed throughout all "frames" of the simulation. --------- Co-authored-by: Florian Omnès Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- .../workflows/install-cmake-328/action.yml | 4 +- .github/workflows/ubuntu.yml | 19 +- .../Expose_cpp_API.md | 10 +- .../separate_install_exe_api.md | 25 +++ src/CMakeLists.txt | 3 +- src/api/API.cpp | 116 +++++++++++ src/api/CMakeLists.txt | 42 ++++ src/api/SimulationObserver.cpp | 73 +++++++ src/api/SimulationResults.cpp | 22 ++ .../include/antares/api/SimulationResults.h | 62 ++++++ src/api/include/antares/api/solver.h | 35 ++++ src/api/private/API.h | 56 ++++++ src/api/private/SimulationObserver.h | 61 ++++++ src/api/solver.cpp | 46 +++++ src/api_client_example/CMakeLists.txt | 12 ++ src/api_client_example/README.md | 3 + src/api_client_example/src/API_client.cpp | 30 +++ src/api_client_example/src/API_client.h | 28 +++ src/api_client_example/src/CMakeLists.txt | 14 ++ src/api_client_example/tests/CMakeLists.txt | 17 ++ src/api_client_example/tests/test.cpp | 37 ++++ .../FileTreeStudyLoader.cpp | 14 +- src/libs/antares/inifile/CMakeLists.txt | 4 +- src/libs/antares/study/CMakeLists.txt | 1 - .../study/parts/short-term-storage/cluster.h | 38 ++-- src/packaging/CMakeLists.txt | 3 + src/packaging/Config.cmake.in | 6 +- src/solver/CMakeLists.txt | 1 + src/solver/application/application.cpp | 9 +- src/solver/lps/CMakeLists.txt | 24 +++ src/solver/lps/LpsFromAntares.cpp | 56 ++++++ .../antares/solver/lps/LpsFromAntares.h | 149 ++++++++++++++ src/solver/main/economy.cpp | 47 ----- src/solver/misc/options.cpp | 40 ++-- src/solver/optimisation/CMakeLists.txt | 4 +- .../HebdoProblemToLpsTranslator.cpp | 109 ++++++++++ .../adequacy_patch_weekly_optimization.cpp | 49 ++--- .../optimisation/base_weekly_optimization.cpp | 55 ++--- .../HebdoProblemToLpsTranslator.h | 81 ++++++++ .../adequacy_patch_weekly_optimization.h | 5 +- .../optimisation/base_weekly_optimization.h | 48 +++-- .../constraints/constraint_builder_utils.h | 1 + .../optimisation/opt_export_structure.h | 58 ++---- .../solver/optimisation/opt_fonctions.h | 62 +++--- .../solver/optimisation/weekly_optimization.h | 44 ++-- .../optimisation/opt_optimisation_hebdo.cpp | 45 +++-- .../opt_optimisation_lineaire.cpp | 71 ++++--- .../opt_pilotage_optimisation_lineaire.cpp | 44 ++-- .../optimisation/opt_rename_problem.cpp | 1 + .../optimisation/weekly_optimization.cpp | 43 ++-- src/solver/simulation/CMakeLists.txt | 55 ++--- src/solver/simulation/adequacy.cpp | 51 ++--- src/solver/simulation/adequacy_mode.cpp | 63 +++--- src/solver/simulation/common-eco-adq.cpp | 42 ++-- src/solver/simulation/economy.cpp | 48 +++-- src/solver/simulation/economy_mode.cpp | 64 +++--- .../solver/simulation/ISimulationObserver.h | 65 ++++++ .../antares/solver/simulation/adequacy.h | 48 ++--- .../antares/solver/simulation/adequacy_mode.h | 4 +- .../antares/solver/simulation/economy.h | 43 ++-- .../antares/solver/simulation/economy_mode.h | 5 +- .../antares/solver/simulation/solver.h | 45 +++-- .../antares/solver/simulation/solver.hxx | 23 ++- .../antares/solver/utils/name_translator.h | 38 ++-- src/tests/CMakeLists.txt | 1 + src/tests/end-to-end/CMakeLists.txt | 1 - .../binding_constraints/CMakeLists.txt | 3 +- .../test_binding_constraints.cpp | 2 +- .../end-to-end/simple_study/CMakeLists.txt | 3 +- .../end-to-end/simple_study/simple-study.cpp | 2 +- src/tests/end-to-end/utils/CMakeLists.txt | 20 -- src/tests/inmemory-study/CMakeLists.txt | 25 +++ .../in-memory-study.cpp} | 51 ++--- .../include/in-memory-study.h} | 43 ++-- src/tests/src/CMakeLists.txt | 2 + src/tests/src/api_internal/CMakeLists.txt | 27 +++ src/tests/src/api_internal/test_api.cpp | 96 +++++++++ src/tests/src/api_lib/CMakeLists.txt | 20 ++ src/tests/src/api_lib/test_api.cpp | 35 ++++ src/tests/src/libs/CMakeLists.txt | 2 +- src/tests/src/solver/CMakeLists.txt | 1 + .../test-unfeasible-problem-analyzer.cpp | 5 +- src/tests/src/solver/lps/CMakeLists.txt | 20 ++ src/tests/src/solver/lps/test_lps.cpp | 77 +++++++ .../src/solver/optimisation/CMakeLists.txt | 26 +-- .../adequacy_patch/CMakeLists.txt | 24 +++ .../{ => adequacy_patch}/adequacy_patch.cpp | 0 .../optimisation/translator/CMakeLists.txt | 20 ++ .../translator/test_translator.cpp | 189 ++++++++++++++++++ .../renderer/scenario-builder-ntc-renderer.h | 38 ++-- src/vcpkg.json | 2 +- 91 files changed, 2427 insertions(+), 729 deletions(-) create mode 100644 docs/Architecture_Decision_Records/separate_install_exe_api.md create mode 100644 src/api/API.cpp create mode 100644 src/api/CMakeLists.txt create mode 100644 src/api/SimulationObserver.cpp create mode 100644 src/api/SimulationResults.cpp create mode 100644 src/api/include/antares/api/SimulationResults.h create mode 100644 src/api/include/antares/api/solver.h create mode 100644 src/api/private/API.h create mode 100644 src/api/private/SimulationObserver.h create mode 100644 src/api/solver.cpp create mode 100644 src/api_client_example/CMakeLists.txt create mode 100644 src/api_client_example/README.md create mode 100644 src/api_client_example/src/API_client.cpp create mode 100644 src/api_client_example/src/API_client.h create mode 100644 src/api_client_example/src/CMakeLists.txt create mode 100644 src/api_client_example/tests/CMakeLists.txt create mode 100644 src/api_client_example/tests/test.cpp create mode 100644 src/solver/lps/CMakeLists.txt create mode 100644 src/solver/lps/LpsFromAntares.cpp create mode 100644 src/solver/lps/include/antares/solver/lps/LpsFromAntares.h delete mode 100644 src/solver/main/economy.cpp create mode 100644 src/solver/optimisation/HebdoProblemToLpsTranslator.cpp create mode 100644 src/solver/optimisation/include/antares/solver/optimisation/HebdoProblemToLpsTranslator.h create mode 100644 src/solver/simulation/include/antares/solver/simulation/ISimulationObserver.h delete mode 100644 src/tests/end-to-end/utils/CMakeLists.txt create mode 100644 src/tests/inmemory-study/CMakeLists.txt rename src/tests/{end-to-end/utils/utils.cpp => inmemory-study/in-memory-study.cpp} (88%) rename src/tests/{end-to-end/utils/utils.h => inmemory-study/include/in-memory-study.h} (86%) create mode 100644 src/tests/src/api_internal/CMakeLists.txt create mode 100644 src/tests/src/api_internal/test_api.cpp create mode 100644 src/tests/src/api_lib/CMakeLists.txt create mode 100644 src/tests/src/api_lib/test_api.cpp create mode 100644 src/tests/src/solver/lps/CMakeLists.txt create mode 100644 src/tests/src/solver/lps/test_lps.cpp create mode 100644 src/tests/src/solver/optimisation/adequacy_patch/CMakeLists.txt rename src/tests/src/solver/optimisation/{ => adequacy_patch}/adequacy_patch.cpp (100%) create mode 100644 src/tests/src/solver/optimisation/translator/CMakeLists.txt create mode 100644 src/tests/src/solver/optimisation/translator/test_translator.cpp diff --git a/.github/workflows/install-cmake-328/action.yml b/.github/workflows/install-cmake-328/action.yml index a6f111746c..1cf045dbee 100644 --- a/.github/workflows/install-cmake-328/action.yml +++ b/.github/workflows/install-cmake-328/action.yml @@ -1,4 +1,4 @@ -name: "Install cmake 3.28 using devtoolset 10" +name: "Install cmake 3.28 using devtoolset 10 if possible" description: "Download and install system wide cmake 3.28" runs: @@ -7,7 +7,7 @@ runs: - name: Build cmake shell: bash run: | - source /opt/rh/devtoolset-10/enable + source /opt/rh/devtoolset-10/enable || true # Ignore error if devtoolset-10 is not available yum -y install openssl-devel wget https://github.com/Kitware/CMake/releases/download/v3.28.2/cmake-3.28.2.tar.gz tar -xvf cmake-3.28.2.tar.gz diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 85713eeb70..88fc65ceac 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -29,7 +29,6 @@ env: RUN_EXTENDED_TESTS: ${{ github.event_name == 'schedule' || inputs.run-tests == 'true' }} REF: ${{ inputs.target_branch =='' && github.ref || inputs.target_branch}} VCPKG_ROOT: ${{ github.workspace }}/vcpkg - vcpkgPackages: yaml-cpp antlr4 boost-test triplet: x64-linux WX_CONFIG: /usr/bin/wx-config @@ -115,6 +114,24 @@ jobs: run: | cmake --build _build -j$(nproc) + - name: Run API tests + run: | + cmake --install _build --prefix antares_install + cd src/api_client_example + cmake -B _build -S . \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_C_COMPILER=/usr/bin/gcc-10 \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=x64-linux-release \ + -DCMAKE_PREFIX_PATH="${{github.workspace}}/rte-antares-deps-Release;${{github.workspace}}/install;${{ env.ORTOOLS_DIR }}/install;${{github.workspace}}/antares_install;${{github.workspace}}/rte-antares-deps-Release;${{github.workspace}}/_build/vcpkg_installed/x64-linux-release" + cmake --build _build -j$(nproc) + cd _build + ctest -C Release --output-on-failure + # simtest - name: Read simtest version id: simtest-version diff --git a/docs/Architecture_Decision_Records/Expose_cpp_API.md b/docs/Architecture_Decision_Records/Expose_cpp_API.md index bae68cd5b4..fcc11c8a93 100644 --- a/docs/Architecture_Decision_Records/Expose_cpp_API.md +++ b/docs/Architecture_Decision_Records/Expose_cpp_API.md @@ -4,11 +4,11 @@ ## Context -Some clients (e.g. Xpansion) would prefer to use a library than a CLI tool. Exposing a library require exposing a public API. -The API can be exposed either as pure C or as C++. -A C API can always be developped as a facade on top of a C++ API. -C++ API will not have to care about ABI compatibility because Simulator lib will be provided as static, meaning a client -upgrading would need to be recompiled and relink with the new lib version. +Several clients, such as Xpansion, express a preference for utilizing a library over a command-line interface (CLI) tool. Exposing a library necessitates the exposure of a public API. + +This API can be presented in either pure C or C++. It's worth noting that a C API can always serve as a facade atop a C++ API. + +In the case of a C++ API, concerns regarding ABI compatibility are alleviated, as the Simulator library is provided in a static form. Consequently, when a client upgrades, they would simply need to recompile and relink with the new version of the library. ## Decision diff --git a/docs/Architecture_Decision_Records/separate_install_exe_api.md b/docs/Architecture_Decision_Records/separate_install_exe_api.md new file mode 100644 index 0000000000..3a9662ec1d --- /dev/null +++ b/docs/Architecture_Decision_Records/separate_install_exe_api.md @@ -0,0 +1,25 @@ +# Expose public C++ API + +## Status: Rejected [2024/04/11] + +## Context + +Originally, there exists a single install target designated to deploy the diverse Antares executables, predominantly packaged within the release assets. However, there's a rationale behind avoiding the creation of a unified package containing both executables and libraries, given that they cater to distinct user demographics. This mirrors the flexibility offered by package managers such as apt, where users can opt to install binary packages and separate development (devel) packages according to their requirements. + +## Decision + +Split installation into two targets + +Produce different assets/packages for each install targets. + + +## Consequences + +* Mutltiplication of assets +* Two install targets to manage +* Users of executable not "polluted" by libraries + +## Reason for rejection + +The decision was rejected because it was deemed unnecessary to split the installation targets. It adds +some difficulties for few benefits at the moment \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 862c7fdbc8..44715f0650 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -233,7 +233,7 @@ message(STATUS "OR-Tools tag ${ORTOOLS_TAG}") FetchContent_MakeAvailable(ortools) endif() -find_package(minizip-ng) +find_package(minizip-ng QUIET) if (minizip-ng_FOUND) add_library(MINIZIP::minizip ALIAS MINIZIP::minizip-ng) else () @@ -267,6 +267,7 @@ add_subdirectory("ext/yuni/src") OMESSAGE("") # empty line # Sub Directories +add_subdirectory(api) add_subdirectory(libs) #antares-core fswalker if(BUILD_UI) diff --git a/src/api/API.cpp b/src/api/API.cpp new file mode 100644 index 0000000000..38e9778eab --- /dev/null +++ b/src/api/API.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include "API.h" +#include "antares/solver/simulation/economy_mode.h" +#include "antares/solver/simulation/adequacy_mode.h" +#include "antares/solver/misc/options.h" +#include "antares/infoCollection/StudyInfoCollector.h" +#include "antares/benchmarking/DurationCollector.h" +#include "antares/exception/LoadingError.hpp" +#include +#include + +namespace Antares::API +{ +SimulationResults APIInternal::run(const IStudyLoader& study_loader) +{ + try { + study_ = study_loader.load(); + } catch (const ::Antares::Error::StudyFolderDoesNotExist& e) { + Antares::API::Error err{.reason = e.what()}; + return { + .simulationPath = "", + .antares_problems = {}, + .error = err + }; + } + return execute(); +} + +/** + * @brief The execute method is used to execute the simulation. + * @return SimulationResults object which contains the results of the simulation. + * + * This method is initialy a copy of Application::execute with some modifications hence the apparent dupllication + */ +SimulationResults APIInternal::execute() const +{ + // study_ == nullptr e.g when the -h flag is given + if (!study_) + { + using namespace std::string_literals; + Antares::API::Error err{.reason = "Couldn't create study"s}; + return {.simulationPath{}, .antares_problems{}, .error = err}; + } + + study_->computePThetaInfForThermalClusters(); + + // Only those two fields are used un simulation + Settings settings; + settings.tsGeneratorsOnly = false; + settings.noOutput = false; + + Benchmarking::DurationCollector durationCollector; + Benchmarking::OptimizationInfo optimizationInfo; + auto ioQueueService = std::make_shared(); + ioQueueService->maximumThreadCount(1); + ioQueueService->start(); + auto resultWriter = Solver::resultWriterFactory( + study_->parameters.resultFormat, study_->folderOutput, ioQueueService, durationCollector); + SimulationObserver simulationObserver; + // Run the simulation + switch (study_->runtime->mode) + { + case Data::SimulationMode::Economy: + case Data::SimulationMode::Expansion: + Solver::runSimulationInEconomicMode(*study_, + settings, + durationCollector, + *resultWriter, + optimizationInfo, + simulationObserver); + break; + case Data::SimulationMode::Adequacy: + Solver::runSimulationInAdequacyMode(*study_, + settings, + durationCollector, + *resultWriter, + optimizationInfo, + simulationObserver); + break; + default: + break; + } + + // Importing Time-Series if asked + study_->importTimeseriesIntoInput(); + + // Stop the display of the progression + study_->progression.stop(); + return + { + .simulationPath = study_->folderOutput.c_str(), + .antares_problems = simulationObserver.acquireLps(), + .error{} + }; +} +} // namespace Antares::API \ No newline at end of file diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt new file mode 100644 index 0000000000..109c640578 --- /dev/null +++ b/src/api/CMakeLists.txt @@ -0,0 +1,42 @@ +add_library(solver_api) +add_library(Antares::solver_api ALIAS solver_api) + +set(PUBLIC_HEADERS + include/antares/api/SimulationResults.h + include/antares/api/solver.h +) + +set(PRIVATE_HEADERS + private/API.h + private/SimulationObserver.h +) + +target_sources(solver_api + PRIVATE + solver.cpp + API.cpp + SimulationObserver.cpp + SimulationResults.cpp + ${PUBLIC_HEADERS} + ${PRIVATE_HEADERS} +) + +target_include_directories(solver_api + PUBLIC + $ + PRIVATE + $ +) + +target_link_libraries(solver_api + PRIVATE + Antares::study + Antares::study-loader + Antares::file-tree-study-loader + antares-solver-simulation + PUBLIC + Antares::lps +) +install(DIRECTORY include/antares + DESTINATION "include" +) \ No newline at end of file diff --git a/src/api/SimulationObserver.cpp b/src/api/SimulationObserver.cpp new file mode 100644 index 0000000000..7842ce8099 --- /dev/null +++ b/src/api/SimulationObserver.cpp @@ -0,0 +1,73 @@ + +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include "SimulationObserver.h" + +#include "antares/solver/optimisation/HebdoProblemToLpsTranslator.h" + +namespace Antares::API +{ +namespace +{ +auto translate(const PROBLEME_HEBDO& problemeHebdo, + std::string_view name, + const Solver::HebdoProblemToLpsTranslator& translator, + const unsigned int year, + const unsigned int week) +{ + auto weekly_data = translator.translate(problemeHebdo.ProblemeAResoudre.get(), name); + Solver::ConstantDataFromAntares common_data; + if (year == 1 && week == 1) + { + common_data = translator.commonProblemData(problemeHebdo.ProblemeAResoudre.get()); + } + return std::make_pair(common_data, weekly_data); +} +} // namespace + +void SimulationObserver::notifyHebdoProblem(const PROBLEME_HEBDO& problemeHebdo, + int optimizationNumber, + std::string_view name) +{ + if (optimizationNumber != 1) + { + return; // We only care about first optimization + } + Solver::HebdoProblemToLpsTranslator translator; + const unsigned int year = problemeHebdo.year + 1; + const unsigned int week = problemeHebdo.weekInTheYear + 1; + // common_data and weekly_data computed before the mutex lock to prevent blocking the thread + auto [common_data, weekly_data] = translate(problemeHebdo, name, translator, year, week); + std::lock_guard lock(mutex_); + if (year == 1 && week == 1) + { + lps_.setConstantData(common_data); + } + lps_.addWeeklyData({year, week}, weekly_data); +} + +Solver::LpsFromAntares&& SimulationObserver::acquireLps() noexcept +{ + std::lock_guard lock(mutex_); + return std::move(lps_); +} +} // namespace Antares::API diff --git a/src/api/SimulationResults.cpp b/src/api/SimulationResults.cpp new file mode 100644 index 0000000000..63c5127a49 --- /dev/null +++ b/src/api/SimulationResults.cpp @@ -0,0 +1,22 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include "antares/api/SimulationResults.h" diff --git a/src/api/include/antares/api/SimulationResults.h b/src/api/include/antares/api/SimulationResults.h new file mode 100644 index 0000000000..5a5e93982a --- /dev/null +++ b/src/api/include/antares/api/SimulationResults.h @@ -0,0 +1,62 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once +#include +#include +#include +#include "antares/solver/lps/LpsFromAntares.h" + +namespace Antares::API +{ +/** + * @struct Error + * @brief The Error structure is used to represent an error that occurred during the simulation. + */ +struct Error { + /** + * @brief The reason for the error. + */ + std::string reason; +}; + +/** + * @struct SimulationResults + * @brief The SimulationResults structure is used to represent the results of a simulation. + * @details It contains the path to the simulation, weekly problems, and an optional error. + */ +struct [[nodiscard("Contains results and potential error")]] SimulationResults +{ + /** + * @brief The path to the simulation (output). + */ + std::filesystem::path simulationPath; + /** + * @brief weekly problems + */ + Antares::Solver::LpsFromAntares antares_problems; + /** + * @brief An optional error that occurred during the simulation. + */ + std::optional error; +}; + +} \ No newline at end of file diff --git a/src/api/include/antares/api/solver.h b/src/api/include/antares/api/solver.h new file mode 100644 index 0000000000..d016a9a08a --- /dev/null +++ b/src/api/include/antares/api/solver.h @@ -0,0 +1,35 @@ + +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once +#include "SimulationResults.h" + +namespace Antares::API +{ +/** + * @brief The PerformSimulation function is used to perform a simulation. + * @param study_path The path to the study to be simulated. + * @return SimulationResults object which contains the results of the simulation. + * @exception noexcept This function does not throw exceptions. + */ +SimulationResults PerformSimulation(const std::filesystem::path& study_path) noexcept; +} // namespace Antares::API diff --git a/src/api/private/API.h b/src/api/private/API.h new file mode 100644 index 0000000000..91f8a4e2d3 --- /dev/null +++ b/src/api/private/API.h @@ -0,0 +1,56 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once +#include + +#include +#include "antares/api/SimulationResults.h" + +namespace Antares::Data +{ +class Study; +} + +namespace Antares::API +{ + +/** + * @class APIInternal + * @brief The APIInternal class is used to run simulations. + */ +class APIInternal +{ +public: + /** + * @brief The run method is used to run the simulation. + * @param study_loader A pointer to an IStudyLoader object. The IStudyLoader object is used to + * load the study that will be simulated. + * @return SimulationResults object which contains the results of the simulation. + */ + SimulationResults run(const IStudyLoader& study_loader); + +private: + std::shared_ptr study_; + SimulationResults execute() const; +}; + +} // namespace Antares::API diff --git a/src/api/private/SimulationObserver.h b/src/api/private/SimulationObserver.h new file mode 100644 index 0000000000..f2d78fc4eb --- /dev/null +++ b/src/api/private/SimulationObserver.h @@ -0,0 +1,61 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once +#include +#include + +namespace Antares::API +{ + +/** + * @class SimulationObserver + * @brief The SimulationObserver class is used to observe the simulation. + * @details It inherits from the ISimulationObserver interface and overrides the notifyHebdoProblem + * method. + */ +class SimulationObserver: public Solver::Simulation::ISimulationObserver +{ +public: + /** + * @brief Used to notify of a solver HEBDO_PROBLEM. + * HEBDO_PROBLEM is assumed to be properly constructed and valid in order to build + * LpsFromAntares properly + * @param problemeHebdo A pointer to a PROBLEME_HEBDO object representing the problem. + * @param optimizationNumber The number of the optimization. + * @param name The name of the problem. + */ + void notifyHebdoProblem(const PROBLEME_HEBDO& problemeHebdo, + int optimizationNumber, + std::string_view name) override; + + /** + * @brief The acquireLps method is used to take ownership of Antares problems. + * @return An LpsFromAntares object containing the linear programming problems. + */ + Solver::LpsFromAntares&& acquireLps() noexcept; + +private: + Solver::LpsFromAntares lps_; + std::mutex mutex_; +}; + +} // namespace Antares::API diff --git a/src/api/solver.cpp b/src/api/solver.cpp new file mode 100644 index 0000000000..6e2f7068ea --- /dev/null +++ b/src/api/solver.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include +#include "antares/file-tree-study-loader/FileTreeStudyLoader.h" +#include "antares/study-loader/IStudyLoader.h" + +#include "private/API.h" + +namespace Antares::API +{ + +SimulationResults PerformSimulation(const std::filesystem::path& study_path) noexcept +{ + try + { + APIInternal api; + FileTreeStudyLoader study_loader(study_path); + return api.run(study_loader); + } + catch (const std::exception& e) + { + Antares::API::Error err{.reason = e.what()}; + return SimulationResults{.simulationPath = study_path, .antares_problems{}, .error = err}; + } +} + +} // namespace Antares::API diff --git a/src/api_client_example/CMakeLists.txt b/src/api_client_example/CMakeLists.txt new file mode 100644 index 0000000000..570ee9341b --- /dev/null +++ b/src/api_client_example/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.5) + +PROJECT(API_client) + +set(CMAKE_CXX_STANDARD 20) + +add_subdirectory(src) + +include(CTest) +if (BUILD_TESTING) + add_subdirectory(tests) +endif () \ No newline at end of file diff --git a/src/api_client_example/README.md b/src/api_client_example/README.md new file mode 100644 index 0000000000..151b1d346b --- /dev/null +++ b/src/api_client_example/README.md @@ -0,0 +1,3 @@ +Client for antares solver API + +To demonstrate as much capabilities as possible this client should stay stand alone this mean not added as a sub_directory for cmake diff --git a/src/api_client_example/src/API_client.cpp b/src/api_client_example/src/API_client.cpp new file mode 100644 index 0000000000..6489806c51 --- /dev/null +++ b/src/api_client_example/src/API_client.cpp @@ -0,0 +1,30 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + + +#include "API_client.h" + +#include + +Antares::API::SimulationResults solve(std::filesystem::path study_path) { + return Antares::API::PerformSimulation(std::move(study_path)); +} + diff --git a/src/api_client_example/src/API_client.h b/src/api_client_example/src/API_client.h new file mode 100644 index 0000000000..5d8500649e --- /dev/null +++ b/src/api_client_example/src/API_client.h @@ -0,0 +1,28 @@ + +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include +#include + +Antares::API::SimulationResults solve(std::filesystem::path study_path); diff --git a/src/api_client_example/src/CMakeLists.txt b/src/api_client_example/src/CMakeLists.txt new file mode 100644 index 0000000000..55ebb33579 --- /dev/null +++ b/src/api_client_example/src/CMakeLists.txt @@ -0,0 +1,14 @@ +add_library(API_client) + +target_sources(API_client + PRIVATE + API_client.cpp + API_client.h +) + +find_package(Antares REQUIRED) +target_link_libraries(API_client PUBLIC Antares::solver_api) +target_include_directories(API_client + PUBLIC + $ +) \ No newline at end of file diff --git a/src/api_client_example/tests/CMakeLists.txt b/src/api_client_example/tests/CMakeLists.txt new file mode 100644 index 0000000000..1fc9c3cc89 --- /dev/null +++ b/src/api_client_example/tests/CMakeLists.txt @@ -0,0 +1,17 @@ +find_package(Boost COMPONENTS unit_test_framework REQUIRED) + +add_executable(test_client) + +target_sources(test_client + PRIVATE + test.cpp +) + +target_link_libraries(test_client + PRIVATE + API_client + Boost::unit_test_framework +) + +add_test(NAME testclient COMMAND test_client) +set_property(TEST testclient PROPERTY LABELS integ) \ No newline at end of file diff --git a/src/api_client_example/tests/test.cpp b/src/api_client_example/tests/test.cpp new file mode 100644 index 0000000000..4adee7bfd6 --- /dev/null +++ b/src/api_client_example/tests/test.cpp @@ -0,0 +1,37 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define BOOST_TEST_MODULE test_client_api + +#include +#include "API_client.h" + +BOOST_AUTO_TEST_CASE(test_run) { + auto results = solve("dummy_study_test_client_api"); + BOOST_CHECK(results.error); + BOOST_CHECK(!results.error->reason.empty()); + auto c = results.error->reason; + std::cout << c << std::endl; + BOOST_CHECK(results.error->reason.find("Study") != std::string::npos); + BOOST_CHECK(results.error->reason.find("folder") != std::string::npos); + BOOST_CHECK(results.error->reason.find("not") != std::string::npos); + BOOST_CHECK(results.error->reason.find("exist") != std::string::npos); +} \ No newline at end of file diff --git a/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp b/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp index 5302c19263..8ff1c2730d 100644 --- a/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp +++ b/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp @@ -49,15 +49,10 @@ namespace * @param study_path A string_view representing the study path. * @return std::vector A vector of strings containing the prepared arguments. */ -[[nodiscard]] std::vector prepareArgs(std::span argv, - std::string_view study_path) +void prepareArgs(std::array& argv, std::span data) { - using namespace std::literals::string_literals; - std::string arg0{""s}; - std::string arg1{study_path}; - argv[0] = arg0.data(); - argv[1] = arg1.data(); - return {std::move(arg0), std::move(arg1)}; + argv[0] = data[0].data(); + argv[1] = data[1].data(); } } // namespace @@ -66,8 +61,9 @@ std::unique_ptr FileTreeStudyLoader::load() const using namespace std::literals::string_literals; Antares::Solver::Application application; constexpr unsigned int argc = 2; + std::array keep_alive{""s, study_path_.string()}; std::array argv; - auto keep_alive = prepareArgs(argv, study_path_.string()); + prepareArgs(argv, keep_alive); application.prepare(argc, argv.data()); return application.acquireStudy(); diff --git a/src/libs/antares/inifile/CMakeLists.txt b/src/libs/antares/inifile/CMakeLists.txt index a68b3f2786..089591f002 100644 --- a/src/libs/antares/inifile/CMakeLists.txt +++ b/src/libs/antares/inifile/CMakeLists.txt @@ -17,11 +17,11 @@ target_link_libraries(inifile PRIVATE io logs - Boost::boost + Boost::headers ) target_include_directories(inifile - PUBLIC + PUBLIC $ ) diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index c90d543fff..65ad5398a6 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -285,7 +285,6 @@ add_library(Antares::study ALIAS study) target_link_libraries(study PUBLIC - Boost::boost yuni-static-core Antares::date #parameters Antares::inifile #parameters diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/cluster.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/cluster.h index afe2e1976f..cc9af74015 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/cluster.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/cluster.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #pragma once #include diff --git a/src/packaging/CMakeLists.txt b/src/packaging/CMakeLists.txt index 6d68ec5e38..868cd7a8ec 100644 --- a/src/packaging/CMakeLists.txt +++ b/src/packaging/CMakeLists.txt @@ -10,6 +10,8 @@ set(TARGET_LIBS #No alias #not dependency is present since once a dependency is in the export set #it is available for everything + solver_api #What we want to export + #solver_api study study-loader @@ -33,6 +35,7 @@ set(TARGET_LIBS #No alias exception benchmarking antares-solver-variable + lps #study-loader #nothing diff --git a/src/packaging/Config.cmake.in b/src/packaging/Config.cmake.in index 2cbf63a275..c9bcb039e1 100644 --- a/src/packaging/Config.cmake.in +++ b/src/packaging/Config.cmake.in @@ -1,8 +1,8 @@ @PACKAGE_INIT@ include(CMakeFindDependencyMacro) -find_dependency(ortools REQUIRED) -find_dependency(minizip-ng) +find_dependency(Boost REQUIRED) +find_package(minizip-ng QUIET) #Optional, don't use find_dependency it forces return in case of dep not found if (minizip-ng_FOUND) add_library(MINIZIP::minizip ALIAS MINIZIP::minizip-ng) else () @@ -11,6 +11,8 @@ else () message (FATAL_ERROR "Minizip dependency (minizip or minizip-ng) not found.") endif () endif () +find_dependency(ortools REQUIRED) +find_dependency(sirius_solver REQUIRED) include("${CMAKE_CURRENT_LIST_DIR}/AntaresTargets.cmake") diff --git a/src/solver/CMakeLists.txt b/src/solver/CMakeLists.txt index aeb17fb3a0..13ab3bfa6c 100644 --- a/src/solver/CMakeLists.txt +++ b/src/solver/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory(application) add_subdirectory(constraints-builder) add_subdirectory(hydro) add_subdirectory(infeasible-problem-analysis) +add_subdirectory(lps) add_subdirectory(misc) add_subdirectory(optimisation) add_subdirectory(signal-handling) diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index d222ad88c0..90d5e559c5 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -34,7 +34,6 @@ #include #include "antares/antares/version.h" #include "antares/config/config.h" -#include "antares/file-tree-study-loader/FileTreeStudyLoader.h" #include "antares/signal-handling/public.h" #include "antares/solver/misc/system-memory.h" #include "antares/solver/misc/write-command-line.h" @@ -410,20 +409,24 @@ void Application::execute() void Application::runSimulationInEconomicMode() { + Simulation::NullSimulationObserver observer; Solver::runSimulationInEconomicMode(*pStudy, pSettings, pDurationCollector, *resultWriter, - pOptimizationInfo); + pOptimizationInfo, + observer); } void Application::runSimulationInAdequacyMode() { + Simulation::NullSimulationObserver observer; Solver::runSimulationInAdequacyMode(*pStudy, pSettings, pDurationCollector, *resultWriter, - pOptimizationInfo); + pOptimizationInfo, + observer); } static std::string timeToString() diff --git a/src/solver/lps/CMakeLists.txt b/src/solver/lps/CMakeLists.txt new file mode 100644 index 0000000000..8c3e48cab0 --- /dev/null +++ b/src/solver/lps/CMakeLists.txt @@ -0,0 +1,24 @@ +set(PROJ lps) +set(HEADERS + include/antares/solver/lps/LpsFromAntares.h +) +set(SRC_PROJ + ${HEADERS} + LpsFromAntares.cpp +) +source_group("solver\\lps" FILES ${SRC_PROJ}) + +add_library(${PROJ}) +target_sources(${PROJ} PRIVATE + ${SRC_PROJ} +) +add_library(Antares::${PROJ} ALIAS ${PROJ}) + +target_include_directories(${PROJ} + PUBLIC + $ +) + +install(DIRECTORY include/antares + DESTINATION "include" +) \ No newline at end of file diff --git a/src/solver/lps/LpsFromAntares.cpp b/src/solver/lps/LpsFromAntares.cpp new file mode 100644 index 0000000000..a32484038d --- /dev/null +++ b/src/solver/lps/LpsFromAntares.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include "antares/solver/lps/LpsFromAntares.h" + +namespace Antares::Solver +{ +bool LpsFromAntares::empty() const +{ + return constantProblemData.VariablesCount == 0 || weeklyProblems.empty(); +} + +void LpsFromAntares::setConstantData(const ConstantDataFromAntares& data) +{ + constantProblemData = data; +} + +void LpsFromAntares::addWeeklyData(WeeklyProblemId id, const WeeklyDataFromAntares& data) +{ + weeklyProblems.emplace(id, data); +} + +const WeeklyDataFromAntares& LpsFromAntares::weeklyData(WeeklyProblemId id) const +{ + auto it = weeklyProblems.find(id); + if (it == weeklyProblems.end()) + { + return WeeklyDataFromAntares(); // TODO Better error handling + } + return it->second; +} + +size_t LpsFromAntares::weekCount() const noexcept +{ + return weeklyProblems.size(); +} + +} // namespace Antares::Solver diff --git a/src/solver/lps/include/antares/solver/lps/LpsFromAntares.h b/src/solver/lps/include/antares/solver/lps/LpsFromAntares.h new file mode 100644 index 0000000000..f85d99b060 --- /dev/null +++ b/src/solver/lps/include/antares/solver/lps/LpsFromAntares.h @@ -0,0 +1,149 @@ + +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once +#include +#include +#include +#include +#include + +namespace Antares::Solver +{ + +/** + * @struct WeeklyProblemId + * @brief The WeeklyProblemId struct is used to identify a weekly problem by year and week. + */ +struct WeeklyProblemId +{ + unsigned int year = 0; + unsigned int week = 0; + // Order of comparison is order of member declaration + auto operator<=>(const WeeklyProblemId& other) const = default; +}; + +// Type de données inutile car les matrices de tous les pbs Weekly sont +// identiques. Cela pourra changer à l'avenir si des coefficients de contraintes +// couplantes peuvent varier au cours du temps (ex: rendement d'une pompe à +// chaleur qui varie selon la température, FlowBased ?, etc) +/** + * @class ConstantDataFromAntares + * @brief The ConstantDataFromAntares class is used to store constant data across all weeks + * of Antares problems. + */ +struct ConstantDataFromAntares +{ + unsigned VariablesCount = 0; // Mathématiquement : Nb colonnes de la matrice, + // Informatiquement = TypeDeVariable.size() + unsigned ConstraintesCount = 0; // Mathématiqument : Nb lignes de la matrice, + // Informatiquement = Mdeb.size() + unsigned CoeffCount = 0; // Mathématiquement : Nb coeffs non nuls de la + // matrice, Informatiquement = Nbterm.size() = + // IndicesColonnes.size()= + // CoefficientsDeLaMatriceDesContraintes.size() + + std::vector VariablesType; // Variables entières ou biniaires + std::vector Mdeb; // Indique dans les indices dans le vecteur IndicesColonnes qui + // correspondent au début de chaque ligne. Ex : Mdeb[3] = 8 et + // Mdeb[4] = 13 -> Les termes IndicesColonnes[8] à + // IndicesColonnes[12] correspondent à des Id de colonnes de la + // ligne 3 de la matrice (en supposant que les lignes sont indexées + // à partir de 0) + std::vector NotNullTermCount; // Nombre de termes non nuls sur chaque ligne. + // Inutile car NbTerm[i] = Mdeb[i+1] - Mdeb[i] + std::vector ColumnIndexes; // Id des colonnes des termes de + // CoefficientsDeLaMatriceDesContraintes : Ex + // IndicesColonnes[3] = 8 -> + // CoefficientsDeLaMatriceDesContraintes[8] donne la + // valeur du terme de la colonne 8, et de la ligne i où + // i est tel que Mdeb[i] <= 3 < Mdeb[i+1] + std::vector ConstraintsMatrixCoeff; // Coefficients de la matrice + + std::vector VariablesMeaning; + std::vector ConstraintsMeaning; + + auto operator<=>(const ConstantDataFromAntares& other) const = default; +}; + +/** + * @class WeeklyDataFromAntares + * @brief The WeeklyDataFromAntares class is used to store weekly data for an Antares Problem. + */ +struct WeeklyDataFromAntares +{ + std::vector Direction; // Sens de la contrainte : < ou > ou =, taille = + // NombreDeContraintes + std::vector Xmax; // Borne max des variables de la semaine + // considérée, taille = NombreDeVariables + std::vector Xmin; // Borne min des variables de la semaine + // considérée, taille = NombreDeVariables + std::vector LinearCost; // Coefficients du vecteur de coût de la fonction objectif, + // taille = NombreDeVariables + std::vector RHS; // Vecteur des second membre des contraintes, taille = + // NombreDeContraintes + std::string name; + + std::vector variables; + std::vector constraints; + + auto operator<=>(const WeeklyDataFromAntares& other) const = default; +}; + +using WeeklyDataByYearWeek = std::map; + +/** + * @class LpsFromAntares + * @brief The LpsFromAntares class is used to manage the constant and weekly data for Antares + * problems. + */ +class LpsFromAntares +{ +public: + /* + * @brief Checks if the LpsFromAntares object is empty. + * Emptiness is defined by either the constant data or the weekly data being empty. + */ + bool empty() const; + /* + * @brief Replaces the constant data in the LpsFromAntares object. + * Copy happens + */ + void setConstantData(const ConstantDataFromAntares& data); + /* + * @brief Adds weekly data to the LpsFromAntares object. + */ + void addWeeklyData(WeeklyProblemId id, const WeeklyDataFromAntares& data); + /* + * @brief Retrieves weekly data from the LpsFromAntares object. + */ + const WeeklyDataFromAntares& weeklyData(WeeklyProblemId id) const; + /* + * @brief Retrieves the number of weeks in the LpsFromAntares object. + */ + [[nodiscard]] size_t weekCount() const noexcept; + + ConstantDataFromAntares constantProblemData; + WeeklyDataByYearWeek weeklyProblems; +}; + +} // namespace Antares::Solver diff --git a/src/solver/main/economy.cpp b/src/solver/main/economy.cpp deleted file mode 100644 index f4fc8ba907..0000000000 --- a/src/solver/main/economy.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ - -#include "antares/solver/simulation/economy.h" - -#include -#include -#include "antares/application/application.h" -#include "antares/solver/simulation/solver.h" - -namespace Antares::Solver -{ -void Application::runSimulationInEconomicMode() -{ - // Type of the simulation - typedef Solver::Simulation::ISimulation SimulationType; - SimulationType simulation(*pStudy, pSettings, pDurationCollector, *resultWriter); - simulation.checkWriter(); - simulation.run(); - - if (!(pSettings.noOutput || pSettings.tsGeneratorsOnly)) - { - pDurationCollector("synthesis_export") - << [&simulation] { simulation.writeResults(/*synthesis:*/ true); }; - - this->pOptimizationInfo = simulation.getOptimizationInfo(); - } -} -} // namespace Antares::Solver diff --git a/src/solver/misc/options.cpp b/src/solver/misc/options.cpp index 9429b50e79..a09b83e17d 100644 --- a/src/solver/misc/options.cpp +++ b/src/solver/misc/options.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/misc/options.h" @@ -45,7 +45,7 @@ std::unique_ptr CreateParser(Settings& settings, StudyLoad { settings.reset(); - auto parser = std::unique_ptr(new Yuni::GetOpt::Parser()); + auto parser = std::make_unique(); parser->addParagraph(Yuni::String() << "Antares Solver v" << ANTARES_VERSION_PUB_STR << "\n"); diff --git a/src/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt index cbf8f33fc3..a6c6f01e66 100644 --- a/src/solver/optimisation/CMakeLists.txt +++ b/src/solver/optimisation/CMakeLists.txt @@ -172,7 +172,8 @@ set(RTESOLVER_OPT variables/VariableManagement.cpp variables/VariableManagerUtils.h variables/VariableManagerUtils.cpp - + include/antares/solver/optimisation/HebdoProblemToLpsTranslator.h + HebdoProblemToLpsTranslator.cpp ) @@ -196,6 +197,7 @@ target_link_libraries(model_antares antares-solver-simulation Antares::benchmarking Antares::optimization-options + Antares::lps PRIVATE infeasible_problem_analysis ) diff --git a/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp b/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp new file mode 100644 index 0000000000..1109e9c780 --- /dev/null +++ b/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp @@ -0,0 +1,109 @@ + +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include "antares/solver/optimisation/HebdoProblemToLpsTranslator.h" +#include "antares/solver/utils/filename.h" + +namespace Antares::Solver +{ + +namespace +{ +/** + * @brief Copies elements from one container to another. + * + * This function takes two containers as arguments. It copies elements from the first container to the second one. + * + * @param in The container from which to copy elements. + * @param out The container to which to copy elements. + */ +template +void copy(const T& in, U& out) +{ + std::ranges::copy(in, std::back_inserter(out)); +} +} + +WeeklyDataFromAntares HebdoProblemToLpsTranslator::translate( + const PROBLEME_ANTARES_A_RESOUDRE* problem, + std::string_view name) const +{ + if (problem == nullptr) + return {}; + auto ret = WeeklyDataFromAntares(); + + copy(problem->CoutLineaire, ret.LinearCost); + copy(problem->Xmax, ret.Xmax); + copy(problem->Xmin, ret.Xmin); + copy(problem->NomDesVariables, ret.variables); + copy(problem->NomDesContraintes, ret.constraints); + copy(problem->SecondMembre, ret.RHS); + copy(problem->Sens, ret.Direction); + + copy(name, ret.name); + + return ret; +} + +ConstantDataFromAntares HebdoProblemToLpsTranslator::commonProblemData(const PROBLEME_ANTARES_A_RESOUDRE* problem) const { + if (problem == nullptr) + return ConstantDataFromAntares(); + + if (problem->NombreDeVariables <= 0) { + throw WeeklyProblemTranslationException("VariablesCount must be strictly positive"); + } + if (problem->NombreDeContraintes <= 0) { + throw WeeklyProblemTranslationException("ConstraintesCount must be strictly positive"); + } + + if (problem->NombreDeContraintes > problem->IndicesDebutDeLigne.size()) { + throw WeeklyProblemTranslationException("ConstraintesCount exceed IndicesDebutDeLigne size"); + } + + if (problem->NombreDeContraintes > problem->NombreDeTermesDesLignes.size()) { + throw WeeklyProblemTranslationException("ConstraintesCount exceed NombreDeTermesDesLignes size"); + } + + ConstantDataFromAntares ret; + + ret.VariablesCount = problem->NombreDeVariables; + ret.ConstraintesCount = problem->NombreDeContraintes; + + ret.CoeffCount = problem->IndicesDebutDeLigne[problem->NombreDeContraintes - 1] + + problem->NombreDeTermesDesLignes[problem->NombreDeContraintes - 1]; + + copy(problem->TypeDeVariable, ret.VariablesType); + + copy(problem->CoefficientsDeLaMatriceDesContraintes, + ret.ConstraintsMatrixCoeff); + copy(problem->IndicesColonnes, ret.ColumnIndexes); + + copy(problem->IndicesDebutDeLigne, ret.Mdeb); + return ret; +} + +WeeklyProblemTranslationException::WeeklyProblemTranslationException( + const std::string& string) noexcept +: std::runtime_error{string} +{ +} +} // namespace Antares::Solver \ No newline at end of file diff --git a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp index 577cfa55b7..174d32564d 100644 --- a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp +++ b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp @@ -1,28 +1,29 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h" #include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/simulation/adequacy_patch_runtime_data.h" +#include "antares/solver/simulation/ISimulationObserver.h" #include "antares/study/fwd.h" using namespace Antares::Data::AdequacyPatch; @@ -35,16 +36,18 @@ AdequacyPatchOptimization::AdequacyPatchOptimization(const Antares::Data::Study& PROBLEME_HEBDO* problemeHebdo, AdqPatchParams& adqPatchParams, uint thread_number, - IResultWriter& writer): - WeeklyOptimization(options, problemeHebdo, adqPatchParams, thread_number, writer), + IResultWriter& writer, + Simulation::ISimulationObserver& observer): + WeeklyOptimization(options, problemeHebdo, adqPatchParams, thread_number, writer, observer), study_(study) { } void AdequacyPatchOptimization::solve() { + Simulation::NullSimulationObserver nullSimulationObserver; problemeHebdo_->adequacyPatchRuntimeData->AdequacyFirstStep = true; - OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_); + OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_, nullSimulationObserver); problemeHebdo_->adequacyPatchRuntimeData->AdequacyFirstStep = false; for (uint32_t pays = 0; pays < problemeHebdo_->NombreDePays; ++pays) @@ -61,7 +64,7 @@ void AdequacyPatchOptimization::solve() } } - OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_); + OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_, nullSimulationObserver); } } // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/base_weekly_optimization.cpp b/src/solver/optimisation/base_weekly_optimization.cpp index d4da2a1167..80efece4b9 100644 --- a/src/solver/optimisation/base_weekly_optimization.cpp +++ b/src/solver/optimisation/base_weekly_optimization.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/optimisation/base_weekly_optimization.h" @@ -34,12 +34,15 @@ WeeklyOptimization::WeeklyOptimization(const OptimizationOptions& options, PROBLEME_HEBDO* problemesHebdo, AdqPatchParams& adqPatchParams, uint thread_number, - IResultWriter& writer): + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver + ) : options_(options), problemeHebdo_(problemesHebdo), adqPatchParams_(adqPatchParams), thread_number_(thread_number), - writer_(writer) + writer_(writer), + simulationObserver_(simulationObserver) { } @@ -48,7 +51,9 @@ std::unique_ptr WeeklyOptimization::create(const Antares::Da AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemeHebdo, uint thread_number, - IResultWriter& writer) + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver + ) { if (adqPatchParams.enabled && adqPatchParams.localMatching.enabled) { @@ -57,7 +62,8 @@ std::unique_ptr WeeklyOptimization::create(const Antares::Da problemeHebdo, adqPatchParams, thread_number, - writer); + writer, + simulationObserver); } else { @@ -65,7 +71,8 @@ std::unique_ptr WeeklyOptimization::create(const Antares::Da problemeHebdo, adqPatchParams, thread_number, - writer); + writer, + simulationObserver); } } diff --git a/src/solver/optimisation/include/antares/solver/optimisation/HebdoProblemToLpsTranslator.h b/src/solver/optimisation/include/antares/solver/optimisation/HebdoProblemToLpsTranslator.h new file mode 100644 index 0000000000..7deb23a0ca --- /dev/null +++ b/src/solver/optimisation/include/antares/solver/optimisation/HebdoProblemToLpsTranslator.h @@ -0,0 +1,81 @@ + +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include "antares/solver/lps/LpsFromAntares.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" + +namespace Antares::Solver +{ + +/** + * @class WeeklyProblemTranslationException + * @brief Exception class for errors during the translation of a weekly problem. + * + * This class is a custom exception class that is thrown when an error occurs during the translation + * of a weekly problem. + */ +class WeeklyProblemTranslationException: public std::runtime_error +{ +public: + explicit WeeklyProblemTranslationException(const std::string& string) noexcept; +}; + +/** + * @class HebdoProblemToLpsTranslator + * @brief Class for translating a weekly problem to a linear programming problem. + * + * This class is responsible for translating a weekly problem to a linear programming problem. + */ +class HebdoProblemToLpsTranslator +{ +public: + /** + * @brief Translates a weekly problem to a linear programming problem. + * + * This function takes a pointer to a PROBLEME_ANTARES_A_RESOUDRE object and a string_view + * representing the name of the problem. It translates the weekly problem to a linear + * programming problem and returns a WeeklyDataFromAntaresPtr to the translated problem. Datas + * from the PROBLEME_ANTARES_A_RESOUDRE are copied to the WeeklyDataFromAntaresPtr. + * + * @param problem A pointer to the weekly problem to be translated. + * @param name The name of the problem. + * @return WeeklyDataFromAntaresPtr A WeeklyDataFromAntaresPtr to the translated problem. + */ + [[nodiscard]] WeeklyDataFromAntares translate(const PROBLEME_ANTARES_A_RESOUDRE* problem, + std::string_view name) const; + + /** + * @brief Retrieves common problem data, the part common to every weekly problems + * + * This function takes a pointer to a PROBLEME_ANTARES_A_RESOUDRE object and retrieves the + * common problem data. It returns a ConstantDataFromAntaresPtr to the common problem data. + * + * @param problem A pointer to the problem from which to retrieve the common data. + * @return ConstantDataFromAntaresPtr A ConstantDataFromAntaresPtr to the common problem data. + */ + [[nodiscard]] ConstantDataFromAntares commonProblemData( + const PROBLEME_ANTARES_A_RESOUDRE* problem) const; +}; + +} // namespace Antares::Solver diff --git a/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h b/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h index 2585fc8053..b11bdc817a 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h @@ -37,9 +37,10 @@ class AdequacyPatchOptimization: public WeeklyOptimization explicit AdequacyPatchOptimization(const Antares::Data::Study& study, const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, - Antares::Data::AdequacyPatch::AdqPatchParams&, + Data::AdequacyPatch::AdqPatchParams&, uint numSpace, - IResultWriter& writer); + IResultWriter& writer, + Simulation::ISimulationObserver& observer); ~AdequacyPatchOptimization() override = default; void solve() override; diff --git a/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h b/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h index 7f4b755bb5..e25ffca086 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h @@ -1,29 +1,30 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #pragma once #include // for "uint" definition #include +#include "antares/solver/simulation/ISimulationObserver.h" #include "antares/solver/simulation/sim_structure_donnees.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" @@ -40,18 +41,23 @@ class WeeklyOptimization Antares::Data::AdequacyPatch::AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemesHebdo, uint numSpace, - IResultWriter& writer); + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver + ); protected: explicit WeeklyOptimization(const OptimizationOptions& options, PROBLEME_HEBDO* problemesHebdo, Antares::Data::AdequacyPatch::AdqPatchParams&, uint numSpace, - IResultWriter& writer); + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver + ); Antares::Solver::Optimization::OptimizationOptions options_; PROBLEME_HEBDO* const problemeHebdo_ = nullptr; Antares::Data::AdequacyPatch::AdqPatchParams& adqPatchParams_; const uint thread_number_ = 0; IResultWriter& writer_; + std::reference_wrapper simulationObserver_; }; } // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/constraint_builder_utils.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/constraint_builder_utils.h index 9e4981700e..9e940aa200 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/constraint_builder_utils.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/constraint_builder_utils.h @@ -22,6 +22,7 @@ #include #include "ConstraintBuilder.h" +struct PROBLEME_HEBDO; ConstraintBuilderData NewGetConstraintBuilderFromProblemHebdoAndProblemAResoudre( PROBLEME_HEBDO* problemeHebdo, diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_export_structure.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_export_structure.h index 4d69d8711e..47aa3838e1 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_export_structure.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_export_structure.h @@ -1,50 +1,32 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ -#ifndef __EXPORT_STRUCTURE__ -#define __EXPORT_STRUCTURE__ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ +#pragma once -#include -#include #include -#include - -#include #include "antares/antares/Enum.hpp" #include "antares/writer/i_writer.h" - -namespace Antares -{ -namespace Data -{ - -class Study; -} // namespace Data -} // namespace Antares - struct PROBLEME_HEBDO; void OPT_ExportInterco(Antares::Solver::IResultWriter& writer, PROBLEME_HEBDO* problemeHebdo); void OPT_ExportAreaName(Antares::Solver::IResultWriter& writer, const std::vector& areaNames); void OPT_ExportStructures(PROBLEME_HEBDO* problemeHebdo, Antares::Solver::IResultWriter& writer); - -#endif diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h index 1a52f7e331..2150ea991a 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #ifndef __SOLVER_OPTIMISATION_FUNCTIONS_H__ #define __SOLVER_OPTIMISATION_FUNCTIONS_H__ @@ -26,6 +26,7 @@ #include #include "antares/config/config.h" #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" +#include "antares/solver/simulation/ISimulationObserver.h" #include "antares/study/parameters/adq-patch-params.h" #include "adequacy_patch_csr/hourly_csr_problem.h" @@ -34,9 +35,10 @@ using AdqPatchParams = Antares::Data::AdequacyPatch::AdqPatchParams; using OptimizationOptions = Antares::Solver::Optimization::OptimizationOptions; void OPT_OptimisationHebdomadaire(const OptimizationOptions& options, - PROBLEME_HEBDO*, - const AdqPatchParams&, - Antares::Solver::IResultWriter& writer); + PROBLEME_HEBDO* pProblemeHebdo, + const AdqPatchParams& adqPatchParams, + Solver::IResultWriter& writer, + Solver::Simulation::ISimulationObserver& simulationObserver); void OPT_NumeroDeJourDuPasDeTemps(PROBLEME_HEBDO*); void OPT_NumeroDIntervalleOptimiseDuPasDeTemps(PROBLEME_HEBDO*); void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaire(PROBLEME_HEBDO*); @@ -65,9 +67,11 @@ bool ADQ_PATCH_CSR(PROBLEME_ANTARES_A_RESOUDRE&, int year); bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, - PROBLEME_HEBDO*, - const AdqPatchParams&, - Antares::Solver::IResultWriter& writer); + PROBLEME_HEBDO* problemeHebdo, + const AdqPatchParams& adqPatchParams, + Solver::IResultWriter& writer, + Solver::Simulation::ISimulationObserver& simulationObserver + ); void OPT_VerifierPresenceReserveJmoins1(PROBLEME_HEBDO*); bool OPT_PilotageOptimisationQuadratique(PROBLEME_HEBDO*); @@ -85,9 +89,11 @@ bool OPT_AppelDuSimplexe(const OptimizationOptions& options, void OPT_LiberationProblemesSimplexe(const OptimizationOptions& options, const PROBLEME_HEBDO*); bool OPT_OptimisationLineaire(const OptimizationOptions& options, - PROBLEME_HEBDO*, - const AdqPatchParams&, - Antares::Solver::IResultWriter& writer); + PROBLEME_HEBDO* problemeHebdo, + const AdqPatchParams& adqPatchParams, + Solver::IResultWriter& writer, + Solver::Simulation::ISimulationObserver& simulationObserver + ); void OPT_RestaurerLesDonnees(PROBLEME_HEBDO*); /*------------------------------*/ diff --git a/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h b/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h index 1f9ae23137..d0f33adb39 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h @@ -1,27 +1,29 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #pragma once #include "antares/solver/simulation/sim_structure_probleme_economique.h" +#include "antares/solver/simulation/ISimulationObserver.h" + #include "base_weekly_optimization.h" @@ -34,7 +36,9 @@ class DefaultWeeklyOptimization: public WeeklyOptimization PROBLEME_HEBDO* problemeHebdo, Antares::Data::AdequacyPatch::AdqPatchParams&, uint numSpace, - IResultWriter& writer); + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver + ); ~DefaultWeeklyOptimization() override = default; void solve() override; }; diff --git a/src/solver/optimisation/opt_optimisation_hebdo.cpp b/src/solver/optimisation/opt_optimisation_hebdo.cpp index 89c59ec57a..6883089378 100644 --- a/src/solver/optimisation/opt_optimisation_hebdo.cpp +++ b/src/solver/optimisation/opt_optimisation_hebdo.cpp @@ -1,29 +1,30 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include #include #include #include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" +#include "antares/solver/simulation/ISimulationObserver.h" #include "antares/solver/simulation/sim_extern_variables_globales.h" extern "C" @@ -39,11 +40,13 @@ using Antares::Solver::Optimization::OptimizationOptions; void OPT_OptimisationHebdomadaire(const OptimizationOptions& options, PROBLEME_HEBDO* pProblemeHebdo, const AdqPatchParams& adqPatchParams, - Solver::IResultWriter& writer) + Solver::IResultWriter& writer, + Solver::Simulation::ISimulationObserver& simulationObserver) { if (pProblemeHebdo->TypeDOptimisation == OPTIMISATION_LINEAIRE) { - if (!OPT_PilotageOptimisationLineaire(options, pProblemeHebdo, adqPatchParams, writer)) + if (!OPT_PilotageOptimisationLineaire( + options, pProblemeHebdo, adqPatchParams, writer, simulationObserver)) { logs.error() << "Linear optimization failed"; throw UnfeasibleProblemError("Linear optimization failed"); diff --git a/src/solver/optimisation/opt_optimisation_lineaire.cpp b/src/solver/optimisation/opt_optimisation_lineaire.cpp index 67c475e396..d3635ff326 100644 --- a/src/solver/optimisation/opt_optimisation_lineaire.cpp +++ b/src/solver/optimisation/opt_optimisation_lineaire.cpp @@ -1,29 +1,32 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include +#include "antares/solver/lps/LpsFromAntares.h" +#include "antares/solver/optimisation/HebdoProblemToLpsTranslator.h" #include "antares/solver/optimisation/LinearProblemMatrix.h" #include "antares/solver/optimisation/constraints/constraint_builder_utils.h" #include "antares/solver/optimisation/opt_export_structure.h" #include "antares/solver/optimisation/opt_fonctions.h" +#include "antares/solver/simulation/ISimulationObserver.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "antares/solver/utils/filename.h" using namespace Antares; @@ -61,11 +64,27 @@ void OPT_EcrireResultatFonctionObjectiveAuFormatTXT( writer.addEntryFromBuffer(filename, buffer); } +namespace +{ +void notifyProblemHebdo(const PROBLEME_HEBDO* problemeHebdo, + int optimizationNumber, + Solver::Simulation::ISimulationObserver& simulationObserver, + const OptPeriodStringGenerator* optPeriodStringGenerator) +{ + simulationObserver.notifyHebdoProblem(*problemeHebdo, + optimizationNumber, + createMPSfilename(*optPeriodStringGenerator, + optimizationNumber)); +} +} + bool runWeeklyOptimization(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, - int optimizationNumber) + int optimizationNumber, + Solver::Simulation::ISimulationObserver& simulationObserver + ) { const int NombreDePasDeTempsPourUneOptimisation = problemeHebdo ->NombreDePasDeTempsPourUneOptimisation; @@ -102,6 +121,8 @@ bool runWeeklyOptimization(const OptimizationOptions& options, problemeHebdo->weekInTheYear, problemeHebdo->year); + notifyProblemHebdo(problemeHebdo, optimizationNumber, simulationObserver, optPeriodStringGenerator.get()); + if (!OPT_AppelDuSimplexe(options, problemeHebdo, numeroDeLIntervalle, @@ -142,7 +163,9 @@ void runThermalHeuristic(PROBLEME_HEBDO* problemeHebdo) bool OPT_OptimisationLineaire(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, const AdqPatchParams& adqPatchParams, - Solver::IResultWriter& writer) + Solver::IResultWriter& writer, + Solver::Simulation::ISimulationObserver& simulationObserver + ) { if (!problemeHebdo->OptimisationAuPasHebdomadaire) { @@ -175,7 +198,8 @@ bool OPT_OptimisationLineaire(const OptimizationOptions& options, problemeHebdo, adqPatchParams, writer, - PREMIERE_OPTIMISATION); + PREMIERE_OPTIMISATION, + simulationObserver); // We only need the 2nd optimization when NOT solving with integer variables // We also skip the 2nd optimization in the hidden 'Expansion' mode @@ -188,7 +212,8 @@ bool OPT_OptimisationLineaire(const OptimizationOptions& options, problemeHebdo, adqPatchParams, writer, - DEUXIEME_OPTIMISATION); + DEUXIEME_OPTIMISATION, + simulationObserver); } return ret; } diff --git a/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp b/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp index 79ce32f0cb..2ca9c71d56 100644 --- a/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp +++ b/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp @@ -1,27 +1,28 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/optimization-options/options.h" #include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" +#include "antares/solver/simulation/ISimulationObserver.h" #include "antares/solver/simulation/sim_extern_variables_globales.h" using Antares::Solver::Optimization::OptimizationOptions; @@ -29,7 +30,8 @@ using Antares::Solver::Optimization::OptimizationOptions; bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, const AdqPatchParams& adqPatchParams, - Solver::IResultWriter& writer) + Solver::IResultWriter& writer, + Solver::Simulation::ISimulationObserver& simulationObserver) { if (!problemeHebdo->LeProblemeADejaEteInstancie) { @@ -75,5 +77,5 @@ bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, OPT_InitialiserNombreMinEtMaxDeGroupesCoutsDeDemarrage(problemeHebdo); } - return OPT_OptimisationLineaire(options, problemeHebdo, adqPatchParams, writer); + return OPT_OptimisationLineaire(options, problemeHebdo, adqPatchParams, writer, simulationObserver); } diff --git a/src/solver/optimisation/opt_rename_problem.cpp b/src/solver/optimisation/opt_rename_problem.cpp index 7a7553a59a..85edf581b8 100644 --- a/src/solver/optimisation/opt_rename_problem.cpp +++ b/src/solver/optimisation/opt_rename_problem.cpp @@ -21,6 +21,7 @@ #include "antares/solver/optimisation/opt_rename_problem.h" +#include #include const std::string HOUR("hour"); diff --git a/src/solver/optimisation/weekly_optimization.cpp b/src/solver/optimisation/weekly_optimization.cpp index 164cabf32f..cf943b2125 100644 --- a/src/solver/optimisation/weekly_optimization.cpp +++ b/src/solver/optimisation/weekly_optimization.cpp @@ -1,22 +1,22 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . */ #include "antares/solver/optimisation/weekly_optimization.h" @@ -29,14 +29,15 @@ DefaultWeeklyOptimization::DefaultWeeklyOptimization(const OptimizationOptions& PROBLEME_HEBDO* problemeHebdo, AdqPatchParams& adqPatchParams, uint thread_number, - IResultWriter& writer): - WeeklyOptimization(options, problemeHebdo, adqPatchParams, thread_number, writer) + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver) : + WeeklyOptimization(options, problemeHebdo, adqPatchParams, thread_number, writer, simulationObserver) { } void DefaultWeeklyOptimization::solve() { - OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_); + OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_, simulationObserver_.get()); } } // namespace Antares::Solver::Optimization diff --git a/src/solver/simulation/CMakeLists.txt b/src/solver/simulation/CMakeLists.txt index 0d2bc666eb..6a5355ea56 100644 --- a/src/solver/simulation/CMakeLists.txt +++ b/src/solver/simulation/CMakeLists.txt @@ -22,36 +22,37 @@ set(SRC_SIMULATION apply-scenario.cpp - # Solver - include/antares/solver/simulation/solver_utils.h - solver_utils.cpp - include/antares/solver/simulation/solver.h - include/antares/solver/simulation/solver.hxx - include/antares/solver/simulation/solver.data.h - solver.data.cpp - include/antares/solver/simulation/common-eco-adq.h - common-eco-adq.cpp - common-hydro-remix.cpp - common-hydro-levels.cpp - include/antares/solver/simulation/adequacy.h - adequacy.cpp - include/antares/solver/simulation/economy.h - economy.cpp - include/antares/solver/simulation/base_post_process.h - base_post_process.cpp - include/antares/solver/simulation/opt_time_writer.h - opt_time_writer.cpp - include/antares/solver/simulation/adequacy_patch_runtime_data.h - adequacy_patch_runtime_data.cpp - include/antares/solver/simulation/ITimeSeriesNumbersWriter.h + # Solver + include/antares/solver/simulation/solver_utils.h + solver_utils.cpp + include/antares/solver/simulation/solver.h + include/antares/solver/simulation/solver.hxx + include/antares/solver/simulation/solver.data.h + solver.data.cpp + include/antares/solver/simulation/common-eco-adq.h + common-eco-adq.cpp + common-hydro-remix.cpp + common-hydro-levels.cpp + include/antares/solver/simulation/adequacy.h + adequacy.cpp + include/antares/solver/simulation/economy.h + economy.cpp + include/antares/solver/simulation/base_post_process.h + base_post_process.cpp + include/antares/solver/simulation/opt_time_writer.h + opt_time_writer.cpp + include/antares/solver/simulation/adequacy_patch_runtime_data.h + adequacy_patch_runtime_data.cpp + include/antares/solver/simulation/ITimeSeriesNumbersWriter.h include/antares/solver/simulation/hydro-final-reservoir-level-functions.h hydro-final-reservoir-level-functions.cpp - TimeSeriesNumbersWriter.cpp + TimeSeriesNumbersWriter.cpp include/antares/solver/simulation/BindingConstraintsTimeSeriesNumbersWriter.h - economy_mode.cpp - adequacy_mode.cpp - include/antares/solver/simulation/economy_mode.h - include/antares/solver/simulation/adequacy_mode.h + include/antares/solver/simulation/ISimulationObserver.h + economy_mode.cpp + adequacy_mode.cpp + include/antares/solver/simulation/economy_mode.h + include/antares/solver/simulation/adequacy_mode.h ) source_group("simulation" FILES ${SRC_SIMULATION}) diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index c2ac21dbea..8ba97fde33 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/simulation/adequacy.h" @@ -29,10 +29,10 @@ using Antares::Constants::nbHoursInAWeek; namespace Antares::Solver::Simulation { -Adequacy::Adequacy(Data::Study& study, IResultWriter& resultWriter): - study(study), - preproOnly(false), - resultWriter(resultWriter) +Adequacy::Adequacy(Data::Study& study, + IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver) : + study(study), resultWriter(resultWriter), simulationObserver_(simulationObserver) { } @@ -207,7 +207,8 @@ bool Adequacy::year(Progression::Task& progression, OPT_OptimisationHebdomadaire(createOptimizationOptions(study), ¤tProblem, study.parameters.adqPatchParams, - resultWriter); + resultWriter, + simulationObserver_.get()); computingHydroLevels(study.areas, currentProblem, false); @@ -367,7 +368,7 @@ bool Adequacy::year(Progression::Task& progression, return true; } -void Adequacy::incrementProgression(Progression::Task& progression) +void Adequacy::incrementProgression(Progression::Task& progression) const { for (uint w = 0; w < pNbWeeks; ++w) { diff --git a/src/solver/simulation/adequacy_mode.cpp b/src/solver/simulation/adequacy_mode.cpp index 59048ddf7b..86435743ce 100644 --- a/src/solver/simulation/adequacy_mode.cpp +++ b/src/solver/simulation/adequacy_mode.cpp @@ -1,23 +1,23 @@ /* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ +* Copyright 2007-2024, RTE (https://www.rte-france.com) +* See AUTHORS.txt +* SPDX-License-Identifier: MPL-2.0 +* This file is part of Antares-Simulator, +* Adequacy and Performance assessment for interconnected energy networks. +* +* Antares_Simulator is free software: you can redistribute it and/or modify +* it under the terms of the Mozilla Public Licence 2.0 as published by +* the Mozilla Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* Antares_Simulator is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* Mozilla Public Licence 2.0 for more details. +* +* You should have received a copy of the Mozilla Public Licence 2.0 +* along with Antares_Simulator. If not, see . +*/ #include "antares/solver/simulation/adequacy_mode.h" @@ -27,23 +27,24 @@ namespace Antares::Solver { void runSimulationInAdequacyMode(Antares::Data::Study& study, - const Settings& settings, + const Settings& settings, Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info) + IResultWriter& resultWriter, + Benchmarking::OptimizationInfo& info, + Simulation::ISimulationObserver& simulationObserver) { - // Type of the simulation - typedef Solver::Simulation::ISimulation SimulationType; - SimulationType simulation(study, settings, durationCollector, resultWriter); - simulation.checkWriter(); - simulation.run(); + // Type of the simulation + typedef Solver::Simulation::ISimulation SimulationType; + SimulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); + simulation.checkWriter(); + simulation.run(); - if (!(settings.noOutput || settings.tsGeneratorsOnly)) - { + if (!(settings.noOutput || settings.tsGeneratorsOnly)) + { durationCollector("synthesis_export") << [&simulation] { simulation.writeResults(/*synthesis:*/ true); }; - info = simulation.getOptimizationInfo(); - } + info = simulation.getOptimizationInfo(); + } } } // namespace Antares::Solver diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index bc63e19708..4917e76f09 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/simulation/common-eco-adq.h" @@ -91,10 +91,12 @@ static void RecalculDesEchangesMoyens(Data::Study& study, try { NullResultWriter resultWriter; + NullSimulationObserver simulationObserver; OPT_OptimisationHebdomadaire(createOptimizationOptions(study), &problem, study.parameters.adqPatchParams, - resultWriter); + resultWriter, + simulationObserver); } catch (Data::UnfeasibleProblemError&) { diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 4baef3d5b4..1fa0b63625 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/simulation/economy.h" @@ -33,10 +33,13 @@ using Antares::Constants::nbHoursInAWeek; namespace Antares::Solver::Simulation { -Economy::Economy(Data::Study& study, IResultWriter& resultWriter): +Economy::Economy(Data::Study& study, + IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver) : study(study), preproOnly(false), - resultWriter(resultWriter) + resultWriter(resultWriter), + simulationObserver_(simulationObserver) { } @@ -82,7 +85,8 @@ bool Economy::simulationBegin() study.parameters.adqPatchParams, &pProblemesHebdo[numSpace], numSpace, - resultWriter); + resultWriter, + simulationObserver_.get()); postProcessesList_[numSpace] = interfacePostProcessList::create( study.parameters.adqPatchParams, &pProblemesHebdo[numSpace], diff --git a/src/solver/simulation/economy_mode.cpp b/src/solver/simulation/economy_mode.cpp index e79d7a1363..816eb1a212 100644 --- a/src/solver/simulation/economy_mode.cpp +++ b/src/solver/simulation/economy_mode.cpp @@ -1,23 +1,23 @@ /* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ +* Copyright 2007-2024, RTE (https://www.rte-france.com) +* See AUTHORS.txt +* SPDX-License-Identifier: MPL-2.0 +* This file is part of Antares-Simulator, +* Adequacy and Performance assessment for interconnected energy networks. +* +* Antares_Simulator is free software: you can redistribute it and/or modify +* it under the terms of the Mozilla Public Licence 2.0 as published by +* the Mozilla Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* Antares_Simulator is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* Mozilla Public Licence 2.0 for more details. +* +* You should have received a copy of the Mozilla Public Licence 2.0 +* along with Antares_Simulator. If not, see . +*/ #include "antares/solver/simulation/economy_mode.h" @@ -27,23 +27,25 @@ namespace Antares::Solver { void runSimulationInEconomicMode(Antares::Data::Study& study, - const Settings& settings, + const Settings& settings, Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info) + IResultWriter& resultWriter, + Benchmarking::OptimizationInfo& info, + Simulation::ISimulationObserver& simulationObserver +) { - // Type of the simulation - typedef Solver::Simulation::ISimulation SimulationType; - SimulationType simulation(study, settings, durationCollector, resultWriter); - simulation.checkWriter(); - simulation.run(); + // Type of the simulation + typedef Solver::Simulation::ISimulation SimulationType; + SimulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); + simulation.checkWriter(); + simulation.run(); - if (!(settings.noOutput || settings.tsGeneratorsOnly)) - { + if (!(settings.noOutput || settings.tsGeneratorsOnly)) + { durationCollector("synthesis_export") << [&simulation] { simulation.writeResults(/*synthesis:*/ true); }; - info = simulation.getOptimizationInfo(); - } + info = simulation.getOptimizationInfo(); + } } } // namespace Antares::Solver diff --git a/src/solver/simulation/include/antares/solver/simulation/ISimulationObserver.h b/src/solver/simulation/include/antares/solver/simulation/ISimulationObserver.h new file mode 100644 index 0000000000..414695a580 --- /dev/null +++ b/src/solver/simulation/include/antares/solver/simulation/ISimulationObserver.h @@ -0,0 +1,65 @@ + +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include "sim_structure_probleme_economique.h" + +namespace Antares::Solver::Simulation +{ + +/** + * @class ISimulationObserver + * @brief The ISimulationObserver class is an interface for observing the simulation. + * @details It declares the notifyHebdoProblem method. + */ +class ISimulationObserver +{ +public: + virtual ~ISimulationObserver() = default; + /** + * @brief The notifyHebdoProblem method is used to notify of a problem during the simulation. + * @param problemeHebdo A pointer to a PROBLEME_HEBDO object representing the problem. + * @param optimizationNumber The number of the optimization. + * @param name The name of the problem. + */ + virtual void notifyHebdoProblem(const PROBLEME_HEBDO& problemeHebdo, + int optimizationNumber, + std::string_view name) + = 0; +}; + +/** + * @class NullSimulationObserver + * @brief The NullSimulationObserver class is a null object for the ISimulationObserver interface. + * @details It overrides the notifyHebdoProblem method with an empty implementation. + */ +class NullSimulationObserver : public ISimulationObserver +{ +public: + ~NullSimulationObserver() override = default; + void notifyHebdoProblem(const PROBLEME_HEBDO&, int, std::string_view) override + { + //null object pattern + } +}; +} // namespace Antares::Solver::Simulation \ No newline at end of file diff --git a/src/solver/simulation/include/antares/solver/simulation/adequacy.h b/src/solver/simulation/include/antares/solver/simulation/adequacy.h index 6d659103c3..130f3c18f5 100644 --- a/src/solver/simulation/include/antares/solver/simulation/adequacy.h +++ b/src/solver/simulation/include/antares/solver/simulation/adequacy.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #ifndef __SOLVER_SIMULATION_ADEQUACY_H__ #define __SOLVER_SIMULATION_ADEQUACY_H__ @@ -41,7 +41,6 @@ class Adequacy return "adequacy"; } -public: //! \name Constructor & Destructor //@{ /*! @@ -49,20 +48,20 @@ class Adequacy ** ** \param study The current study */ - Adequacy(Data::Study& study, IResultWriter& resultWriter); + Adequacy(Data::Study& study, IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver); //! Destructor ~Adequacy() = default; //@} Benchmarking::OptimizationInfo getOptimizationInfo() const; -public: //! Current study Data::Study& study; //! All variables Solver::Variable::Adequacy::AllVariables variables; //! Prepro only - bool preproOnly; + bool preproOnly = false; protected: void setNbPerformedYearsInParallel(uint nbMaxPerformedYearsInParallel); @@ -79,7 +78,7 @@ class Adequacy OptimizationStatisticsWriter& optWriter, const Antares::Data::Area::ScratchMap& scratchmap); - void incrementProgression(Progression::Task& progression); + void incrementProgression(Progression::Task& progression) const; void simulationEnd(); @@ -102,6 +101,7 @@ class Adequacy Matrix<> pRES; IResultWriter& resultWriter; + std::reference_wrapper simulationObserver_; }; // class Adequacy } // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h b/src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h index 260ba2c92f..66734027b9 100644 --- a/src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h +++ b/src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h @@ -24,6 +24,7 @@ #include "antares/infoCollection/StudyInfoCollector.h" #include "antares/solver/misc/options.h" +#include "antares/solver/simulation/ISimulationObserver.h" #include "antares/writer/i_writer.h" namespace Antares::Solver @@ -32,5 +33,6 @@ void runSimulationInAdequacyMode(Antares::Data::Study& study, const Settings& settings, Benchmarking::DurationCollector& durationCollector, IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info); + Benchmarking::OptimizationInfo& info, + Simulation::ISimulationObserver& simulationObserver); } diff --git a/src/solver/simulation/include/antares/solver/simulation/economy.h b/src/solver/simulation/include/antares/solver/simulation/economy.h index b7661c3f11..592fac59f8 100644 --- a/src/solver/simulation/include/antares/solver/simulation/economy.h +++ b/src/solver/simulation/include/antares/solver/simulation/economy.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #ifndef __SOLVER_SIMULATION_ECONOMY_H__ #define __SOLVER_SIMULATION_ECONOMY_H__ @@ -50,7 +50,9 @@ class Economy ** ** \param study The current study */ - Economy(Data::Study& study, IResultWriter& resultWriter); + Economy(Data::Study& study, + IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver); //! Destructor ~Economy() = default; //@} @@ -100,6 +102,7 @@ class Economy weeklyOptProblems_; std::vector> postProcessesList_; IResultWriter& resultWriter; + std::reference_wrapper simulationObserver_; }; // class Economy } // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/include/antares/solver/simulation/economy_mode.h b/src/solver/simulation/include/antares/solver/simulation/economy_mode.h index 5e1f454884..7437d39cf1 100644 --- a/src/solver/simulation/include/antares/solver/simulation/economy_mode.h +++ b/src/solver/simulation/include/antares/solver/simulation/economy_mode.h @@ -24,6 +24,7 @@ #include "antares/infoCollection/StudyInfoCollector.h" #include "antares/solver/misc/options.h" +#include "antares/solver/simulation/ISimulationObserver.h" #include "antares/writer/i_writer.h" namespace Antares::Solver @@ -32,5 +33,7 @@ void runSimulationInEconomicMode(Antares::Data::Study& study, const Settings& settings, Benchmarking::DurationCollector& durationCollector, IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info); + Benchmarking::OptimizationInfo& info, + Simulation::ISimulationObserver& simulationObserver +); } diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.h b/src/solver/simulation/include/antares/solver/simulation/solver.h index fe16b660b9..cd2abfa366 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #ifndef __SOLVER_SIMULATION_SOLVER_H__ #define __SOLVER_SIMULATION_SOLVER_H__ @@ -26,6 +26,7 @@ #include #include +#include #include #include #include "antares/solver/hydro/management/management.h" @@ -54,7 +55,8 @@ class ISimulation: public Impl ISimulation(Data::Study& study, const ::Settings& settings, Benchmarking::DurationCollector& duration_collector, - IResultWriter& resultWriter); + IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver); //! Destructor ~ISimulation(); //@} @@ -76,7 +78,6 @@ class ISimulation: public Impl */ void writeResults(bool synthesis, uint year = 0, uint numSpace = 9999); -public: //! Reference to the current study Data::Study& study; //! The global settings @@ -136,7 +137,6 @@ class ISimulation: public Impl */ void loopThroughYears(uint firstYear, uint endYear, std::vector& state); -private: //! Some temporary to avoid performing useless complex checks Solver::Private::Simulation::CacheData pData; //! @@ -160,6 +160,7 @@ class ISimulation: public Impl //! Result writer Antares::Solver::IResultWriter& pResultWriter; + std::reference_wrapper simulationObserver_; }; // class ISimulation } // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 232fa520fc..57dff06fd9 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -31,8 +31,8 @@ #include #include #include "antares/concurrency/concurrency.h" -#include "antares/solver//variable/constants.h" -#include "antares/solver//variable/print.h" +#include "antares/solver/variable/constants.h" +#include "antares/solver/variable/print.h" #include "antares/solver/hydro/management/management.h" // Added for use of randomReservoirLevel(...) #include "antares/solver/simulation/apply-scenario.h" #include "antares/solver/simulation/opt_time_writer.h" @@ -61,7 +61,8 @@ public: Variable::State& pState, bool pYearByYear, Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter): + IResultWriter& resultWriter, + ISimulationObserver& simulationObserver): simulation_(simulation), y(pY), yearFailed(pYearFailed), @@ -75,6 +76,7 @@ public: yearByYear(pYearByYear), pDurationCollector(durationCollector), pResultWriter(resultWriter), + simulationObserver_(simulationObserver), hydroManagement(study.areas, study.parameters, study.calendar, @@ -101,6 +103,7 @@ private: bool yearByYear; Benchmarking::DurationCollector& pDurationCollector; IResultWriter& pResultWriter; + std::reference_wrapper simulationObserver_; HydroManagement hydroManagement; Antares::Data::Area::ScratchMap scratchmap; @@ -235,8 +238,9 @@ inline ISimulation::ISimulation( Data::Study& study, const ::Settings& settings, Benchmarking::DurationCollector& duration_collector, - IResultWriter& resultWriter): - ImplementationType(study, resultWriter), + IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver): + ImplementationType(study, resultWriter, simulationObserver), study(study), settings(settings), pNbYearsReallyPerformed(0), @@ -245,7 +249,8 @@ inline ISimulation::ISimulation( pFirstSetParallelWithAPerformedYearWasRun(false), pDurationCollector(duration_collector), pQueueService(study.pQueueService), - pResultWriter(resultWriter) + pResultWriter(resultWriter), + simulationObserver_(simulationObserver) { // Ask to the interface to show the messages logs.info(); @@ -300,9 +305,6 @@ void ISimulation::run() // Determine if we have to use the preprocessors at least one time. pData.initialize(study.parameters); - // Prepro only ? - ImplementationType::preproOnly = settings.tsGeneratorsOnly; - ImplementationType::setNbPerformedYearsInParallel(pNbMaxPerformedYearsInParallel); TSGenerator::ResizeGeneratedTimeSeries(study.areas, study.parameters); @@ -1042,7 +1044,8 @@ void ISimulation::loopThroughYears(uint firstYear, state[numSpace], pYearByYear, pDurationCollector, - pResultWriter); + pResultWriter, + simulationObserver_.get()); results.add(Concurrency::AddTask(*pQueueService, task)); } // End loop over years of the current set of parallel years diff --git a/src/solver/utils/include/antares/solver/utils/name_translator.h b/src/solver/utils/include/antares/solver/utils/name_translator.h index e7a54b3614..5612e30c76 100644 --- a/src/solver/utils/include/antares/solver/utils/name_translator.h +++ b/src/solver/utils/include/antares/solver/utils/name_translator.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #pragma once #include diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index a771c25503..fcbc5cd6b2 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -34,6 +34,7 @@ if (${RECENT_BOOST}) add_subdirectory(end-to-end) add_subdirectory(src) add_subdirectory(kirchhoff-cbuilder) + add_subdirectory(inmemory-study) else() message(STATUS "Boost >= 1.60.0 is required for end-to-end tests, found ${Boost_VERSION}. Skipping") endif() diff --git a/src/tests/end-to-end/CMakeLists.txt b/src/tests/end-to-end/CMakeLists.txt index 9830013131..6c2031e372 100644 --- a/src/tests/end-to-end/CMakeLists.txt +++ b/src/tests/end-to-end/CMakeLists.txt @@ -1,3 +1,2 @@ -add_subdirectory(utils) add_subdirectory(simple_study) add_subdirectory(binding_constraints) \ No newline at end of file diff --git a/src/tests/end-to-end/binding_constraints/CMakeLists.txt b/src/tests/end-to-end/binding_constraints/CMakeLists.txt index 1b7cf52e86..72e2e46f62 100644 --- a/src/tests/end-to-end/binding_constraints/CMakeLists.txt +++ b/src/tests/end-to-end/binding_constraints/CMakeLists.txt @@ -12,18 +12,17 @@ add_executable(tests-binding_constraints target_link_libraries(tests-binding_constraints PRIVATE - test_utils Boost::unit_test_framework model_antares antares-solver-simulation antares-solver-hydro antares-solver-ts-generator + Antares::tests::in-memory-study ) target_include_directories(tests-binding_constraints PRIVATE ${CMAKE_SOURCE_DIR}/solver - ${CMAKE_CURRENT_SOURCE_DIR}/../utils ) add_test(NAME end-to-end-binding_constraints COMMAND tests-binding_constraints) diff --git a/src/tests/end-to-end/binding_constraints/test_binding_constraints.cpp b/src/tests/end-to-end/binding_constraints/test_binding_constraints.cpp index c1b875378f..10f91f2a40 100644 --- a/src/tests/end-to-end/binding_constraints/test_binding_constraints.cpp +++ b/src/tests/end-to-end/binding_constraints/test_binding_constraints.cpp @@ -23,7 +23,7 @@ #include #include -#include "utils.h" +#include "in-memory-study.h" namespace utf = boost::unit_test; namespace tt = boost::test_tools; diff --git a/src/tests/end-to-end/simple_study/CMakeLists.txt b/src/tests/end-to-end/simple_study/CMakeLists.txt index 670cb16187..cc5c93b410 100644 --- a/src/tests/end-to-end/simple_study/CMakeLists.txt +++ b/src/tests/end-to-end/simple_study/CMakeLists.txt @@ -12,19 +12,18 @@ add_executable(tests-simple-study target_link_libraries(tests-simple-study PRIVATE - test_utils antares-solver-hydro antares-solver-variable antares-solver-simulation antares-solver-ts-generator model_antares ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} + Antares::tests::in-memory-study ) target_include_directories(tests-simple-study PRIVATE ${CMAKE_SOURCE_DIR}/solver - ${CMAKE_CURRENT_SOURCE_DIR}/../utils ) add_test(NAME end-to-end-simple-study COMMAND tests-simple-study) diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index bfad50326f..7992165af2 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -22,7 +22,7 @@ #include #include -#include "utils.h" +#include "in-memory-study.h" namespace utf = boost::unit_test; namespace tt = boost::test_tools; diff --git a/src/tests/end-to-end/utils/CMakeLists.txt b/src/tests/end-to-end/utils/CMakeLists.txt deleted file mode 100644 index 166e083bc0..0000000000 --- a/src/tests/end-to-end/utils/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -add_library(test_utils - utils.cpp - utils.h - ) - -target_link_libraries(test_utils - PUBLIC - ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} - Antares::infoCollection - antares-solver-simulation - ) - -target_include_directories(test_utils - PRIVATE - ${CMAKE_SOURCE_DIR}/solver - ) - -set_target_properties(test_utils PROPERTIES FOLDER Unit-tests/end_to_end) - -target_include_directories(test_utils PUBLIC ${Boost_INCLUDE_DIRS}) diff --git a/src/tests/inmemory-study/CMakeLists.txt b/src/tests/inmemory-study/CMakeLists.txt new file mode 100644 index 0000000000..36c757f717 --- /dev/null +++ b/src/tests/inmemory-study/CMakeLists.txt @@ -0,0 +1,25 @@ +add_library(in-memory-study) +add_library(Antares::tests::in-memory-study ALIAS in-memory-study) + +target_sources(in-memory-study + PRIVATE + in-memory-study.cpp + include/in-memory-study.h +) + +target_link_libraries(in-memory-study + PUBLIC + ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} + antares-solver-simulation + PRIVATE + Antares::infoCollection +) + +target_include_directories(in-memory-study + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include +) + +set_target_properties(in-memory-study PROPERTIES FOLDER Unit-tests) + +target_include_directories(in-memory-study PUBLIC ${Boost_INCLUDE_DIRS}) diff --git a/src/tests/end-to-end/utils/utils.cpp b/src/tests/inmemory-study/in-memory-study.cpp similarity index 88% rename from src/tests/end-to-end/utils/utils.cpp rename to src/tests/inmemory-study/in-memory-study.cpp index a42891ea45..77b984fb45 100644 --- a/src/tests/end-to-end/utils/utils.cpp +++ b/src/tests/inmemory-study/in-memory-study.cpp @@ -1,27 +1,28 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #define WIN32_LEAN_AND_MEAN -#include "utils.h" +#include "in-memory-study.h" -void initializeStudy(Study::Ptr study) + +void initializeStudy(Study* study) { study->parameters.reset(); } @@ -187,11 +188,11 @@ void SimulationHandler::create() { study_.initializeRuntimeInfos(); addScratchpadToEachArea(study_); - simulation_ = std::make_shared>(study_, settings_, durationCollector_, - resultWriter_); + resultWriter_, + observer_); SIM_AllocationTableaux(study_); } @@ -203,10 +204,10 @@ StudyBuilder::StudyBuilder() // Make logs shrink to errors (and higher) only logs.verbosityLevel = Logs::Verbosity::Error::level; - study = std::make_shared(); + study = std::make_unique(true); simulation = std::make_shared(*study); - initializeStudy(study); + initializeStudy(study.get()); } void StudyBuilder::simulationBetweenDays(const unsigned int firstDay, const unsigned int lastDay) diff --git a/src/tests/end-to-end/utils/utils.h b/src/tests/inmemory-study/include/in-memory-study.h similarity index 86% rename from src/tests/end-to-end/utils/utils.h rename to src/tests/inmemory-study/include/in-memory-study.h index 1fa55efbff..101b6b47ab 100644 --- a/src/tests/end-to-end/utils/utils.h +++ b/src/tests/inmemory-study/include/in-memory-study.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #pragma once #define WIN32_LEAN_AND_MEAN #include "antares/solver/simulation/economy.h" @@ -30,7 +30,7 @@ using namespace Antares::Solver; using namespace Antares::Solver::Simulation; using namespace Antares::Data::ScenarioBuilder; -void initializeStudy(Study::Ptr study); +void initializeStudy(Study* study); void configureLinkCapacities(AreaLink* link); class TimeSeriesConfigurer @@ -207,6 +207,7 @@ class SimulationHandler Settings settings_; Study& study_; NullResultWriter resultWriter_; + NullSimulationObserver observer_; }; // ========================= @@ -224,7 +225,7 @@ struct StudyBuilder void giveWeightToYear(float weight, unsigned int year); // Data members - std::shared_ptr study; + std::unique_ptr study; std::shared_ptr simulation; }; diff --git a/src/tests/src/CMakeLists.txt b/src/tests/src/CMakeLists.txt index f6275f8386..14c9929f56 100644 --- a/src/tests/src/CMakeLists.txt +++ b/src/tests/src/CMakeLists.txt @@ -1,3 +1,5 @@ +add_subdirectory(api_internal) +add_subdirectory(api_lib) add_subdirectory(utils) add_subdirectory(libs) diff --git a/src/tests/src/api_internal/CMakeLists.txt b/src/tests/src/api_internal/CMakeLists.txt new file mode 100644 index 0000000000..2186dc6f4b --- /dev/null +++ b/src/tests/src/api_internal/CMakeLists.txt @@ -0,0 +1,27 @@ +set(EXECUTABLE_NAME test-api) +add_executable(${EXECUTABLE_NAME}) + +target_sources(${EXECUTABLE_NAME} + PRIVATE + test_api.cpp +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + Antares::solver_api + Antares::tests::in-memory-study +) + +target_include_directories(${EXECUTABLE_NAME} + PRIVATE + #Allow to use the private headers + $ +) + +# Storing tests-ts-numbers under the folder Unit-tests in the IDE +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) + +add_test(NAME test-api COMMAND ${EXECUTABLE_NAME}) + +set_property(TEST test-api PROPERTY LABELS unit) diff --git a/src/tests/src/api_internal/test_api.cpp b/src/tests/src/api_internal/test_api.cpp new file mode 100644 index 0000000000..d60f6315d5 --- /dev/null +++ b/src/tests/src/api_internal/test_api.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define BOOST_TEST_MODULE test_api +#define WIN32_LEAN_AND_MEAN + +#include + +#include + +#include "API.h" +#include "in-memory-study.h" + +class InMemoryStudyLoader: public Antares::IStudyLoader +{ +public: + explicit InMemoryStudyLoader(bool success = true): + success_(success){}; + + [[nodiscard]] std::unique_ptr load() const override + { + if (!success_) + { + return nullptr; + } + StudyBuilder builder; + builder.addAreaToStudy("area1"); + builder.addAreaToStudy("area2"); + builder.setNumberMCyears(1); + builder.study->initializeRuntimeInfos(); + builder.study->parameters.resultFormat = ResultFormat::inMemory; + builder.study->prepareOutput(); + return std::move(builder.study); + } + + bool success_ = true; +}; + +BOOST_AUTO_TEST_CASE(simulation_path_points_to_results) +{ + Antares::API::APIInternal api; + auto study_loader = std::make_unique(); + auto results = api.run(*study_loader.get()); + BOOST_CHECK_EQUAL(results.simulationPath, std::filesystem::path{"no_output"}); + // Testing for "no_output" is a bit weird, but it's the only way to test this without actually + // running the simulation +} + +BOOST_AUTO_TEST_CASE(api_run_contains_antares_problem) +{ + Antares::API::APIInternal api; + auto study_loader = std::make_unique(); + auto results = api.run(*study_loader.get()); + + BOOST_CHECK(!results.antares_problems.empty()); + BOOST_CHECK(!results.error); +} + +BOOST_AUTO_TEST_CASE(result_failure_when_study_is_null) +{ + Antares::API::APIInternal api; + auto study_loader = std::make_unique(false); + auto results = api.run(*study_loader.get()); + + BOOST_CHECK(results.error); +} + +// Test where data in problems are consistant with data in study +BOOST_AUTO_TEST_CASE(result_contains_problems) +{ + Antares::API::APIInternal api; + auto study_loader = std::make_unique(); + auto results = api.run(*study_loader.get()); + + BOOST_CHECK(!results.antares_problems.empty()); + BOOST_CHECK(!results.error); + BOOST_CHECK_EQUAL(results.antares_problems.weeklyProblems.size(), 52); +} diff --git a/src/tests/src/api_lib/CMakeLists.txt b/src/tests/src/api_lib/CMakeLists.txt new file mode 100644 index 0000000000..b5ce633955 --- /dev/null +++ b/src/tests/src/api_lib/CMakeLists.txt @@ -0,0 +1,20 @@ +set(EXECUTABLE_NAME test-client-api) +add_executable(${EXECUTABLE_NAME}) + +target_sources(${EXECUTABLE_NAME} + PRIVATE + test_api.cpp +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + Antares::solver_api +) + +# Storing tests-ts-numbers under the folder Unit-tests in the IDE +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) + +add_test(NAME test-client-api COMMAND ${EXECUTABLE_NAME}) + +set_property(TEST test-client-api PROPERTY LABELS unit) diff --git a/src/tests/src/api_lib/test_api.cpp b/src/tests/src/api_lib/test_api.cpp new file mode 100644 index 0000000000..0dbddfae7f --- /dev/null +++ b/src/tests/src/api_lib/test_api.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define BOOST_TEST_MODULE test_api +#define WIN32_LEAN_AND_MEAN + +#include + +#include "antares/api/solver.h" + +BOOST_AUTO_TEST_CASE(result_failure_when_study_path_invalid) +{ + using namespace std::string_literals; + auto results = Antares::API::PerformSimulation("dummy"s); + BOOST_CHECK(results.error); + BOOST_CHECK(!results.error->reason.empty()); +} diff --git a/src/tests/src/libs/CMakeLists.txt b/src/tests/src/libs/CMakeLists.txt index b97a7df1bc..81b6173280 100644 --- a/src/tests/src/libs/CMakeLists.txt +++ b/src/tests/src/libs/CMakeLists.txt @@ -1,2 +1,2 @@ -add_subdirectory(antares) \ No newline at end of file +add_subdirectory(antares) diff --git a/src/tests/src/solver/CMakeLists.txt b/src/tests/src/solver/CMakeLists.txt index 690cf4fa68..e301a13a77 100644 --- a/src/tests/src/solver/CMakeLists.txt +++ b/src/tests/src/solver/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(simulation) add_subdirectory(optimisation) add_subdirectory(utils) add_subdirectory(infeasible-problem-analysis) +add_subdirectory(lps) diff --git a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp index d333f5104c..5f10a75879 100644 --- a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp +++ b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp @@ -24,16 +24,15 @@ #include #include #include +#include #include "antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h" #include "antares/solver/infeasible-problem-analysis/unfeasible-pb-analyzer.h" #include "antares/solver/infeasible-problem-analysis/variables-bounds-consistency.h" -#include "ortools/linear_solver/linear_solver.h" - namespace bdata = boost::unit_test::data; -using operations_research::MPSolver; +using namespace operations_research; using Antares::Optimization::ConstraintSlackAnalysis; using Antares::Optimization::UnfeasibilityAnalysis; diff --git a/src/tests/src/solver/lps/CMakeLists.txt b/src/tests/src/solver/lps/CMakeLists.txt new file mode 100644 index 0000000000..89121152ba --- /dev/null +++ b/src/tests/src/solver/lps/CMakeLists.txt @@ -0,0 +1,20 @@ +set(EXECUTABLE_NAME test-lps) +add_executable(${EXECUTABLE_NAME}) + +target_sources(${EXECUTABLE_NAME} + PRIVATE + test_lps.cpp +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + antares-solver-simulation +) + +# Storing tests-ts-numbers under the folder Unit-tests in the IDE +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) + +add_test(NAME test-lps COMMAND ${EXECUTABLE_NAME}) + +set_property(TEST test-lps PROPERTY LABELS unit) diff --git a/src/tests/src/solver/lps/test_lps.cpp b/src/tests/src/solver/lps/test_lps.cpp new file mode 100644 index 0000000000..3a0bf4aa34 --- /dev/null +++ b/src/tests/src/solver/lps/test_lps.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define BOOST_TEST_MODULE test_translator +#define WIN32_LEAN_AND_MEAN + +#include + +#include + +using namespace Antares::Solver; + +BOOST_AUTO_TEST_CASE(new_lps_is_empty) +{ + LpsFromAntares lps; + BOOST_CHECK(lps.empty()); +} + +BOOST_AUTO_TEST_CASE(lps_with_only_constant_data_is_empty) +{ + LpsFromAntares lps; + lps.setConstantData(ConstantDataFromAntares()); + BOOST_CHECK(lps.empty()); +} + +BOOST_AUTO_TEST_CASE(lps_with_no_variabled_is_empty) +{ + LpsFromAntares lps; + lps.constantProblemData.VariablesCount = 0; + lps.addWeeklyData({0, 0}, WeeklyDataFromAntares()); + BOOST_CHECK(lps.empty()); +} + +BOOST_AUTO_TEST_CASE(lps_with_both_constant_and_weekly_data_is_not_empty) +{ + LpsFromAntares lps; + lps.constantProblemData.VariablesCount = 65; + lps.addWeeklyData({0, 0}, WeeklyDataFromAntares()); + BOOST_CHECK(!lps.empty()); +} + +BOOST_AUTO_TEST_CASE(replace_const_data) +{ + LpsFromAntares lps; + ConstantDataFromAntares var; + var.VariablesCount = 42; + lps.setConstantData(var); + BOOST_CHECK(lps.constantProblemData.VariablesCount == 42); +} + +// Add weekly data for week 1 year 1 +BOOST_AUTO_TEST_CASE(add_weekly_data_for_week_1_year_1) +{ + LpsFromAntares lps; + WeeklyDataFromAntares w; + w.RHS.push_back(43); + lps.addWeeklyData({1, 1}, w); + BOOST_CHECK(lps.weeklyData({1, 1}).RHS.size() != WeeklyDataFromAntares().RHS.size()); +} diff --git a/src/tests/src/solver/optimisation/CMakeLists.txt b/src/tests/src/solver/optimisation/CMakeLists.txt index 72d92448a3..d3b9a9a82e 100644 --- a/src/tests/src/solver/optimisation/CMakeLists.txt +++ b/src/tests/src/solver/optimisation/CMakeLists.txt @@ -1,24 +1,2 @@ -# Useful variables definitions -set(src_solver_optimisation "${CMAKE_SOURCE_DIR}/solver/optimisation") - -set(EXECUTABLE_NAME tests-adq-patch) -add_executable(${EXECUTABLE_NAME} adequacy_patch.cpp) - -target_include_directories(${EXECUTABLE_NAME} - PRIVATE - "${src_solver_optimisation}" -) - -target_link_libraries(${EXECUTABLE_NAME} - PRIVATE - Boost::unit_test_framework - model_antares - array -) - -# Storing tests-ts-numbers under the folder Unit-tests in the IDE -set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) - -add_test(NAME test-adq-patch COMMAND ${EXECUTABLE_NAME}) - -set_property(TEST test-adq-patch PROPERTY LABELS unit) +add_subdirectory(adequacy_patch) +add_subdirectory(translator) \ No newline at end of file diff --git a/src/tests/src/solver/optimisation/adequacy_patch/CMakeLists.txt b/src/tests/src/solver/optimisation/adequacy_patch/CMakeLists.txt new file mode 100644 index 0000000000..bb28a99864 --- /dev/null +++ b/src/tests/src/solver/optimisation/adequacy_patch/CMakeLists.txt @@ -0,0 +1,24 @@ +# Useful variables definitions +set(src_solver_optimisation "${CMAKE_SOURCE_DIR}/solver/optimisation") + +set(EXECUTABLE_NAME tests-adq-patch) +add_executable(${EXECUTABLE_NAME} adequacy_patch.cpp) + +target_include_directories(${EXECUTABLE_NAME} + PRIVATE + "${src_solver_optimisation}" +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + model_antares + array +) + +# Storing tests-ts-numbers under the folder Unit-tests in the IDE +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) + +add_test(NAME test-adq-patch COMMAND ${EXECUTABLE_NAME}) + +set_property(TEST test-adq-patch PROPERTY LABELS unit) diff --git a/src/tests/src/solver/optimisation/adequacy_patch.cpp b/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp similarity index 100% rename from src/tests/src/solver/optimisation/adequacy_patch.cpp rename to src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp diff --git a/src/tests/src/solver/optimisation/translator/CMakeLists.txt b/src/tests/src/solver/optimisation/translator/CMakeLists.txt new file mode 100644 index 0000000000..87f3d5a0cb --- /dev/null +++ b/src/tests/src/solver/optimisation/translator/CMakeLists.txt @@ -0,0 +1,20 @@ +set(EXECUTABLE_NAME test-translator) +add_executable(${EXECUTABLE_NAME}) + +target_sources(${EXECUTABLE_NAME} + PRIVATE + test_translator.cpp +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + model_antares +) + +# Storing tests-ts-numbers under the folder Unit-tests in the IDE +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) + +add_test(NAME test-translator COMMAND ${EXECUTABLE_NAME}) + +set_property(TEST test-translator PROPERTY LABELS unit) diff --git a/src/tests/src/solver/optimisation/translator/test_translator.cpp b/src/tests/src/solver/optimisation/translator/test_translator.cpp new file mode 100644 index 0000000000..6fdc32c8fd --- /dev/null +++ b/src/tests/src/solver/optimisation/translator/test_translator.cpp @@ -0,0 +1,189 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define BOOST_TEST_MODULE test_translator +#define WIN32_LEAN_AND_MEAN + +#include + +#include + +#include +#include "antares/solver/utils/opt_period_string_generator.h" + +using namespace Antares::Solver; + +class StubOptPeriodStringGenerator: public OptPeriodStringGenerator +{ +public: + std::string to_string() const override + { + return "Plop"; + } +}; + +BOOST_AUTO_TEST_CASE(null_hebdo_is_empty_lps) +{ + HebdoProblemToLpsTranslator translator; + auto ret = translator.translate(nullptr, std::string()); + BOOST_CHECK(ret == WeeklyDataFromAntares()); +} + +BOOST_AUTO_TEST_CASE(non_null_hebdo_returns_non_empty_lps) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.CoutLineaire.push_back(45); + auto ret = translator.translate(&problemHebdo, std::string()); + BOOST_CHECK(ret != WeeklyDataFromAntares()); +} + +BOOST_AUTO_TEST_CASE(Data_properly_copied) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.CoutLineaire = {0, 1, 2}; + problemHebdo.Xmax = {10, 11, 12}; + problemHebdo.Xmin = {20, 21, 22}; + problemHebdo.NomDesVariables = {"a", "b", "c"}; + problemHebdo.NomDesContraintes = {"d", "e", "f"}; + problemHebdo.SecondMembre = {30, 31, 32}; + + auto ret = translator.translate(&problemHebdo, std::string()); + BOOST_CHECK(ret.LinearCost == problemHebdo.CoutLineaire); + BOOST_CHECK(ret.Xmax == problemHebdo.Xmax); + BOOST_CHECK(ret.Xmin == problemHebdo.Xmin); + BOOST_CHECK(ret.RHS == problemHebdo.SecondMembre); + + BOOST_CHECK(ret.variables == problemHebdo.NomDesVariables); + BOOST_CHECK(ret.constraints == problemHebdo.NomDesContraintes); +} + +BOOST_AUTO_TEST_CASE(translate_sens) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.Sens = "<=>"; + + auto ret = translator.translate(&problemHebdo, std::string()); + BOOST_CHECK(ret.Direction == std::vector({'<', '=', '>'})); +} + +BOOST_AUTO_TEST_CASE(translate_name_is_filled) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + + auto ret = translator.translate(&problemHebdo, "dummy"); + BOOST_CHECK(!ret.name.empty()); +} + +BOOST_AUTO_TEST_CASE(translate_name_is_properly_filled) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + + auto ret = translator.translate(&problemHebdo, "problem-Plop--optim-nb-1.mps"); + BOOST_CHECK_EQUAL(ret.name, "problem-Plop--optim-nb-1.mps"); +} + +BOOST_AUTO_TEST_CASE(empty_problem_empty_const_data) +{ + HebdoProblemToLpsTranslator translator; + auto ret = translator.commonProblemData(nullptr); + BOOST_CHECK(ret == ConstantDataFromAntares()); +} + +BOOST_AUTO_TEST_CASE(common_data_properly_copied) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.NombreDeVariables = 1; + problemHebdo.NombreDeContraintes = 2; + problemHebdo.TypeDeVariable = {0, 1, 2}; + problemHebdo.IndicesDebutDeLigne = {0, 3}; + problemHebdo.NombreDeTermesDesLignes = {3, 3}; + problemHebdo.CoefficientsDeLaMatriceDesContraintes = {0, 1, 2, 3, 4, 5}; + problemHebdo.IndicesColonnes = {0, 1, 2, 3, 4, 5}; + + auto ret = translator.commonProblemData(&problemHebdo); + BOOST_CHECK_EQUAL(ret.VariablesCount, problemHebdo.NombreDeVariables); + BOOST_CHECK_EQUAL(ret.ConstraintesCount, problemHebdo.NombreDeContraintes); + BOOST_CHECK(std::ranges::equal(ret.VariablesType, problemHebdo.TypeDeVariable)); + BOOST_CHECK(ret.ConstraintsMatrixCoeff == problemHebdo.CoefficientsDeLaMatriceDesContraintes); + BOOST_CHECK(std::ranges::equal(ret.ColumnIndexes, problemHebdo.IndicesColonnes)); + BOOST_CHECK(std::ranges::equal(ret.Mdeb, problemHebdo.IndicesDebutDeLigne)); +} + +// throw exception if NombreDeVariables is 0 +BOOST_AUTO_TEST_CASE(throw_exception_if_NombreDeVariables_is_0) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.NombreDeVariables = 0; + BOOST_CHECK_THROW(translator.commonProblemData(&problemHebdo), std::runtime_error); +} + +BOOST_AUTO_TEST_CASE(throw_exception_if_NombreDeContraintes_is_0) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.NombreDeContraintes = 0; + BOOST_CHECK_THROW(translator.commonProblemData(&problemHebdo), std::runtime_error); +} + +BOOST_AUTO_TEST_CASE(throw_exception_if_IndicesDebutDeLigne_out_of_bound) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.NombreDeVariables = 1; + problemHebdo.NombreDeContraintes = 3; + problemHebdo.IndicesDebutDeLigne = {0, 3}; + problemHebdo.NombreDeTermesDesLignes = {0, 3, 6, 7, 8}; + BOOST_CHECK_THROW(translator.commonProblemData(&problemHebdo), std::runtime_error); +} + +BOOST_AUTO_TEST_CASE(throw_exception_if_NombreDeTermesDesLignes_out_of_bound) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.NombreDeVariables = 1; + problemHebdo.NombreDeContraintes = 3; + problemHebdo.NombreDeTermesDesLignes = {0, 3}; + problemHebdo.IndicesDebutDeLigne = {0, 3, 6, 7, 8}; + BOOST_CHECK_THROW(translator.commonProblemData(&problemHebdo), std::runtime_error); +} + +// NombreDeCoefficients +BOOST_AUTO_TEST_CASE(NombreDeCoefficients_is_properly_computed) +{ + HebdoProblemToLpsTranslator translator; + PROBLEME_ANTARES_A_RESOUDRE problemHebdo; + problemHebdo.NombreDeVariables = 1; + problemHebdo.NombreDeContraintes = 3; + problemHebdo.IndicesDebutDeLigne = {0, 3, 6}; + problemHebdo.NombreDeTermesDesLignes = {3, 3, 3}; + problemHebdo.CoefficientsDeLaMatriceDesContraintes = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + problemHebdo.IndicesColonnes = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + + auto ret = translator.commonProblemData(&problemHebdo); + BOOST_CHECK_EQUAL(ret.CoeffCount, 9); +} diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-ntc-renderer.h b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-ntc-renderer.h index 9bb7cdfd1f..edc1c49580 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-ntc-renderer.h +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-ntc-renderer.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #pragma once #include "scenario-builder-renderer-base.h" diff --git a/src/vcpkg.json b/src/vcpkg.json index fdd3963fd5..08acfb9e79 100644 --- a/src/vcpkg.json +++ b/src/vcpkg.json @@ -24,7 +24,7 @@ "version>=": "1.81.0" }, { - "name": "boost-algorithm", + "name": "boost-core", "version>=": "1.81.0" }, { From b2cede8835a9a0261579cab30868fa9b6ed3a687 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:48:42 +0200 Subject: [PATCH 042/127] add develop to sonar branch (#2206) --- .github/workflows/sonarcloud.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index cfe5324d3c..e16bb1180e 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,6 +1,8 @@ name: SonarCloud on: + branches: + - develop pull_request: jobs: From 52c7bd6303062d263001e5a3ddea7eb8cbeb5bdd Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:58:04 +0200 Subject: [PATCH 043/127] Fix/sonar (#2207) --- .github/workflows/sonarcloud.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index e16bb1180e..e72287894d 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,6 +1,7 @@ name: SonarCloud on: + push: branches: - develop pull_request: From 5a592b4fd748b1ace805c1f061bf7ee1df7aef69 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:05:04 +0200 Subject: [PATCH 044/127] Improve error message for ts-generation arg parsing (#2205) --- src/libs/antares/utils/utils.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/antares/utils/utils.cpp b/src/libs/antares/utils/utils.cpp index 047881b0e6..5f5efc9e9e 100644 --- a/src/libs/antares/utils/utils.cpp +++ b/src/libs/antares/utils/utils.cpp @@ -116,6 +116,8 @@ std::vector> splitStringIntoPairs(const std: else { logs.warning() << "Error while parsing: " << token; + logs.warning() << "Correct format is: \"object1" << delimiter2 << "object2" + << delimiter1 << "object3" << delimiter2 << "object4\""; } } From 8dc4f18f54a91345d8afc2faec543bc26c626804 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:43:58 +0200 Subject: [PATCH 045/127] Remove TS links from solver (#2155) The aim of this PR is removing from **Antares solver** the code related to TS generation associated to **links** capacity. It follows PR #1986 Note that : - Loading the study is now no longer required to generate TS associated to links. - Handling errors related to each link's TS generation was simplified : For a link, if we meet a problem while loading data required to generated its TS, a **warning** is raised and the TS generation for this link will be skipped. What was done : - Reading data for links TS generation : We now don't need the study to be loaded in order to generate TS. Some new code retrieves data from study - Generating TS associated to links : Code of base branch was adapted to use data having a different format. - Code related to link TS generation in **solver** was removed. An exception though : due to new data (related to links TS generation) next to data consumed by solver, we had to keep special skipping code for it, otherwise we get reading errors. --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- src/libs/antares/study/area/links.cpp | 135 +------ src/libs/antares/study/area/list.cpp | 2 +- .../antares/study/cleaner/cleaner-v20.cpp | 2 +- src/libs/antares/study/fwd.cpp | 4 - .../study/include/antares/study/area/area.h | 3 +- .../study/include/antares/study/area/links.h | 5 - .../antares/study/include/antares/study/fwd.h | 2 - .../include/antares/study/load-options.h | 3 - .../study/include/antares/study/parameters.h | 2 - src/libs/antares/study/parameters.cpp | 13 +- src/solver/ts-generator/availability.cpp | 166 +++++---- .../antares/solver/ts-generator/generator.h | 45 ++- .../antares/solver/ts-generator/prepro.h | 22 -- src/tools/ts-generator/main.cpp | 342 ++++++++++++++++-- 14 files changed, 464 insertions(+), 282 deletions(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 40da9df149..96a304d28e 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -23,10 +23,7 @@ #include #include - -#include - -#include +#include #include #include @@ -137,58 +134,6 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol return success; } -// This function is "lazy", it only loads files if they exist -// and set a `valid` flag -bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) -{ - const std::string idprepro = std::string(from->id) + "/" + std::string(with->id); - tsGeneration.prepro = - std::make_unique(idprepro, tsGeneration.unitCount); - - bool anyFileWasLoaded = false; - - // file name without suffix, .txt for general infos and mod_direct/indirect.txt - fs::path preproFile = folder / "prepro" / with->id.c_str(); - - // Prepro - fs::path filepath = preproFile; - filepath += ".txt"; - if (fs::exists(filepath)) - { - anyFileWasLoaded = true; - tsGeneration.valid = tsGeneration.prepro->data.loadFromCSVFile( - filepath.string(), - Antares::Data::PreproAvailability::preproAvailabilityMax, - DAYS_PER_YEAR) - && tsGeneration.prepro->validate(); - } - - // Modulation - filepath = preproFile; - filepath += "_mod_direct.txt"; - if (fs::exists(filepath)) - { - anyFileWasLoaded = true; - tsGeneration.valid &= tsGeneration.modulationCapacityDirect - .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); - } - - filepath = preproFile; - filepath += "_mod_indirect.txt"; - if (fs::exists(filepath)) - { - anyFileWasLoaded = true; - tsGeneration.valid &= tsGeneration.modulationCapacityIndirect - .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); - } - - if (anyFileWasLoaded) - { - return tsGeneration.valid; - } - return true; -} - bool AreaLink::isLinkPhysical() const { // All link types are physical, except arVirt @@ -360,7 +305,16 @@ AreaLink* AreaAddLinkBetweenAreas(Area* area, Area* with, bool warning) namespace // anonymous { -bool handleKey(Data::AreaLink& link, const String& key, const String& value) + +bool isPropertyUsedForLinkTSgeneration(const std::string& key) +{ + std::array listKeys + = {"unitcount", "nominalcapacity", "law.planned", "law.forced", + "volatility.planned", "volatility.forced", "force-no-generation"}; + return std::find(listKeys.begin(), listKeys.end(), key) != listKeys.end(); +} + +bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const String& value) { if (key == "hurdles-cost") { @@ -503,55 +457,9 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) link.filterYearByYear = stringIntoDatePrecision(value); return true; } - return false; -} - -bool handleTSGenKey(Data::LinkTsGeneration& out, - const std::string& key, - const String& value) -{ - - if (key == "unitcount") - { - return value.to(out.unitCount); - } - - if (key == "nominalcapacity") - { - return value.to(out.nominalCapacity); - } - - if (key == "law.planned") - { - return value.to(out.plannedLaw); - } - - if (key == "law.forced") - { - return value.to(out.forcedLaw); - } - - if (key == "volatility.planned") - { - return value.to(out.plannedVolatility); - } - - if (key == "volatility.forced") - { - return value.to(out.forcedVolatility); - } - - if (key == "force-no-generation") - { - return value.to(out.forceNoGeneration); - } - - return false; -} - -bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const String& value) -{ - return handleKey(link, key, value) || handleTSGenKey(link.tsGeneration, key, value); + // Properties used by TS generator only. + // We just skip them (otherwise : reading error) + return isPropertyUsedForLinkTSgeneration(key.to()); } [[noreturn]] void logLinkDataCheckError(const AreaLink& link, const String& msg, int hour) @@ -572,7 +480,7 @@ bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const } } // anonymous namespace -bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::path& folder, bool loadTSGen) +bool AreaLinksLoadFromFolder(Study& study, AreaList* areaList, Area* area, const fs::path& folder) { // Assert assert(area); @@ -594,16 +502,16 @@ bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::pa for (auto* s = ini.firstSection; s; s = s->next) { // Getting the name of the area - std::string buffer = transformNameIntoID(s->name); + const std::string targetAreaName = transformNameIntoID(s->name); // Trying to find it - Area* linkedWith = AreaListLFind(l, buffer.c_str()); - if (!linkedWith) + Area* targetArea = AreaListLFind(areaList, targetAreaName.c_str()); + if (!targetArea) { logs.error() << '`' << s->name << "`: Impossible to find the area"; continue; } - AreaLink* lnk = AreaAddLinkBetweenAreas(area, linkedWith); + AreaLink* lnk = AreaAddLinkBetweenAreas(area, targetArea); if (!lnk) { logs.error() << "Impossible to create a link between two areas"; @@ -698,11 +606,6 @@ bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::pa } } - if (loadTSGen) - { - ret = link.loadTSGenTimeSeries(folder) && ret; - } - // From the solver only if (study.usedByTheSolver) { diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index f76afb5686..fd2b3bb5b7 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -881,7 +881,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, // Links { fs::path folder = fs::path(study.folderInput.c_str()) / "links" / area.id.c_str(); - ret = AreaLinksLoadFromFolder(study, list, &area, folder, options.linksLoadTSGen) && ret; + ret = AreaLinksLoadFromFolder(study, list, &area, folder) && ret; } // UI diff --git a/src/libs/antares/study/cleaner/cleaner-v20.cpp b/src/libs/antares/study/cleaner/cleaner-v20.cpp index 7d1aadf58e..3c8f183be4 100644 --- a/src/libs/antares/study/cleaner/cleaner-v20.cpp +++ b/src/libs/antares/study/cleaner/cleaner-v20.cpp @@ -362,7 +362,7 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) logs.verbosityLevel = Logs::Verbosity::Warning::level; // load all links buffer.clear() << infos->folder << "/input/links/" << area->id; - if (not AreaLinksLoadFromFolder(*study, arealist, area, buffer.c_str(), false)) + if (not AreaLinksLoadFromFolder(*study, arealist, area, buffer.c_str())) { delete arealist; delete study; diff --git a/src/libs/antares/study/fwd.cpp b/src/libs/antares/study/fwd.cpp index f45f093aaf..100a4b127e 100644 --- a/src/libs/antares/study/fwd.cpp +++ b/src/libs/antares/study/fwd.cpp @@ -53,8 +53,6 @@ const char* SeedToCString(SeedIndex seed) return "Noise on virtual Hydro costs"; case seedHydroManagement: return "Initial reservoir levels"; - case seedTsGenLinks: - return "Links time-series generation"; case seedMax: return ""; } @@ -87,8 +85,6 @@ const char* SeedToID(SeedIndex seed) return "seed-hydro-costs"; case seedHydroManagement: return "seed-initial-reservoir-levels"; - case seedTsGenLinks: - return "seed-tsgen-links"; case seedMax: return ""; } diff --git a/src/libs/antares/study/include/antares/study/area/area.h b/src/libs/antares/study/include/antares/study/area/area.h index 6fbb69dde4..6661ab8556 100644 --- a/src/libs/antares/study/include/antares/study/area/area.h +++ b/src/libs/antares/study/include/antares/study/area/area.h @@ -727,8 +727,7 @@ AreaLink* AreaAddLinkBetweenAreas(Area* area, Area* with, bool warning = true); bool AreaLinksLoadFromFolder(Study& s, AreaList* l, Area* area, - const std::filesystem::path& folder, - bool loadTSGen); + const std::filesystem::path& folder); /*! ** \brief Save interconnections of a given area into a folder (`input/areas/[area]/ntc`) diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index 5b01ba3efd..fd4b8e69d8 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -71,8 +71,6 @@ class AreaLink final: public Yuni::NonCopyable bool loadTimeSeries(const StudyVersion& version, const AnyString& folder); - bool loadTSGenTimeSeries(const std::filesystem::path& folder); - void storeTimeseriesNumbers(Solver::IResultWriter& writer) const; //! \name Area @@ -208,9 +206,6 @@ class AreaLink final: public Yuni::NonCopyable int linkWidth; friend struct CompareLinkName; - - LinkTsGeneration tsGeneration; - }; // class AreaLink struct CompareLinkName final diff --git a/src/libs/antares/study/include/antares/study/fwd.h b/src/libs/antares/study/include/antares/study/fwd.h index 7256eda4a2..6fa2819aca 100644 --- a/src/libs/antares/study/include/antares/study/fwd.h +++ b/src/libs/antares/study/include/antares/study/fwd.h @@ -361,8 +361,6 @@ enum SeedIndex seedHydroCosts, //! Seed - Hydro management seedHydroManagement, - //! The seed for links - seedTsGenLinks, //! The number of seeds seedMax, }; diff --git a/src/libs/antares/study/include/antares/study/load-options.h b/src/libs/antares/study/include/antares/study/load-options.h index 1ecd34b968..41eee86cbb 100644 --- a/src/libs/antares/study/include/antares/study/load-options.h +++ b/src/libs/antares/study/include/antares/study/load-options.h @@ -53,9 +53,6 @@ class StudyLoadOptions //! Force the year-by-year flag bool forceYearByYear; - //! Load data associated to link TS generation - bool linksLoadTSGen = false; - //! Force the derated mode bool forceDerated; diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index 73ba5b5f77..204afcdd0d 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -257,8 +257,6 @@ class Parameters final uint nbTimeSeriesThermal; //! Nb of timeSeries : Solar uint nbTimeSeriesSolar; - //! Nb of timeSeries : Links - uint nbLinkTStoGenerate = 1; //@} //! \name Time-series refresh diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index dbfb7f81e2..af0aedc14b 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -530,7 +530,9 @@ static bool SGDIntLoadFamily_General(Parameters& d, } if (key == "nbtimeserieslinks") { - return value.to(d.nbLinkTStoGenerate); + // This data is among solver data, but is useless while running a simulation + // Only by TS generator. We skip it here (otherwise, we get a reading error). + return true; } // Interval values if (key == "refreshintervalload") @@ -1026,10 +1028,6 @@ static bool SGDIntLoadFamily_SeedsMersenneTwister(Parameters& d, { return value.to(d.seed[seedTsGenSolar]); } - if (key == "seed_links") - { - return value.to(d.seed[seedTsGenLinks]); - } if (key == "seed_timeseriesnumbers") { return value.to(d.seed[seedTimeseriesNumbers]); @@ -1046,6 +1044,10 @@ static bool SGDIntLoadFamily_SeedsMersenneTwister(Parameters& d, return value.to(d.seed[sd]); } } + if (key == "seed-tsgen-links") + { + return true; // Useless for solver, belongs to TS generator + } } } return false; @@ -1766,7 +1768,6 @@ void Parameters::saveToINI(IniFile& ini) const section->add("nbTimeSeriesWind", nbTimeSeriesWind); section->add("nbTimeSeriesThermal", nbTimeSeriesThermal); section->add("nbTimeSeriesSolar", nbTimeSeriesSolar); - section->add("nbtimeserieslinks", nbLinkTStoGenerate); // Refresh ParametersSaveTimeSeries(section, "refreshTimeSeries", timeSeriesToRefresh); diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 69f62a10a1..696725f846 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -28,6 +28,7 @@ #include #include #include +#include // For Antares::IO::fileSetContent #include "antares/study/simulation.h" #define SEP Yuni::IO::Separator @@ -36,21 +37,21 @@ constexpr double FAILURE_RATE_EQ_1 = 0.999; namespace Antares::TSGenerator { -AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* source): - unitCount(source->unitCount), - nominalCapacity(source->nominalCapacity), - forcedVolatility(source->forcedVolatility), - plannedVolatility(source->plannedVolatility), - forcedLaw(source->forcedLaw), - plannedLaw(source->plannedLaw), - prepro(source->prepro), - series(source->series.timeSeries), - modulationCapacity(source->modulation[Data::thermalModulationCapacity]), - name(source->name()) +AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* cluster): + unitCount(cluster->unitCount), + nominalCapacity(cluster->nominalCapacity), + forcedVolatility(cluster->forcedVolatility), + plannedVolatility(cluster->plannedVolatility), + forcedLaw(cluster->forcedLaw), + plannedLaw(cluster->plannedLaw), + prepro(cluster->prepro), + series(cluster->series.timeSeries), + modulationCapacity(cluster->modulation[Data::thermalModulationCapacity]), + name(cluster->name()) { } -AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::LinkTsGeneration& source, +AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(LinkTSgenerationParams& source, Data::TimeSeries& capacity, Matrix<>& modulation, const std::string& areaDestName): @@ -73,8 +74,9 @@ class GeneratorTempData final { public: explicit GeneratorTempData(Data::Study&, unsigned, MersenneTwister&); + explicit GeneratorTempData(bool, unsigned, MersenneTwister&); - void generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) const; + void generateTS(AvailabilityTSGeneratorData&) const; private: bool derated; @@ -106,6 +108,13 @@ GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGe { } +GeneratorTempData::GeneratorTempData(bool derated, unsigned int nbOfSeriesToGen, MersenneTwister& rndGenerator): + derated(derated), + nbOfSeriesToGen_(nbOfSeriesToGen), + rndgenerator(rndGenerator) +{ +} + template void GeneratorTempData::prepareIndispoFromLaw(Data::StatisticalLaw law, double volatility, @@ -184,28 +193,18 @@ int GeneratorTempData::durationGenerator(Data::StatisticalLaw law, return 0; } -void GeneratorTempData::generateTS(const Data::Area& area, - AvailabilityTSGeneratorData& cluster) const +void GeneratorTempData::generateTS(AvailabilityTSGeneratorData& tsGenerationData) const { - if (!cluster.prepro) - { - logs.error() - << "Cluster: " << area.name << '/' << cluster.name - << ": The timeseries will not be regenerated. All data related to the ts-generator for " - << "'thermal' have been released."; - return; - } + assert(tsGenerationData.prepro); - assert(cluster.prepro); - - if (0 == cluster.unitCount || 0 == cluster.nominalCapacity) + if (0 == tsGenerationData.unitCount || 0 == tsGenerationData.nominalCapacity) { return; } - const auto& preproData = *(cluster.prepro); + const auto& preproData = *(tsGenerationData.prepro); - int AUN = cluster.unitCount; + int AUN = tsGenerationData.unitCount; auto& FOD = preproData.data[Data::PreproAvailability::foDuration]; @@ -219,13 +218,13 @@ void GeneratorTempData::generateTS(const Data::Area& area, auto& NPOmax = preproData.data[Data::PreproAvailability::npoMax]; - double f_volatility = cluster.forcedVolatility; + double f_volatility = tsGenerationData.forcedVolatility; - double p_volatility = cluster.plannedVolatility; + double p_volatility = tsGenerationData.plannedVolatility; - auto f_law = cluster.forcedLaw; + auto f_law = tsGenerationData.forcedLaw; - auto p_law = cluster.plannedLaw; + auto p_law = tsGenerationData.plannedLaw; std::vector> FPOW(DAYS_PER_YEAR); std::vector> PPOW(DAYS_PER_YEAR); @@ -247,8 +246,8 @@ void GeneratorTempData::generateTS(const Data::Area& area, for (uint d = 0; d < DAYS_PER_YEAR; ++d) { - FPOW[d].resize(cluster.unitCount + 1); - PPOW[d].resize(cluster.unitCount + 1); + FPOW[d].resize(tsGenerationData.unitCount + 1); + PPOW[d].resize(tsGenerationData.unitCount + 1); PODOfTheDay = (int)POD[d]; FODOfTheDay = (int)FOD[d]; @@ -281,7 +280,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, pp[d] = lp[d] / b; } - for (uint k = 0; k != cluster.unitCount + 1; ++k) + for (uint k = 0; k != tsGenerationData.unitCount + 1; ++k) { FPOW[d][k] = pow(a, (double)k); PPOW[d][k] = pow(b, (double)k); @@ -313,7 +312,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, double cumul = 0; double last = 0; - auto& modulation = cluster.modulationCapacity; + auto& modulation = tsGenerationData.modulationCapacity; double* dstSeries = nullptr; const uint tsCount = nbOfSeriesToGen_ + 2; @@ -323,7 +322,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, if (tsIndex > 1) { - dstSeries = cluster.series[tsIndex - 2]; + dstSeries = tsGenerationData.series[tsIndex - 2]; } for (uint dayInTheYear = 0; dayInTheYear < DAYS_PER_YEAR; ++dayInTheYear) @@ -498,7 +497,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, } } - if (cluster.unitCount == 1) + if (tsGenerationData.unitCount == 1) { if (POC == 1 && FOC == 1) { @@ -568,7 +567,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, } NOW = (NOW + 1) % Log_size; - AVP[dayInTheYear] = AUN * cluster.nominalCapacity; + AVP[dayInTheYear] = AUN * tsGenerationData.nominalCapacity; if (tsIndex > 1) { @@ -584,7 +583,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, if (derated) { - cluster.series.averageTimeseries(); + tsGenerationData.series.averageTimeseries(); } } } // namespace @@ -609,23 +608,6 @@ std::vector getAllClustersToGen(const Data::AreaList& are return clusters; } -listOfLinks getAllLinksToGen(Data::AreaList& areas) -{ - listOfLinks links; - - areas.each( - [&links](const Data::Area& area) - { - std::ranges::for_each(area.links, [&links](auto& l) - { - if (!l.second->tsGeneration.forceNoGeneration) - links.push_back(l.second); - }); - }); - - return links; -} - void writeResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, const Matrix<>& series, @@ -641,6 +623,20 @@ void writeResultsToDisk(const Data::Study& study, writer.addEntryFromBuffer(savePath, buffer); } +void writeResultsToDisk(const Matrix<>& series, + const std::filesystem::path savePath) +{ + std::string buffer; + series.saveToBuffer(buffer, 0); + + std::filesystem::path parentDir = savePath.parent_path(); + if (! std::filesystem::exists(parentDir)) + { + std::filesystem::create_directories(parentDir); + } + Antares::IO::fileSetContent(savePath.string(), buffer); +} + bool generateThermalTimeSeries(Data::Study& study, const std::vector& clusters, Solver::IResultWriter& writer, @@ -655,13 +651,12 @@ bool generateThermalTimeSeries(Data::Study& study, study.parameters.nbTimeSeriesThermal, study.runtime->random[Data::seedTsGenThermal]); - // TODO VP: parallel for (auto* cluster: clusters) { - AvailabilityTSGeneratorData tsConfigData(cluster); - generator.generateTS(*cluster->parentArea, tsConfigData); + AvailabilityTSGeneratorData tsGenerationData(cluster); + generator.generateTS(tsGenerationData); - if (archive) // compatibilty with in memory + if (archive) // For compatibilty with in memory thermal TS generation { std::string filePath = savePath + SEP + cluster->parentArea->id + SEP + cluster->id() + ".txt"; @@ -672,48 +667,49 @@ bool generateThermalTimeSeries(Data::Study& study, return true; } -bool generateLinkTimeSeries(Data::Study& study, - const listOfLinks& links, - Solver::IResultWriter& writer, +// gp : we should try to add const identifiers before args here +bool generateLinkTimeSeries(std::vector& links, + StudyParamsForLinkTS& generalParams, const std::string& savePath) { logs.info(); - logs.info() << "Generating the links time-series"; - - auto generator = GeneratorTempData(study, - study.parameters.nbLinkTStoGenerate, - study.runtime->random[Data::seedTsGenLinks]); + logs.info() << "Generation of links time-series"; - for (const auto& link: links) + auto generator = GeneratorTempData(generalParams.derated, + generalParams.nbLinkTStoGenerate, + generalParams.random); + for (auto& link: links) { - Data::TimeSeries ts(link->timeseriesNumbers); - ts.resize(study.parameters.nbLinkTStoGenerate, HOURS_PER_YEAR); - - auto& tsGenStruct = link->tsGeneration; - - if (!tsGenStruct.valid) + if (! link.hasValidData) { - logs.error() << "Missing data for link " << link->from->id << "/" << link->with->id; + logs.error() << "Missing data for link " << link.namesPair.first << "/" << link.namesPair.second; return false; } + if (link.forceNoGeneration) + continue; // Skipping the link + + Data::TimeSeriesNumbers fakeTSnumbers; // gp : to quickly get rid of + Data::TimeSeries ts(fakeTSnumbers); + ts.resize(generalParams.nbLinkTStoGenerate, HOURS_PER_YEAR); + // DIRECT - AvailabilityTSGeneratorData tsConfigDataDirect(tsGenStruct, ts, tsGenStruct.modulationCapacityDirect, link->with->name); + AvailabilityTSGeneratorData tsConfigDataDirect(link, ts, link.modulationCapacityDirect, link.namesPair.second); - generator.generateTS(*link->from, tsConfigDataDirect); + generator.generateTS(tsConfigDataDirect); - std::string filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + std::string filePath = savePath + SEP + link.namesPair.first + SEP + link.namesPair.second + "_direct.txt"; - writeResultsToDisk(study, writer, ts.timeSeries, filePath); + writeResultsToDisk(ts.timeSeries, filePath); // INDIRECT - AvailabilityTSGeneratorData tsConfigDataIndirect(tsGenStruct, ts, tsGenStruct.modulationCapacityIndirect, link->with->name); + AvailabilityTSGeneratorData tsConfigDataIndirect(link, ts, link.modulationCapacityIndirect, link.namesPair.second); - generator.generateTS(*link->from, tsConfigDataIndirect); + generator.generateTS(tsConfigDataIndirect); - filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + filePath = savePath + SEP + link.namesPair.first + SEP + link.namesPair.second + "_indirect.txt"; - writeResultsToDisk(study, writer, ts.timeSeries, filePath); + writeResultsToDisk(ts.timeSeries, filePath); } return true; diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 1c32e67bdd..8cddc50679 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -33,13 +33,50 @@ #include "xcast/xcast.h" +using LinkPair = std::pair; +using LinkPairs = std::vector; + namespace Antares::TSGenerator { + +struct StudyParamsForLinkTS +{ + unsigned int nbLinkTStoGenerate = 1; + bool derated = false; + // gp : we will have a problem with that if seed-tsgen-links not set in + // gp : generaldata.ini. In that case, our default value is wrong. + MersenneTwister random; +}; + +struct LinkTSgenerationParams +{ + LinkPair namesPair; + + unsigned unitCount = 0; + double nominalCapacity = 0; + + double forcedVolatility = 0.; + double plannedVolatility = 0.; + + Data::StatisticalLaw forcedLaw = Data::LawUniform; + Data::StatisticalLaw plannedLaw = Data::LawUniform; + + std::unique_ptr prepro; + + Matrix<> modulationCapacityDirect; + Matrix<> modulationCapacityIndirect; + + bool forceNoGeneration = false; + bool hasValidData = true; +}; + + class AvailabilityTSGeneratorData { public: explicit AvailabilityTSGeneratorData(Data::ThermalCluster*); - AvailabilityTSGeneratorData(Data::LinkTsGeneration&, + + AvailabilityTSGeneratorData(LinkTSgenerationParams&, Data::TimeSeries&, Matrix<>& modulation, const std::string& name); @@ -77,15 +114,13 @@ bool generateThermalTimeSeries(Data::Study& study, Solver::IResultWriter& writer, const std::string& savePath); -bool generateLinkTimeSeries(Data::Study& study, - const listOfLinks& links, - Solver::IResultWriter& writer, +bool generateLinkTimeSeries(std::vector& links, + StudyParamsForLinkTS&, const std::string& savePath); std::vector getAllClustersToGen(const Data::AreaList& areas, bool globalThermalTSgeneration); -listOfLinks getAllLinksToGen(Data::AreaList& areas); /*! ** \brief Destroy all TS Generators diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index ac36a826ea..4d93f56f8a 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -114,28 +114,6 @@ class PreproAvailability YString id; unsigned int unitCount; }; // class PreproAvailability - -struct LinkTsGeneration -{ - unsigned unitCount = 0; - double nominalCapacity = 0; - - double forcedVolatility = 0.; - double plannedVolatility = 0.; - - Data::StatisticalLaw forcedLaw = LawUniform; - Data::StatisticalLaw plannedLaw = LawUniform; - - std::unique_ptr prepro; - - Matrix<> modulationCapacityDirect; - Matrix<> modulationCapacityIndirect; - - bool valid = false; - - bool forceNoGeneration = false; -}; - } // namespace Antares::Data #endif // __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_HXX__ diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 8f23f60619..60ad9dd720 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -36,6 +37,7 @@ #include using namespace Antares; +using namespace Antares::TSGenerator; namespace fs = std::filesystem; @@ -111,28 +113,311 @@ std::vector getClustersToGen(Data::AreaList& areas, return clusters; } -TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, const std::string& linksToGen) +// ===== New code for TS generation links ==================================== + +std::vector extractTargetAreas(fs::path sourceLinkDir) +{ + std::vector to_return; + fs::path pathToIni = sourceLinkDir / "properties.ini"; + IniFile ini; + ini.open(pathToIni); // gp : we should handle reading issues + for (auto* s = ini.firstSection; s; s = s->next) + { + std::string targetAreaName = transformNameIntoID(s->name); + to_return.push_back(targetAreaName); + } + return to_return; +} + +LinkPairs extractLinkNamesFromStudy(fs::path studyDir) +{ + LinkPairs to_return; + fs::path linksDir = studyDir / "input" / "links"; + for (auto const& item : fs::directory_iterator{linksDir}) + { + if (item.is_directory()) + { + std::string sourceAreaName = item.path().filename().generic_string(); + auto targetAreas = extractTargetAreas(item); + for (auto& targetAreaName : targetAreas) + { + auto linkPair = std::make_pair(sourceAreaName, targetAreaName); + to_return.push_back(linkPair); + } + } + } + return to_return; +} + +bool pairs_match(const LinkPair& p1, const LinkPair& p2) { - TSGenerator::listOfLinks links; - const auto ids = splitStringIntoPairs(linksToGen, ';', '.'); + return (p1.first == p2.first && p1.second == p2.second) + || (p1.first == p2.second && p1.second == p2.first); +} - for (const auto& [areaFromID, areaWithID]: ids) +const LinkPair* getMatchingPairInCollection(const LinkPair& pair, const LinkPairs& collection) +{ + for(const auto& p : collection) { - logs.info() << "Searching for link: " << areaFromID << "/" << areaWithID; + if (pairs_match(pair, p)) + return &p; + } + return nullptr; +} - auto* link = areas.findLink(areaFromID, areaWithID); - if (!link) +LinkPairs extractLinkNamesFromCmdLine(const LinkPairs& allLinks, + const std::string linksFromCmdLine) +{ + LinkPairs to_return; + LinkPairs pairsFromCmdLine = splitStringIntoPairs(linksFromCmdLine, ';', '.'); + for (auto& p : pairsFromCmdLine) + { + if (const auto* found_pair = getMatchingPairInCollection(p, allLinks); found_pair) + { + to_return.push_back(*found_pair); + } + else { - logs.warning() << "Link not found: " << areaFromID << "/" << areaWithID; + logs.error() << "Link '" << p.first << "." << p.second << "' not found"; + } + } + return to_return; +} + +bool readLinkGeneralProperty(StudyParamsForLinkTS& params, + const Yuni::String& key, + const Yuni::String& value) +{ + if (key == "derated") + { + return value.to(params.derated); + } + if (key == "nbtimeserieslinks") + { + return value.to(params.nbLinkTStoGenerate); + } + if (key == "seed-tsgen-links") + { + unsigned int seed {0}; + if (! value.to(seed)) + return false; + params.random.reset(seed); + return true; + } + return true; // gp : should we return true here ? +} + +StudyParamsForLinkTS readGeneralParamsForLinksTS(fs::path studyDir) +{ + StudyParamsForLinkTS to_return; + fs::path pathToGeneraldata = studyDir / "settings" / "generaldata.ini"; + IniFile ini; + ini.open(pathToGeneraldata); // gp : we should handle reading issues + for (auto* section = ini.firstSection; section; section = section->next) + { + // Skipping sections useless in the current context + Yuni::String sectionName = section->name; + if (sectionName != "general" && sectionName != "seeds - Mersenne Twister") continue; + + for (const IniFile::Property* p = section->firstProperty; p; p = p->next) + { + if (! readLinkGeneralProperty(to_return, p->key, p->value)) + { + logs.warning() << ini.filename() << ": reading value of '" + << p->key << "' went wrong"; + } } + } + return to_return; +} - links.emplace_back(link); +std::vector CreateLinkList(const LinkPairs& linksFromCmdLine) +{ + std::vector to_return; + to_return.reserve(linksFromCmdLine.size()); + for (const auto& link_pair : linksFromCmdLine) + { + LinkTSgenerationParams params; + params.namesPair = link_pair; + to_return.push_back(std::move(params)); } + return to_return; +} - return links; +LinkTSgenerationParams* findLinkInList(const LinkPair& link_to_find, + std::vector& linkList) +{ + for(auto& link : linkList) + { + if (link.namesPair == link_to_find) + return &link; + } + return nullptr; } +bool readLinkIniProperty(LinkTSgenerationParams* link, + const Yuni::String& key, + const Yuni::String& value) +{ + if (key == "unitcount") + { + return value.to(link->unitCount); + } + + if (key == "nominalcapacity") + { + return value.to(link->nominalCapacity); + } + + if (key == "law.planned") + { + return value.to(link->plannedLaw); + } + + if (key == "law.forced") + { + return value.to(link->forcedLaw); + } + + if (key == "volatility.planned") + { + return value.to(link->plannedVolatility); + } + + if (key == "volatility.forced") + { + return value.to(link->forcedVolatility); + } + + if (key == "force-no-generation") + { + return value.to(link->forceNoGeneration); + } + return true; +} + +void readLinkIniProperties(LinkTSgenerationParams* link, + IniFile::Section* section) +{ + for (const IniFile::Property* p = section->firstProperty; p; p = p->next) + { + if (! readLinkIniProperty(link, p->key, p->value)) + { + std::string linkName = link->namesPair.first + "." + link->namesPair.second; + logs.warning() << "Link '" << linkName << "' : reading value of '" + << p->key << "' went wrong"; + link->hasValidData = false; + } + } +} + +void readSourceAreaIniFile(fs::path pathToIni, + std::string sourceAreaName, + std::vector& linkList) +{ + IniFile ini; + ini.open(pathToIni); // gp : we should handle reading issues + for (auto* section = ini.firstSection; section; section = section->next) + { + std::string targetAreaName = transformNameIntoID(section->name); + const LinkPair processedLink = std::make_pair(sourceAreaName, targetAreaName); + if (auto* foundLink = findLinkInList(processedLink, linkList); foundLink) + { + readLinkIniProperties(foundLink, section); + } + } +} + +void readIniProperties(std::vector& linkList, fs::path toLinksDir) +{ + for(auto& link : linkList) + { + std::string sourceAreaName = link.namesPair.first; + fs::path pathToIni = toLinksDir / sourceAreaName / "properties.ini"; + readSourceAreaIniFile(pathToIni, sourceAreaName, linkList); + } +} + +bool readLinkPreproTimeSeries(LinkTSgenerationParams& link, + fs::path sourceAreaDir) +{ + bool to_return = true; + const auto preproId = link.namesPair.first + "/" + link.namesPair.second; + link.prepro = std::make_unique(preproId, link.unitCount); + + auto preproFileRoot = sourceAreaDir / "prepro" / link.namesPair.second; + + auto preproFile = preproFileRoot; + preproFile += ".txt"; + if (fs::exists(preproFile)) + { + to_return = link.prepro->data.loadFromCSVFile( + preproFile.string(), + Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && link.prepro->validate() + && to_return; + } + + auto modulationFileDirect = preproFileRoot; + modulationFileDirect += "_mod_direct.txt"; + if (fs::exists(modulationFileDirect)) + { + to_return = link.modulationCapacityDirect.loadFromCSVFile( + modulationFileDirect.string(), + 1, + HOURS_PER_YEAR) + && to_return; + } + + auto modulationFileIndirect = preproFileRoot; + modulationFileIndirect += "_mod_indirect.txt"; + if (fs::exists(modulationFileIndirect)) + { + to_return = link.modulationCapacityIndirect.loadFromCSVFile( + modulationFileIndirect.string(), + 1, + HOURS_PER_YEAR) + && to_return; + } + // Makes possible a skip of TS generation when time comes + link.hasValidData = link.hasValidData && to_return; + return to_return; +} + +void readPreproTimeSeries(std::vector& linkList, + fs::path toLinksDir) +{ + for(auto& link : linkList) + { + std::string sourceAreaName = link.namesPair.first; + fs::path sourceAreaDir = toLinksDir / sourceAreaName; + if (! readLinkPreproTimeSeries(link, sourceAreaDir)) + { + logs.warning() << "Could not load all prepro data for link '" + << link.namesPair.first << "." << link.namesPair.second << "'"; + } + } +} + +void readLinksSpecificTSparameters(std::vector& linkList, + fs::path studyFolder) +{ + fs::path toLinksDir = studyFolder / "input" / "links"; + readIniProperties(linkList, toLinksDir); + readPreproTimeSeries(linkList, toLinksDir); +} + +std::string DateAndTime() +{ + YString to_return; + unsigned int now = Yuni::DateTime::Now(); + Yuni::DateTime::TimestampToString(to_return, "%Y%m%d-%H%M", now); + return to_return.to(); +} +// ============================================================================ + int main(int argc, char* argv[]) { logs.applicationName("ts-generator"); @@ -168,7 +453,6 @@ int main(int argc, char* argv[]) auto study = std::make_shared(true); Data::StudyLoadOptions studyOptions; studyOptions.prepareOutput = true; - studyOptions.linksLoadTSGen = true; if (!study->loadFromFolder(settings.studyFolder, studyOptions)) { @@ -197,9 +481,8 @@ int main(int argc, char* argv[]) durationCollector); const auto thermalSavePath = fs::path("ts-generator") / "thermal"; - const auto linksSavePath = fs::path("ts-generator") / "links"; - // THERMAL + // ============ THERMAL : Getting data for generating time-series ========= std::vector clusters; if (settings.allThermal) { @@ -215,28 +498,31 @@ int main(int argc, char* argv[]) logs.debug() << c->id(); } - // LINKS - TSGenerator::listOfLinks links; + // ============ LINKS : Getting data for generating LINKS time-series ===== + auto allLinksPairs = extractLinkNamesFromStudy(settings.studyFolder); + auto linksFromCmdLine = extractLinkNamesFromCmdLine(allLinksPairs, + settings.linksListToGen); if (settings.allLinks) - { - links = TSGenerator::getAllLinksToGen(study->areas); - } - else if (!settings.linksListToGen.empty()) - { - links = getLinksToGen(study->areas, settings.linksListToGen); - } + linksFromCmdLine = allLinksPairs; - for (auto& l: links) - { - logs.debug() << l->getName(); - } + StudyParamsForLinkTS generalParams = readGeneralParamsForLinksTS(settings.studyFolder); + + std::vector linkList = CreateLinkList(linksFromCmdLine); + readLinksSpecificTSparameters(linkList, settings.studyFolder); + + auto saveLinksTSpath = fs::path(settings.studyFolder) / "output" / DateAndTime(); + saveLinksTSpath /= "ts-generator"; + saveLinksTSpath /= "links"; + + // ============ TS Generation ============================================= bool ret = TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath.string()); - ret = TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath.string()) + + ret = TSGenerator::generateLinkTimeSeries(linkList, generalParams, saveLinksTSpath.string()) && ret; return !ret; // return 0 for success -} +} \ No newline at end of file From a00b90a051570310e55cf8fa1e83f41af1bdccec Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:39:47 +0200 Subject: [PATCH 046/127] Perform hydro checks prior to the simulation [ANT-1720] (#2132) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Florian Omnès Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> Co-authored-by: payetvin <113102157+payetvin@users.noreply.github.com> Co-authored-by: Guillaume PIERRE Co-authored-by: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Co-authored-by: Milos A Co-authored-by: Milos <97689304+Milos-RTEi@users.noreply.github.com> Co-authored-by: NikolaIlic --- .../antares/study/parts/hydro/container.h | 55 +++ src/libs/antares/study/runtime/runtime.cpp | 1 + src/solver/application/CMakeLists.txt | 6 +- .../application/ScenarioBuilderOwner.cpp | 57 +++ src/solver/application/application.cpp | 4 +- .../application/ScenarioBuilderOwner.h | 44 +++ .../include/antares/application/application.h | 1 + src/solver/hydro/CMakeLists.txt | 9 + .../hydro/management/HydroInputsChecker.h | 62 ++++ .../hydro/management/MinGenerationScaling.h | 41 +++ .../solver/hydro/management/PrepareInflows.h | 43 +++ .../hydro-final-reservoir-level-functions.h | 6 +- .../solver/hydro/management/management.h | 104 ++---- .../hydro/management/HydroInputsChecker.cpp | 204 +++++++++++ .../hydro/management/MinGenerationScaling.cpp | 92 +++++ .../hydro/management/PrepareInflows.cpp | 86 +++++ src/solver/hydro/management/daily.cpp | 65 ++-- .../hydro-final-reservoir-level-functions.cpp | 69 ++++ src/solver/hydro/management/management.cpp | 331 ++---------------- src/solver/hydro/management/monthly.cpp | 100 +++--- src/solver/simulation/CMakeLists.txt | 2 - .../hydro-final-reservoir-level-functions.cpp | 68 ---- .../antares/solver/simulation/solver.h | 2 +- .../antares/solver/simulation/solver.hxx | 131 +++---- .../end-to-end/simple_study/simple-study.cpp | 3 +- src/tests/inmemory-study/CMakeLists.txt | 1 + src/tests/inmemory-study/in-memory-study.cpp | 5 +- .../src/solver/simulation/CMakeLists.txt | 2 + ...-hydro-final-reservoir-level-functions.cpp | 18 +- 29 files changed, 1013 insertions(+), 599 deletions(-) create mode 100644 src/solver/application/ScenarioBuilderOwner.cpp create mode 100644 src/solver/application/include/antares/application/ScenarioBuilderOwner.h create mode 100644 src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h create mode 100644 src/solver/hydro/include/antares/solver/hydro/management/MinGenerationScaling.h create mode 100644 src/solver/hydro/include/antares/solver/hydro/management/PrepareInflows.h rename src/solver/{simulation/include/antares/solver/simulation => hydro/include/antares/solver/hydro/management}/hydro-final-reservoir-level-functions.h (77%) create mode 100644 src/solver/hydro/management/HydroInputsChecker.cpp create mode 100644 src/solver/hydro/management/MinGenerationScaling.cpp create mode 100644 src/solver/hydro/management/PrepareInflows.cpp create mode 100644 src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp delete mode 100644 src/solver/simulation/hydro-final-reservoir-level-functions.cpp diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index 6748c830e7..9bece26ff3 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -29,6 +29,60 @@ namespace Antares::Data { + + //! The maximum number of days in a year +constexpr size_t dayYearCount = 366; + +struct DailyDemand +{ + //! Net demand, for each day of the year, for each area + double DLN = 0.; + //! Daily local effective load + double DLE = 0.; +}; + +struct MonthlyGenerationTargetData +{ + //! Monthly local effective demand + double MLE = 0.; + //! Monthly optimal generation + double MOG = 0.; + //! Monthly optimal level + double MOL = 0.; + //! Monthly target generations + double MTG = 0.; +}; + +//! Hydro Management Data for a given area +struct TimeDependantHydroManagementData +{ + std::array daily{0}; + std::array monthly{0}; +}; + +//! Area Hydro Management Data for a given year +struct AreaDependantHydroManagementData +{ + //! inflows + std::array inflows{}; + //! monthly minimal generation + std::array mingens{}; + + //! daily minimal generation + std::array dailyMinGen{}; + + // Data for minGen<->inflows preChecks + //! monthly total mingen + std::array totalMonthMingen{}; + //! monthly total inflows + std::array totalMonthInflows{}; + //! yearly total mingen + double totalYearMingen = 0; + //! yearly total inflows + double totalYearInflows = 0; + +}; // struct AreaDependantHydroManagementData + /*! ** \brief Hydro for a single area */ @@ -165,6 +219,7 @@ class PartHydro // which contains other time. Matrix dailyNbHoursAtGenPmax; Matrix dailyNbHoursAtPumpPmax; + std::unordered_map managementData; std::vector> deltaBetweenFinalAndInitialLevels; diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index 035faf86ac..1b093f4d2a 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -175,6 +175,7 @@ void StudyRuntimeInfos::initializeRangeLimits(const Study& study, StudyRangeLimi limits.month[rangeCount] = limits.month[rangeEnd] - limits.month[rangeBegin] + 1; // year limits.year[rangeBegin] = 0; + /// reminder to get rangeLimits.year[Data::rangeEnd] limits.year[rangeEnd] = study.parameters.nbYears - 1; limits.year[rangeCount] = study.parameters.effectiveNbYears; diff --git a/src/solver/application/CMakeLists.txt b/src/solver/application/CMakeLists.txt index 413e99543b..9f554a4b9f 100644 --- a/src/solver/application/CMakeLists.txt +++ b/src/solver/application/CMakeLists.txt @@ -1,10 +1,12 @@ set(HEADERS include/antares/application/application.h + include/antares/application/ScenarioBuilderOwner.h ) set(SRC_APPLICATION ${HEADERS} application.cpp process-priority.cpp + ScenarioBuilderOwner.cpp ) source_group("application" FILES ${SRC_APPLICATION}) @@ -29,10 +31,10 @@ target_link_libraries(application ) target_include_directories(application - PUBLIC + PUBLIC $ ) -install(DIRECTORY include/antares +install(DIRECTORY include/antares DESTINATION "include" ) \ No newline at end of file diff --git a/src/solver/application/ScenarioBuilderOwner.cpp b/src/solver/application/ScenarioBuilderOwner.cpp new file mode 100644 index 0000000000..ef6084fed5 --- /dev/null +++ b/src/solver/application/ScenarioBuilderOwner.cpp @@ -0,0 +1,57 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ + +#include +#include +#include "antares/solver/simulation/apply-scenario.h" +#include "antares/solver/simulation/timeseries-numbers.h" +#include "antares/solver/ts-generator/generator.h" +#include "antares/study/study.h" + +Antares::Solver::ScenarioBuilderOwner::ScenarioBuilderOwner(Data::Study& study): + study_(study) +{ +} + +void Antares::Solver::ScenarioBuilderOwner::callScenarioBuilder() { + TSGenerator::ResizeGeneratedTimeSeries(study_.areas, study_.parameters); + + // Sampled time-series Numbers + // We will resize all matrix related to the time-series numbers + // This operation can be done once since the number of years is constant + // for a single simulation + study_.resizeAllTimeseriesNumbers(1 + study_.runtime->rangeLimits.year[Data::rangeEnd]); + if (not TimeSeriesNumbers::CheckNumberOfColumns(study_.areas)) + { + throw FatalError( + "Inconsistent number of time-series detected. Please check your input data."); + } + + if (not TimeSeriesNumbers::Generate(study_)) + { + throw FatalError("An unrecoverable error has occurred. Can not continue."); + } + if (study_.parameters.useCustomScenario) + { + ApplyCustomScenario(study_); + } +} + diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index 90d5e559c5..4a47abd1ff 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -232,6 +233,8 @@ void Application::readDataForTheStudy(Data::StudyLoadOptions& options) // Apply transformations needed by the solver only (and not the interface for example) study.performTransformationsBeforeLaunchingSimulation(); + ScenarioBuilderOwner(study).callScenarioBuilder(); + // alloc global vectors SIM_AllocationTableaux(study); } @@ -256,7 +259,6 @@ void Application::startSimulation(Data::StudyLoadOptions& options) pStudy = std::make_unique(true /* for the solver */); pParameters = &(pStudy->parameters); - readDataForTheStudy(options); postParametersChecks(); diff --git a/src/solver/application/include/antares/application/ScenarioBuilderOwner.h b/src/solver/application/include/antares/application/ScenarioBuilderOwner.h new file mode 100644 index 0000000000..f536737be0 --- /dev/null +++ b/src/solver/application/include/antares/application/ScenarioBuilderOwner.h @@ -0,0 +1,44 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +namespace Antares +{ +namespace Data +{ +class Study; +} + +namespace Solver +{ + +class ScenarioBuilderOwner +{ +public: + explicit ScenarioBuilderOwner(Antares::Data::Study& study); + + void callScenarioBuilder(); + +private: + Antares::Data::Study& study_; +}; +} // namespace Solver +} // namespace Antares diff --git a/src/solver/application/include/antares/application/application.h b/src/solver/application/include/antares/application/application.h index 788aff68e9..be114f2d88 100644 --- a/src/solver/application/include/antares/application/application.h +++ b/src/solver/application/include/antares/application/application.h @@ -130,5 +130,6 @@ class Application final: public Yuni::IEventObserver. +*/ +#pragma once +#include +#include "antares/date/date.h" +#include "antares/solver/hydro/management/MinGenerationScaling.h" +#include "antares/solver/hydro/management/PrepareInflows.h" +#include "antares/study/study.h" +namespace Antares +{ + +class HydroInputsChecker +{ +public: + explicit HydroInputsChecker(Antares::Data::Study& study); + void Execute(uint year); + +private: + Data::AreaList& areas_; + const Data::Parameters& parameters_; + const Date::Calendar& calendar_; + Data::SimulationMode simulationMode_; + const uint firstYear_; + const uint endYear_; + PrepareInflows prepareInflows_; + MinGenerationScaling minGenerationScaling_; + const Data::TimeSeries::TS& scenarioInitialHydroLevels_; + const Data::TimeSeries::TS& scenarioFinalHydroLevels_; + + //! return false if checkGenerationPowerConsistency or checkMinGeneration returns false + bool checkMonthlyMinGeneration(uint year, const Data::Area& area) const; + //! check Yearly minimum generation is lower than available inflows + bool checkYearlyMinGeneration(uint year, const Data::Area& area) const; + //! check Weekly minimum generation is lower than available inflows + bool checkWeeklyMinGeneration(uint year, const Data::Area& area) const; + //! check Hourly minimum generation is lower than available inflows + bool checkGenerationPowerConsistency(uint year) const; + //! return false if checkGenerationPowerConsistency or checkMinGeneration returns false + bool checksOnGenerationPowerBounds(uint year) const; + //! check minimum generation is lower than available inflows + bool checkMinGeneration(uint year) const; +}; + +} // namespace Antares diff --git a/src/solver/hydro/include/antares/solver/hydro/management/MinGenerationScaling.h b/src/solver/hydro/include/antares/solver/hydro/management/MinGenerationScaling.h new file mode 100644 index 0000000000..31feb6fa53 --- /dev/null +++ b/src/solver/hydro/include/antares/solver/hydro/management/MinGenerationScaling.h @@ -0,0 +1,41 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include +#include "antares/date/date.h" + +namespace Antares +{ + +//! Prepare minimum generation scaling for each area +class MinGenerationScaling +{ +public: + MinGenerationScaling(Data::AreaList& areas, const Date::Calendar& calendar); + void Run(uint year); + +private: + Data::AreaList& areas_; + const Date::Calendar& calendar_; +}; + +} // namespace Antares diff --git a/src/solver/hydro/include/antares/solver/hydro/management/PrepareInflows.h b/src/solver/hydro/include/antares/solver/hydro/management/PrepareInflows.h new file mode 100644 index 0000000000..79b7eae0a5 --- /dev/null +++ b/src/solver/hydro/include/antares/solver/hydro/management/PrepareInflows.h @@ -0,0 +1,43 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once +#include +#include "antares/date/date.h" + +namespace Antares +{ + +//! Prepare inflows scaling for each area +class PrepareInflows +{ +public: + PrepareInflows(Data::AreaList& areas, const Date::Calendar& calendar); + void Run(uint year); + +private: + void LoadInflows(uint year); + //! prepare data for Final reservoir level + void ChangeInflowsToAccommodateFinalLevels(uint year); + Data::AreaList& areas_; + const Date::Calendar& calendar_; +}; + +} // namespace Antares diff --git a/src/solver/simulation/include/antares/solver/simulation/hydro-final-reservoir-level-functions.h b/src/solver/hydro/include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h similarity index 77% rename from src/solver/simulation/include/antares/solver/simulation/hydro-final-reservoir-level-functions.h rename to src/solver/hydro/include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h index 4b60c4cc8f..9ded556947 100644 --- a/src/solver/simulation/include/antares/solver/simulation/hydro-final-reservoir-level-functions.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h @@ -31,7 +31,11 @@ namespace Antares::Solver { -void CheckFinalReservoirLevelsConfiguration(const Data::Study& study); +void CheckFinalReservoirLevelsConfiguration(Data::AreaList& areas, + const Data::Parameters& parameters, + const Data::TimeSeries::TS& scenarioInitialHydroLevels, + const Data::TimeSeries::TS& scenarioFinalHydroLevels, + uint year); } // namespace Antares::Solver #endif // __SOLVER_SIMULATION_HYDRO_FINAL_RESERVOIR_PRE_CHECKS_H__ diff --git a/src/solver/hydro/include/antares/solver/hydro/management/management.h b/src/solver/hydro/include/antares/solver/hydro/management/management.h index b642e441c2..7d8f5360c5 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -47,49 +47,6 @@ double GammaVariable(double a, MersenneTwister& random); } // namespace Solver -enum -{ - //! The maximum number of days in a year - dayYearCount = 366 -}; - -//! Temporary data -struct TmpDataByArea -{ - //! Monthly local effective demand - double MLE[12]; - //! Monthly optimal generation - double MOG[12]; - //! Monthly optimal level - double MOL[12]; - //! Monthly target generations - double MTG[12]; - //! inflows - double inflows[12]; - //! monthly minimal generation - std::array mingens; - - //! Net demand, for each day of the year, for each area - double DLN[dayYearCount]; - //! Daily local effective load - double DLE[dayYearCount]; - //! Daily optimized Generation - double DOG[dayYearCount]; - //! daily minimal generation - std::array dailyMinGen; - - // Data for minGen<->inflows preChecks - //! monthly total mingen - std::array totalMonthMingen; - //! monthly total inflows - std::array totalMonthInflows; - //! yearly total mingen - double totalYearMingen; - //! yearly total inflows - double totalYearInflows; - -}; // struct TmpDataByArea - typedef struct { std::vector HydrauliqueModulableQuotidien; /* indice par jour */ @@ -100,6 +57,8 @@ typedef struct } VENTILATION_HYDRO_RESULTS_BY_AREA; using HYDRO_VENTILATION_RESULTS = std::vector; +using HydroSpecificMap = std::unordered_map; class HydroManagement final { @@ -120,47 +79,42 @@ class HydroManagement final } private: - //! Prepare inflows scaling for each area - void prepareInflowsScaling(uint year); - //! prepare data for Final reservoir level - void changeInflowsToAccommodateFinalLevels(uint yearIndex); - //! Prepare minimum generation scaling for each area - void minGenerationScaling(uint year); - //! check Monthly minimum generation is lower than available inflows - bool checkMonthlyMinGeneration(uint year, const Data::Area& area) const; - //! check Yearly minimum generation is lower than available inflows - bool checkYearlyMinGeneration(uint year, const Data::Area& area) const; - //! check Weekly minimum generation is lower than available inflows - bool checkWeeklyMinGeneration(uint year, const Data::Area& area) const; - //! check Hourly minimum generation is lower than available inflows - bool checkGenerationPowerConsistency(uint year) const; - //! return false if checkGenerationPowerConsistency or checkMinGeneration returns false - bool checksOnGenerationPowerBounds(uint year) const; - //! check minimum generation is lower than available inflows - bool checkMinGeneration(uint year) const; //! Prepare the net demand for each area - void prepareNetDemand(uint year, - Data::SimulationMode mode, - const Antares::Data::Area::ScratchMap& scratchmap); + void prepareNetDemand( + uint year, + Data::SimulationMode mode, + const Antares::Data::Area::ScratchMap& scratchmap, + HydroSpecificMap& hydro_specific_map); //! Prepare the effective demand for each area - void prepareEffectiveDemand(); + void prepareEffectiveDemand( + uint year, + HydroSpecificMap& hydro_specific_map); //! Monthly Optimal generations - void prepareMonthlyOptimalGenerations(double* random_reservoir_level, uint y); + void prepareMonthlyOptimalGenerations( + double* random_reservoir_level, + uint y, + HydroSpecificMap& hydro_specific_map); //! Monthly target generations // note: inflows may have two different types, if in swap mode or not // \return The total inflow for the whole year - double prepareMonthlyTargetGenerations(Data::Area& area, TmpDataByArea& data); - - void prepareDailyOptimalGenerations(uint y, - Antares::Data::Area::ScratchMap& scratchmap); - - void prepareDailyOptimalGenerations(Data::Area& area, - uint y, - Antares::Data::Area::ScratchMap& scratchmap); + double prepareMonthlyTargetGenerations( + Data::Area& area, + Antares::Data::AreaDependantHydroManagementData& data, + Antares::Data::TimeDependantHydroManagementData& hydro_specific); + + void prepareDailyOptimalGenerations( + uint y, + Antares::Data::Area::ScratchMap& scratchmap, + HydroSpecificMap& hydro_specific_map); + + void prepareDailyOptimalGenerations( + Data::Area& area, + uint y, + Antares::Data::Area::ScratchMap& scratchmap, + Antares::Data::TimeDependantHydroManagementData& hydro_specific); private: - std::unordered_map tmpDataByArea_; const Data::AreaList& areas_; const Date::Calendar& calendar_; const Data::Parameters& parameters_; diff --git a/src/solver/hydro/management/HydroInputsChecker.cpp b/src/solver/hydro/management/HydroInputsChecker.cpp new file mode 100644 index 0000000000..613e760f74 --- /dev/null +++ b/src/solver/hydro/management/HydroInputsChecker.cpp @@ -0,0 +1,204 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#include "antares/solver/hydro/management/HydroInputsChecker.h" + +#include + +#include +#include "antares/antares/fatal-error.h" +#include "antares/solver/hydro/management/hydro-final-reservoir-level-functions.h" +#include "antares/solver/hydro/monthly/h2o_m_donnees_annuelles.h" +#include "antares/solver/hydro/monthly/h2o_m_fonctions.h" +#include "antares/solver/simulation/common-eco-adq.h" + +namespace Antares +{ + +HydroInputsChecker::HydroInputsChecker(Antares::Data::Study& study): + areas_(study.areas), + parameters_(study.parameters), + calendar_(study.calendar), + simulationMode_(study.runtime->mode), + firstYear_(0), + endYear_(1 + study.runtime->rangeLimits.year[Data::rangeEnd]), + prepareInflows_(study.areas, study.calendar), + minGenerationScaling_(study.areas, study.calendar), + scenarioInitialHydroLevels_(study.scenarioInitialHydroLevels), + scenarioFinalHydroLevels_(study.scenarioFinalHydroLevels) +{ +} + +void HydroInputsChecker::Execute(uint year) +{ + prepareInflows_.Run(year); + minGenerationScaling_.Run(year); + + if (!checksOnGenerationPowerBounds(year)) + { + throw FatalError("hydro inputs checks: invalid minimum generation"); + } + if (parameters_.useCustomScenario) + { + CheckFinalReservoirLevelsConfiguration(areas_, parameters_, scenarioInitialHydroLevels_, scenarioFinalHydroLevels_, year); + } +} + +bool HydroInputsChecker::checksOnGenerationPowerBounds(uint year) const +{ + return checkMinGeneration(year) && checkGenerationPowerConsistency(year); +} + +bool HydroInputsChecker::checkMinGeneration(uint year) const +{ + bool ret = true; + areas_.each( + [this, &ret, &year](const Data::Area& area) + { + bool useHeuristicTarget = area.hydro.useHeuristicTarget; + bool followLoadModulations = area.hydro.followLoadModulations; + bool reservoirManagement = area.hydro.reservoirManagement; + + if (!useHeuristicTarget) + { + return; + } + + if (!followLoadModulations) + { + ret = checkWeeklyMinGeneration(year, area) && ret; + return; + } + + if (reservoirManagement) + { + ret = checkYearlyMinGeneration(year, area) && ret; + } + else + { + ret = checkMonthlyMinGeneration(year, area) && ret; + } + }); + return ret; +} + +bool HydroInputsChecker::checkWeeklyMinGeneration(uint year, const Data::Area& area) const +{ + const auto& srcinflows = area.hydro.series->storage.getColumn(year); + const auto& srcmingen = area.hydro.series->mingen.getColumn(year); + // Weekly minimum generation <= Weekly inflows for each week + for (uint week = 0; week < calendar_.maxWeeksInYear - 1; ++week) + { + double totalWeekMingen = 0.0; + double totalWeekInflows = 0.0; + for (uint hour = calendar_.weeks[week].hours.first; + hour < calendar_.weeks[week].hours.end && hour < HOURS_PER_YEAR; + ++hour) + { + totalWeekMingen += srcmingen[hour]; + } + + for (uint day = calendar_.weeks[week].daysYear.first; + day < calendar_.weeks[week].daysYear.end; + ++day) + { + totalWeekInflows += srcinflows[day]; + } + if (totalWeekMingen > totalWeekInflows) + { + logs.error() << "In Area " << area.name << " the minimum generation of " + << totalWeekMingen << " MW in week " << week + 1 << " of TS-" + << area.hydro.series->mingen.getSeriesIndex(year) + 1 + << " is incompatible with the inflows of " << totalWeekInflows << " MW."; + return false; + } + } + return true; +} + +bool HydroInputsChecker::checkYearlyMinGeneration(uint year, const Data::Area& area) const +{ + const auto& data = area.hydro.managementData.at(year); + if (data.totalYearMingen > data.totalYearInflows) + { + // Yearly minimum generation <= Yearly inflows + logs.error() << "In Area " << area.name << " the minimum generation of " + << data.totalYearMingen << " MW of TS-" + << area.hydro.series->mingen.getSeriesIndex(year) + 1 + << " is incompatible with the inflows of " << data.totalYearInflows << " MW."; + return false; + } + return true; +} + +bool HydroInputsChecker::checkMonthlyMinGeneration(uint year, const Data::Area& area) const +{ + const auto& data = area.hydro.managementData.at(year); + for (uint month = 0; month != 12; ++month) + { + uint realmonth = calendar_.months[month].realmonth; + // Monthly minimum generation <= Monthly inflows for each month + if (data.totalMonthMingen[realmonth] > data.totalMonthInflows[realmonth]) + { + logs.error() << "In Area " << area.name << " the minimum generation of " + << data.totalMonthMingen[realmonth] << " MW in month " << month + 1 + << " of TS-" << area.hydro.series->mingen.getSeriesIndex(year) + 1 + << " is incompatible with the inflows of " + << data.totalMonthInflows[realmonth] << " MW."; + return false; + } + } + return true; +} + +bool HydroInputsChecker::checkGenerationPowerConsistency(uint year) const +{ + bool ret = true; + + areas_.each( + [&ret, &year](const Data::Area& area) + { + const auto& srcmingen = area.hydro.series->mingen.getColumn(year); + const auto& srcmaxgen = area.hydro.series->maxHourlyGenPower.getColumn(year); + + const uint tsIndexMin = area.hydro.series->mingen.getSeriesIndex(year); + const uint tsIndexMax = area.hydro.series->maxHourlyGenPower.getSeriesIndex(year); + + for (uint h = 0; h < HOURS_PER_YEAR; ++h) + { + const auto& min = srcmingen[h]; + const auto& max = srcmaxgen[h]; + + if (max < min) + { + logs.error() << "In area: " << area.name << " [hourly] minimum generation of " + << min << " MW in timestep " << h + 1 << " of TS-" << tsIndexMin + 1 + << " is incompatible with the maximum generation of " << max + << " MW in timestep " << h + 1 << " of TS-" << tsIndexMax + 1 + << " MW."; + ret = false; + return; + } + } + }); + + return ret; +} +} // namespace Antares diff --git a/src/solver/hydro/management/MinGenerationScaling.cpp b/src/solver/hydro/management/MinGenerationScaling.cpp new file mode 100644 index 0000000000..08c9bf87d1 --- /dev/null +++ b/src/solver/hydro/management/MinGenerationScaling.cpp @@ -0,0 +1,92 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ + +#include "antares/solver/hydro/management/MinGenerationScaling.h" + +#include + +namespace Antares +{ +MinGenerationScaling::MinGenerationScaling(Data::AreaList& areas, const Date::Calendar& calendar): + areas_(areas), + calendar_(calendar) +{ +} + +void MinGenerationScaling::Run(uint year) +{ + areas_.each( + // un-const because now data is a member of area [&](const Data::Area& area) + [this, &year](Data::Area& area) + { + const auto& srcmingen = area.hydro.series->mingen.getColumn(year); + + auto& data = area.hydro.managementData[year]; + double totalYearMingen = 0.0; + + for (uint month = 0; month != 12; ++month) + { + uint realmonth = calendar_.months[month].realmonth; + uint firstDayOfMonth = calendar_.months[month].daysYear.first; + uint firstDayOfNextMonth = calendar_.months[month].daysYear.end; + + double totalMonthMingen = std::accumulate(srcmingen + firstDayOfMonth * 24, + srcmingen + firstDayOfNextMonth * 24, + 0.); + + data.totalMonthMingen[realmonth] = totalMonthMingen; + totalYearMingen += totalMonthMingen; + + if (!(area.hydro.reservoirCapacity < 1e-4)) + { + if (area.hydro.reservoirManagement) + { + // Set monthly mingen, used later for h2o_m + data.mingens[realmonth] = totalMonthMingen / (area.hydro.reservoirCapacity); + assert(!std::isnan(data.mingens[month]) && "nan value detect in mingen"); + } + else + { + data.mingens[realmonth] = totalMonthMingen; + } + } + else + { + data.mingens[realmonth] = totalMonthMingen; + } + + // Set daily mingen, used later for h2o_d + uint simulationMonth = calendar_.mapping.months[realmonth]; + auto daysPerMonth = calendar_.months[simulationMonth].days; + uint firstDay = calendar_.months[simulationMonth].daysYear.first; + uint endDay = firstDay + daysPerMonth; + + for (uint day = firstDay; day != endDay; ++day) + { + data.dailyMinGen[day] = std::accumulate(srcmingen + day * 24, + srcmingen + day * 24 + 24, + 0.); + } + } + data.totalYearMingen = totalYearMingen; + }); +} +} // namespace Antares diff --git a/src/solver/hydro/management/PrepareInflows.cpp b/src/solver/hydro/management/PrepareInflows.cpp new file mode 100644 index 0000000000..f1a43e71fd --- /dev/null +++ b/src/solver/hydro/management/PrepareInflows.cpp @@ -0,0 +1,86 @@ + +#include "antares/solver/hydro/management/PrepareInflows.h" + +namespace Antares +{ + +PrepareInflows::PrepareInflows(Data::AreaList& areas, const Date::Calendar& calendar): + areas_(areas), + calendar_(calendar) +{ +} + +void PrepareInflows::Run(uint year){ + LoadInflows(year); + ChangeInflowsToAccommodateFinalLevels(year); +} +void PrepareInflows::LoadInflows(uint year) +{ + areas_.each( + // un-const because now data is a member of area [&](const Data::Area& area) + [&](Data::Area& area) + { + const auto& srcinflows = area.hydro.series->storage.getColumn(year); + + auto& data = area.hydro.managementData[year]; + double totalYearInflows = 0.0; + + for (uint month = 0; month != 12; ++month) + { + uint realmonth = calendar_.months[month].realmonth; + + double totalMonthInflows = 0.0; + + uint firstDayOfMonth = calendar_.months[month].daysYear.first; + + uint firstDayOfNextMonth = calendar_.months[month].daysYear.end; + + for (uint d = firstDayOfMonth; d != firstDayOfNextMonth; ++d) + { + totalMonthInflows += srcinflows[d]; + } + + data.totalMonthInflows[realmonth] = totalMonthInflows; + totalYearInflows += totalMonthInflows; + + if (not(area.hydro.reservoirCapacity < 1e-4)) + { + if (area.hydro.reservoirManagement) + { + data.inflows[realmonth] = totalMonthInflows / (area.hydro.reservoirCapacity); + assert(!std::isnan(data.inflows[month]) && "nan value detect in inflows"); + } + else + { + data.inflows[realmonth] = totalMonthInflows; + } + } + else + { + data.inflows[realmonth] = totalMonthInflows; + } + } + data.totalYearInflows = totalYearInflows; + }); +} + +void PrepareInflows::ChangeInflowsToAccommodateFinalLevels(uint year) +{ + areas_.each([this, &year](Data::Area& area) + { + auto& data = area.hydro.managementData[year]; + + if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) + return; + + // Must be done before prepareMonthlyTargetGenerations + double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); + if (delta < 0) + data.inflows[0] -= delta; + else if (delta > 0) + data.inflows[11] -= delta; + }); +} + + +} // namespace Antares diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index f7e4665159..d1947d6d52 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -93,7 +93,7 @@ struct DebugData std::array previousMonthWaste{0}; Solver::IResultWriter& pWriter; - const TmpDataByArea& data; + const Antares::Data::AreaDependantHydroManagementData& data; const VENTILATION_HYDRO_RESULTS_BY_AREA& ventilationResults; const double* srcinflows; const MaxPowerType& maxP; @@ -102,15 +102,18 @@ struct DebugData const ReservoirLevelType& lowLevel; const double reservoirCapacity; + const Antares::Data::TimeDependantHydroManagementData& hydro_specific; + DebugData(Solver::IResultWriter& writer, - const TmpDataByArea& data, + const Antares::Data::AreaDependantHydroManagementData& data, const VENTILATION_HYDRO_RESULTS_BY_AREA& ventilationResults, const double* srcinflows, const MaxPowerType& maxP, const MaxPowerType& maxE, const double* dailyTargetGen, const ReservoirLevelType& lowLevel, - double reservoirCapacity): + double reservoirCapacity, + const Antares::Data::TimeDependantHydroManagementData& hydro_specific): pWriter(writer), data(data), ventilationResults(ventilationResults), @@ -119,7 +122,8 @@ struct DebugData maxE(maxE), dailyTargetGen(dailyTargetGen), lowLevel(lowLevel), - reservoirCapacity(reservoirCapacity) + reservoirCapacity(reservoirCapacity), + hydro_specific(hydro_specific) { OVF.fill(0); DEV.fill(0); @@ -141,7 +145,8 @@ struct DebugData { double value = ventilationResults.HydrauliqueModulableQuotidien[day]; buffer << day << '\t' << value << '\t' << OPP[day] << '\t' << DailyTargetGen[day] - << '\t' << data.DLE[day] << '\t' << data.DLN[day]; + << '\t' << hydro_specific.daily[day].DLE << '\t' + << hydro_specific.daily[day].DLN; buffer << '\n'; } auto buffer_str = buffer.str(); @@ -157,7 +162,7 @@ struct DebugData path << "debug" << SEP << "solver" << SEP << (1 + y) << SEP << "daily." << areaName.c_str() << ".txt"; - buffer << "\tNiveau init : " << data.MOL[initReservoirLvlMonth] << "\n"; + buffer << "\tNiveau init : " << hydro_specific.monthly[initReservoirLvlMonth].MOL << "\n"; for (uint month = 0; month != 12; ++month) { uint realmonth = (initReservoirLvlMonth + month) % 12; @@ -202,9 +207,9 @@ struct DebugData buffer << '\t' << deviationMax[realmonth] * 100 << '\t' << '\t' << violationMax[realmonth] * 100 << '\t' << '\t' << WASTE[realmonth] * 100 << '\t' << CoutTotal[realmonth] << '\t' - << (data.MOG[realmonth] / reservoirCapacity) * 100 << '\t' << '\t' - << '\t' << '\t' << '\t' - << (data.MOG[realmonth] / reservoirCapacity + << (hydro_specific.monthly[realmonth].MOG / reservoirCapacity) * 100 + << '\t' << '\t' << '\t' << '\t' << '\t' + << (hydro_specific.monthly[realmonth].MOG / reservoirCapacity + previousMonthWaste[realmonth]) * 100; } @@ -219,13 +224,14 @@ struct DebugData }; inline void HydroManagement::prepareDailyOptimalGenerations( - Data::Area& area, - uint y, - Antares::Data::Area::ScratchMap& scratchmap) + Data::Area& area, + uint y, + Antares::Data::Area::ScratchMap& scratchmap, + Antares::Data::TimeDependantHydroManagementData& hydro_specific) { const auto srcinflows = area.hydro.series->storage.getColumn(y); - auto& data = tmpDataByArea_[&area]; + auto& data = area.hydro.managementData[y]; auto& scratchpad = scratchmap.at(&area); @@ -262,7 +268,8 @@ inline void HydroManagement::prepareDailyOptimalGenerations( maxE, dailyTargetGen, lowLevel, - reservoirCapacity); + reservoirCapacity, + hydro_specific); } for (uint month = 0; month != 12; ++month) @@ -317,9 +324,9 @@ inline void HydroManagement::prepareDailyOptimalGenerations( for (uint day = 0; day != daysPerMonth; ++day) { auto dYear = day + dayYear; - if (data.DLE[dYear] > demandMax) + if (hydro_specific.daily[dYear].DLE > demandMax) { - demandMax = data.DLE[dYear]; + demandMax = hydro_specific.daily[dYear].DLE; } } @@ -331,23 +338,24 @@ inline void HydroManagement::prepareDailyOptimalGenerations( for (uint day = 0; day != daysPerMonth; ++day) { auto dYear = day + dayYear; - coeff += std::pow(data.DLE[dYear] / demandMax, + coeff += std::pow(hydro_specific.daily[dYear].DLE / demandMax, area.hydro.interDailyBreakdown); } - coeff = data.MOG[realmonth] / coeff; + coeff = hydro_specific.monthly[realmonth].MOG / coeff; for (uint day = 0; day != daysPerMonth; ++day) { auto dYear = day + dayYear; dailyTargetGen[dYear] = coeff - * std::pow(data.DLE[dYear] / demandMax, + * std::pow(hydro_specific.daily[dYear].DLE + / demandMax, area.hydro.interDailyBreakdown); } } else { assert(daysPerMonth > 0); - double coeff = data.MOG[realmonth] / daysPerMonth; + double coeff = hydro_specific.monthly[realmonth].MOG / daysPerMonth; for (uint day = 0; day != daysPerMonth; ++day) { @@ -391,7 +399,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( DONNEES_MENSUELLES* problem = H2O_J_Instanciation(); H2O_J_AjouterBruitAuCout(*problem); problem->NombreDeJoursDuMois = (int)daysPerMonth; - problem->TurbineDuMois = data.MOG[realmonth]; + problem->TurbineDuMois = hydro_specific.monthly[realmonth].MOG; uint dayMonth = 0; for (uint day = firstDay; day != endDay; ++day) @@ -440,7 +448,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( else { - double monthInitialLevel = data.MOL[initReservoirLvlMonth]; + double monthInitialLevel = hydro_specific.monthly[initReservoirLvlMonth].MOL; double wasteFromPreviousMonth = 0.; Hydro_problem_costs h2o2_optim_costs(parameters_); @@ -466,7 +474,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( problem.NombreDeJoursDuMois = (int)daysPerMonth; - problem.TurbineDuMois = (data.MOG[realmonth] + wasteFromPreviousMonth) + problem.TurbineDuMois = (hydro_specific.monthly[realmonth].MOG + wasteFromPreviousMonth) / reservoirCapacity; problem.NiveauInitialDuMois = monthInitialLevel; problem.reservoirCapacity = reservoirCapacity; @@ -549,10 +557,13 @@ inline void HydroManagement::prepareDailyOptimalGenerations( } } -void HydroManagement::prepareDailyOptimalGenerations(uint y, - Antares::Data::Area::ScratchMap& scratchmap) +void HydroManagement::prepareDailyOptimalGenerations( + uint y, + Antares::Data::Area::ScratchMap& scratchmap, + HydroSpecificMap& hydro_specific_map) { - areas_.each([this, &scratchmap, &y](Data::Area& area) - { prepareDailyOptimalGenerations(area, y, scratchmap); }); + areas_.each( + [this, &scratchmap, &y, &hydro_specific_map](Data::Area& area) + { prepareDailyOptimalGenerations(area, y, scratchmap, hydro_specific_map[&area]); }); } } // namespace Antares diff --git a/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp b/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp new file mode 100644 index 0000000000..3aa1d7e426 --- /dev/null +++ b/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp @@ -0,0 +1,69 @@ +/* +** Copyright 2007-2023 RTE +** Authors: RTE-international / Redstork / Antares_Simulator Team +** +** This file is part of Antares_Simulator. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** There are special exceptions to the terms and conditions of the +** license as they are applied to this software. View the full text of +** the exceptions in file COPYING.txt in the directory of this software +** distribution +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Antares_Simulator. If not, see . +** +** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions +*/ + +#include "antares/solver/hydro/management/hydro-final-reservoir-level-functions.h" + +#include +#include "antares/study/parts/hydro/finalLevelValidator.h" + +namespace Antares::Solver +{ + +void CheckFinalReservoirLevelsConfiguration(Data::AreaList& areas, + const Data::Parameters& parameters, + const Data::TimeSeries::TS& scenarioInitialHydroLevels, + const Data::TimeSeries::TS& scenarioFinalHydroLevels, + uint year) +{ + if (!parameters.yearsFilter.at(year)) + return; + + areas.each([&areas, ¶meters, &scenarioInitialHydroLevels, &scenarioFinalHydroLevels, year](Data::Area &area) + { + double initialLevel = scenarioInitialHydroLevels.entry[area.index][year]; + double finalLevel = scenarioFinalHydroLevels.entry[area.index][year]; + + Data::FinalLevelValidator validator(area.hydro, + area.index, + area.name, + initialLevel, + finalLevel, + year, + parameters.simulationDays.end, + parameters.firstMonthInYear); + if (!validator.check()) + { + throw FatalError("hydro final level : infeasibility"); + } + if (validator.finalLevelFineForUse()) + { + area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; + } + }); +} // End function CheckFinalReservoirLevelsConfiguration + +} // namespace Antares::Solver diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 703235fc61..98b3b0b562 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -140,279 +140,22 @@ HydroManagement::HydroManagement(const Data::AreaList& areas, } } -void HydroManagement::prepareInflowsScaling(uint year) +void HydroManagement::prepareNetDemand( + uint year, + Data::SimulationMode mode, + const Antares::Data::Area::ScratchMap& scratchmap, + HydroSpecificMap& hydro_specific_map) { areas_.each( - [this, &year](const Data::Area& area) - { - const auto& srcinflows = area.hydro.series->storage.getColumn(year); - - auto& data = tmpDataByArea_[&area]; - double totalYearInflows = 0.0; - - for (uint month = 0; month != 12; ++month) - { - uint realmonth = calendar_.months[month].realmonth; - - double totalMonthInflows = 0.0; - - uint firstDayOfMonth = calendar_.months[month].daysYear.first; - - uint firstDayOfNextMonth = calendar_.months[month].daysYear.end; - - for (uint d = firstDayOfMonth; d != firstDayOfNextMonth; ++d) - { - totalMonthInflows += srcinflows[d]; - } - - data.totalMonthInflows[realmonth] = totalMonthInflows; - totalYearInflows += totalMonthInflows; - - if (not(area.hydro.reservoirCapacity < 1e-4)) - { - if (area.hydro.reservoirManagement) - { - data.inflows[realmonth] = totalMonthInflows / (area.hydro.reservoirCapacity); - assert(!std::isnan(data.inflows[month]) && "nan value detect in inflows"); - } - else - { - data.inflows[realmonth] = totalMonthInflows; - } - } - else - { - data.inflows[realmonth] = totalMonthInflows; - } - } - data.totalYearInflows = totalYearInflows; - }); -} - -void HydroManagement::minGenerationScaling(uint year) -{ - areas_.each( - [this, &year](const Data::Area& area) - { - const auto& srcmingen = area.hydro.series->mingen.getColumn(year); - - auto& data = tmpDataByArea_[&area]; - double totalYearMingen = 0.0; - - for (uint month = 0; month != 12; ++month) - { - uint realmonth = calendar_.months[month].realmonth; - uint firstDayOfMonth = calendar_.months[month].daysYear.first; - uint firstDayOfNextMonth = calendar_.months[month].daysYear.end; - - double totalMonthMingen = std::accumulate(srcmingen + firstDayOfMonth * 24, - srcmingen + firstDayOfNextMonth * 24, - 0.); - - data.totalMonthMingen[realmonth] = totalMonthMingen; - totalYearMingen += totalMonthMingen; - - if (!(area.hydro.reservoirCapacity < 1e-4)) - { - if (area.hydro.reservoirManagement) - { - // Set monthly mingen, used later for h2o_m - data.mingens[realmonth] = totalMonthMingen / (area.hydro.reservoirCapacity); - assert(!std::isnan(data.mingens[month]) && "nan value detect in mingen"); - } - else - { - data.mingens[realmonth] = totalMonthMingen; - } - } - else - { - data.mingens[realmonth] = totalMonthMingen; - } - - // Set daily mingen, used later for h2o_d - uint simulationMonth = calendar_.mapping.months[realmonth]; - auto daysPerMonth = calendar_.months[simulationMonth].days; - uint firstDay = calendar_.months[simulationMonth].daysYear.first; - uint endDay = firstDay + daysPerMonth; - - for (uint day = firstDay; day != endDay; ++day) - { - data.dailyMinGen[day] = std::accumulate(srcmingen + day * 24, - srcmingen + day * 24 + 24, - 0.); - } - } - data.totalYearMingen = totalYearMingen; - }); -} - -bool HydroManagement::checkMonthlyMinGeneration(uint year, const Data::Area& area) const -{ - const auto& data = tmpDataByArea_.at(&area); - for (uint month = 0; month != 12; ++month) - { - uint realmonth = calendar_.months[month].realmonth; - // Monthly minimum generation <= Monthly inflows for each month - if (data.totalMonthMingen[realmonth] > data.totalMonthInflows[realmonth]) - { - logs.error() << "In Area " << area.name << " the minimum generation of " - << data.totalMonthMingen[realmonth] << " MW in month " << month + 1 - << " of TS-" << area.hydro.series->mingen.getSeriesIndex(year) + 1 - << " is incompatible with the inflows of " - << data.totalMonthInflows[realmonth] << " MW."; - return false; - } - } - return true; -} - -bool HydroManagement::checkYearlyMinGeneration(uint year, const Data::Area& area) const -{ - const auto& data = tmpDataByArea_.at(&area); - if (data.totalYearMingen > data.totalYearInflows) - { - // Yearly minimum generation <= Yearly inflows - logs.error() << "In Area " << area.name << " the minimum generation of " - << data.totalYearMingen << " MW of TS-" - << area.hydro.series->mingen.getSeriesIndex(year) + 1 - << " is incompatible with the inflows of " << data.totalYearInflows << " MW."; - return false; - } - return true; -} - -bool HydroManagement::checkWeeklyMinGeneration(uint year, const Data::Area& area) const -{ - const auto& srcinflows = area.hydro.series->storage.getColumn(year); - const auto& srcmingen = area.hydro.series->mingen.getColumn(year); - // Weekly minimum generation <= Weekly inflows for each week - for (uint week = 0; week < calendar_.maxWeeksInYear - 1; ++week) - { - double totalWeekMingen = 0.0; - double totalWeekInflows = 0.0; - for (uint hour = calendar_.weeks[week].hours.first; - hour < calendar_.weeks[week].hours.end && hour < HOURS_PER_YEAR; - ++hour) - { - totalWeekMingen += srcmingen[hour]; - } - - for (uint day = calendar_.weeks[week].daysYear.first; - day < calendar_.weeks[week].daysYear.end; - ++day) - { - totalWeekInflows += srcinflows[day]; - } - if (totalWeekMingen > totalWeekInflows) - { - logs.error() << "In Area " << area.name << " the minimum generation of " - << totalWeekMingen << " MW in week " << week + 1 << " of TS-" - << area.hydro.series->mingen.getSeriesIndex(year) + 1 - << " is incompatible with the inflows of " << totalWeekInflows << " MW."; - return false; - } - } - return true; -} - -bool HydroManagement::checkGenerationPowerConsistency(uint year) const -{ - bool ret = true; - - areas_.each( - [&ret, &year](const Data::Area& area) - { - const auto& srcmingen = area.hydro.series->mingen.getColumn(year); - const auto& srcmaxgen = area.hydro.series->maxHourlyGenPower.getColumn(year); - - const uint tsIndexMin = area.hydro.series->mingen.getSeriesIndex(year); - const uint tsIndexMax = area.hydro.series->maxHourlyGenPower.getSeriesIndex(year); - - for (uint h = 0; h < HOURS_PER_YEAR; ++h) - { - const auto& min = srcmingen[h]; - const auto& max = srcmaxgen[h]; - - if (max < min) - { - logs.error() << "In area: " << area.name << " [hourly] minimum generation of " - << min << " MW in timestep " << h + 1 << " of TS-" << tsIndexMin + 1 - << " is incompatible with the maximum generation of " << max - << " MW in timestep " << h + 1 << " of TS-" << tsIndexMax + 1 - << " MW."; - ret = false; - return; - } - } - }); - - return ret; -} - -bool HydroManagement::checkMinGeneration(uint year) const -{ - bool ret = true; - areas_.each( - [this, &ret, &year](const Data::Area& area) - { - bool useHeuristicTarget = area.hydro.useHeuristicTarget; - bool followLoadModulations = area.hydro.followLoadModulations; - bool reservoirManagement = area.hydro.reservoirManagement; - - if (!useHeuristicTarget) - { - return; - } - - if (!followLoadModulations) - { - ret = checkWeeklyMinGeneration(year, area) && ret; - return; - } - - if (reservoirManagement) - { - ret = checkYearlyMinGeneration(year, area) && ret; - } - else - { - ret = checkMonthlyMinGeneration(year, area) && ret; - } - }); - return ret; -} - -void HydroManagement::changeInflowsToAccommodateFinalLevels(uint year) -{ - areas_.each([this, &year](Data::Area& area) - { - auto& data = tmpDataByArea_[&area]; - - if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) - return; - - // Must be done before prepareMonthlyTargetGenerations - double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); - if (delta < 0) - data.inflows[0] -= delta; - else if (delta > 0) - data.inflows[11] -= delta; - }); -} - -void HydroManagement::prepareNetDemand(uint year, Data::SimulationMode mode, - const Antares::Data::Area::ScratchMap& scratchmap) -{ - areas_.each( - [this, &year, &scratchmap, &mode](const Data::Area& area) + [this, &year, &scratchmap, &mode, &hydro_specific_map](Data::Area& area) { const auto& scratchpad = scratchmap.at(&area); const auto& rormatrix = area.hydro.series->ror; const auto* ror = rormatrix.getColumn(year); - auto& data = tmpDataByArea_[&area]; + auto& data = area.hydro.managementData[year]; + auto& hydro_specific = hydro_specific_map[&area]; const double* loadSeries = area.load.series.getColumn(year); const double* windSeries = area.wind.series.getColumn(year); const double* solarSeries = area.solar.series.getColumn(year); @@ -449,17 +192,20 @@ void HydroManagement::prepareNetDemand(uint year, Data::SimulationMode mode, assert(!std::isnan(netdemand) && "hydro management: NaN detected when calculating the net demande"); - data.DLN[dayYear] += netdemand; + hydro_specific.daily[dayYear].DLN += netdemand; } }); } -void HydroManagement::prepareEffectiveDemand() +void HydroManagement::prepareEffectiveDemand( + uint year, + HydroSpecificMap& hydro_specific_map) { areas_.each( - [this](Data::Area& area) + [this, &year, &hydro_specific_map](Data::Area& area) { - auto& data = tmpDataByArea_[&area]; + auto& data = area.hydro.managementData[year]; + auto& hydro_specific = hydro_specific_map[&area]; for (uint day = 0; day != 365; ++day) { @@ -470,18 +216,19 @@ void HydroManagement::prepareEffectiveDemand() double effectiveDemand = 0; // area.hydro.allocation is indexed by area index area.hydro.allocation.eachNonNull( - [this, &effectiveDemand, &day](unsigned areaIndex, double value) + [this, &effectiveDemand, &day, &hydro_specific_map](unsigned areaIndex, double value) { const auto* area = areas_.byIndex[areaIndex]; - effectiveDemand += tmpDataByArea_[area].DLN[day] * value; + effectiveDemand += hydro_specific_map[area].daily[day].DLN * value; }); assert(!std::isnan(effectiveDemand) && "nan value detected for effectiveDemand"); - data.DLE[day] += effectiveDemand; - data.MLE[realmonth] += effectiveDemand; + hydro_specific.daily[day].DLE += effectiveDemand; + hydro_specific.monthly[realmonth].MLE += effectiveDemand; - assert(not std::isnan(data.DLE[day]) && "nan value detected for DLE"); - assert(not std::isnan(data.MLE[realmonth]) && "nan value detected for DLE"); + assert(not std::isnan(hydro_specific.daily[day].DLE) && "nan value detected for DLE"); + assert(not std::isnan(hydro_specific.monthly[realmonth].MLE) + && "nan value detected for DLE"); } auto minimumYear = std::numeric_limits::infinity(); @@ -496,9 +243,9 @@ void HydroManagement::prepareEffectiveDemand() for (uint d = 0; d != daysPerMonth; ++d) { auto dYear = d + dayYear; - if (data.DLE[dYear] < minimumMonth) + if (hydro_specific.daily[dYear].DLE < minimumMonth) { - minimumMonth = data.DLE[dYear]; + minimumMonth = hydro_specific.daily[dYear].DLE; } } @@ -506,13 +253,13 @@ void HydroManagement::prepareEffectiveDemand() { for (uint d = 0; d != daysPerMonth; ++d) { - data.DLE[dayYear + d] -= minimumMonth - 1e-4; + hydro_specific.daily[dayYear + d].DLE -= minimumMonth - 1e-4; } } - if (data.MLE[realmonth] < minimumYear) + if (hydro_specific.monthly[realmonth].MLE < minimumYear) { - minimumYear = data.MLE[realmonth]; + minimumYear = hydro_specific.monthly[realmonth].MLE; } dayYear += daysPerMonth; @@ -522,34 +269,22 @@ void HydroManagement::prepareEffectiveDemand() { for (uint realmonth = 0; realmonth != 12; ++realmonth) { - data.MLE[realmonth] -= minimumYear - 1e-4; + hydro_specific.monthly[realmonth].MLE -= minimumYear - 1e-4; } } }); } -bool HydroManagement::checksOnGenerationPowerBounds(uint year) const -{ - return (checkMinGeneration(year) && checkGenerationPowerConsistency(year)) ? true : false; -} - void HydroManagement::makeVentilation(double* randomReservoirLevel, uint y, Antares::Data::Area::ScratchMap& scratchmap) { - prepareInflowsScaling(y); - minGenerationScaling(y); - if (!checksOnGenerationPowerBounds(y)) - { - throw FatalError("hydro management: invalid minimum generation"); - } - - changeInflowsToAccommodateFinalLevels(y); - prepareNetDemand(y, parameters_.mode, scratchmap); - prepareEffectiveDemand(); + HydroSpecificMap hydro_specific_map; + prepareNetDemand(y, parameters_.mode, scratchmap, hydro_specific_map); + prepareEffectiveDemand(y, hydro_specific_map); - prepareMonthlyOptimalGenerations(randomReservoirLevel, y); - prepareDailyOptimalGenerations(y, scratchmap); + prepareMonthlyOptimalGenerations(randomReservoirLevel, y, hydro_specific_map); + prepareDailyOptimalGenerations(y, scratchmap, hydro_specific_map); } } // namespace Antares diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index aa10b7c10e..5804782531 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -82,7 +82,10 @@ static void CheckHydroAllocationProblem(Data::Area& area, } } -double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, TmpDataByArea& data) +double HydroManagement::prepareMonthlyTargetGenerations( + Data::Area& area, + Antares::Data::AreaDependantHydroManagementData& data, + Antares::Data::TimeDependantHydroManagementData& hydro_specific) { double total = 0; @@ -95,7 +98,7 @@ double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, TmpDat { for (uint realmonth = 0; realmonth != 12; ++realmonth) { - data.MTG[realmonth] = data.inflows[realmonth]; + hydro_specific.monthly[realmonth].MTG = data.inflows[realmonth]; } return total; @@ -105,9 +108,9 @@ double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, TmpDat for (uint realmonth = 0; realmonth != 12; ++realmonth) { - if (data.MLE[realmonth] > monthlyMaxDemand) + if (hydro_specific.monthly[realmonth].MLE > monthlyMaxDemand) { - monthlyMaxDemand = data.MLE[realmonth]; + monthlyMaxDemand = hydro_specific.monthly[realmonth].MLE; } } @@ -116,8 +119,8 @@ double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, TmpDat double coeff = 0.; for (uint realmonth = 0; realmonth != 12; ++realmonth) { - assert(data.MLE[realmonth] / monthlyMaxDemand >= 0.); - coeff += std::pow(data.MLE[realmonth] / monthlyMaxDemand, + assert(hydro_specific.monthly[realmonth].MLE / monthlyMaxDemand >= 0.); + coeff += std::pow(hydro_specific.monthly[realmonth].MLE / monthlyMaxDemand, area.hydro.intermonthlyBreakdown); } @@ -128,10 +131,11 @@ double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, TmpDat for (uint realmonth = 0; realmonth != 12; ++realmonth) { - assert(data.MLE[realmonth] / monthlyMaxDemand >= 0.); - data.MTG[realmonth] = coeff - * std::pow(data.MLE[realmonth] / monthlyMaxDemand, - area.hydro.intermonthlyBreakdown); + assert(hydro_specific.monthly[realmonth].MLE / monthlyMaxDemand >= 0.); + hydro_specific.monthly[realmonth].MTG = coeff + * std::pow(hydro_specific.monthly[realmonth].MLE + / monthlyMaxDemand, + area.hydro.intermonthlyBreakdown); } } else @@ -140,20 +144,24 @@ double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, TmpDat for (uint realmonth = 0; realmonth != 12; ++realmonth) { - data.MTG[realmonth] = coeff; + hydro_specific.monthly[realmonth].MTG = coeff; } } return total; } -void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_level, uint y) +void HydroManagement::prepareMonthlyOptimalGenerations( + double* random_reservoir_level, + uint y, + HydroSpecificMap& hydro_specific_map) { uint indexArea = 0; areas_.each( - [this, &random_reservoir_level, &y, &indexArea](Data::Area& area) + [this, &random_reservoir_level, &y, &indexArea, &hydro_specific_map](Data::Area& area) { - auto& data = tmpDataByArea_[&area]; + auto& data = area.hydro.managementData[y]; + auto& hydro_specific = hydro_specific_map[&area]; auto& minLvl = area.hydro.reservoirLevel[Data::PartHydro::minimum]; auto& maxLvl = area.hydro.reservoirLevel[Data::PartHydro::maximum]; @@ -173,7 +181,7 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ { auto problem = H2O_M_Instanciation(1); - double totalInflowsYear = prepareMonthlyTargetGenerations(area, data); + double totalInflowsYear = prepareMonthlyTargetGenerations(area, data, hydro_specific); assert(totalInflowsYear >= 0.); problem.CoutDepassementVolume = 1e2; @@ -189,7 +197,7 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ problem.TurbineMax[month] = totalInflowsYear; problem.TurbineMin[month] = data.mingens[realmonth]; - problem.TurbineCible[month] = data.MTG[realmonth]; + problem.TurbineCible[month] = hydro_specific.monthly[realmonth].MTG; problem.Apport[month] = data.inflows[realmonth]; problem.VolumeMin[month] = minLvl[firstDay]; problem.VolumeMax[month] = maxLvl[firstDay]; @@ -209,10 +217,11 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ { uint realmonth = (initReservoirLvlMonth + month) % 12; - data.MOG[realmonth] = problem.Turbine[month] * area.hydro.reservoirCapacity; - data.MOL[realmonth] = problem.Volume[month]; + hydro_specific.monthly[realmonth].MOG = problem.Turbine[month] + * area.hydro.reservoirCapacity; + hydro_specific.monthly[realmonth].MOL = problem.Volume[month]; } - data.MOL[initReservoirLvlMonth] = lvi; + hydro_specific.monthly[initReservoirLvlMonth].MOL = lvi; solutionCost = problem.ProblemeHydraulique.CoutDeLaSolution; solutionCostNoised = problem.ProblemeHydraulique.CoutDeLaSolutionBruite; @@ -242,18 +251,22 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ for (uint realmonth = 0; realmonth != 12; ++realmonth) { - data.MOG[realmonth] = data.inflows[realmonth]; - data.MOL[realmonth] = reservoirLevel[realmonth]; + hydro_specific.monthly[realmonth].MOG = data.inflows[realmonth]; + hydro_specific.monthly[realmonth].MOL = reservoirLevel[realmonth]; } } #ifndef NDEBUG for (uint realmonth = 0; realmonth != 12; ++realmonth) { - assert(!std::isnan(data.MOG[realmonth]) && "nan value detected for MOG"); - assert(!std::isnan(data.MOL[realmonth]) && "nan value detected for MOL"); - assert(!std::isinf(data.MOG[realmonth]) && "infinite value detected for MOG"); - assert(!std::isinf(data.MOL[realmonth]) && "infinite value detected for MOL"); + assert(!std::isnan(hydro_specific.monthly[realmonth].MOG) + && "nan value detected for MOG"); + assert(!std::isnan(hydro_specific.monthly[realmonth].MOL) + && "nan value detected for MOL"); + assert(!std::isinf(hydro_specific.monthly[realmonth].MOG) + && "infinite value detected for MOG"); + assert(!std::isinf(hydro_specific.monthly[realmonth].MOL) + && "infinite value detected for MOL"); } #endif if (parameters_.hydroDebug) @@ -278,8 +291,9 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ writeSolutionCost("Solution cost (noised) : ", solutionCostNoised); buffer << "\n\n"; - buffer << '\t' << "\tInflows" << '\t' << "\tTarget Gen." << "\tTurbined" << "\tLevels" - << '\t' << "\tLvl min" << '\t' << "\tLvl max\n"; + buffer << '\t' << "\tInflows" << '\t' << "\tTarget Gen." + << "\tTurbined" + << "\tLevels" << '\t' << "\tLvl min" << '\t' << "\tLvl max\n"; for (uint month = 0; month != 12; ++month) { uint realmonth = (initReservoirLvlMonth + month) % 12; @@ -290,22 +304,22 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ auto monthName = calendar_.text.months[simulationMonth].name; - buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; - buffer << '\t'; - buffer << data.inflows[realmonth] << '\t'; - buffer << data.MTG[realmonth] << '\t'; - buffer << data.MOG[realmonth] / area.hydro.reservoirCapacity << '\t'; - buffer << data.MOL[realmonth] << '\t'; - buffer << minLvl[firstDay] << '\t'; - buffer << maxLvl[firstDay] << '\t'; - buffer << '\n'; - } - auto content = buffer.str(); - resultWriter_.addEntryFromBuffer(path.str(), content); - } - - indexArea++; - }); + buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; + buffer << '\t'; + buffer << data.inflows[realmonth] << '\t'; + buffer << hydro_specific.monthly[realmonth].MTG << '\t'; + buffer << hydro_specific.monthly[realmonth].MOG / area.hydro.reservoirCapacity + << '\t'; + buffer << hydro_specific.monthly[realmonth].MOL << '\t'; + buffer << minLvl[firstDay] << '\t'; + buffer << maxLvl[firstDay] << '\t'; + buffer << '\n'; + } + auto content = buffer.str(); + resultWriter_.addEntryFromBuffer(path.str(), content); + } + indexArea++; + }); } } // namespace Antares diff --git a/src/solver/simulation/CMakeLists.txt b/src/solver/simulation/CMakeLists.txt index 6a5355ea56..fbfeb17f6a 100644 --- a/src/solver/simulation/CMakeLists.txt +++ b/src/solver/simulation/CMakeLists.txt @@ -44,8 +44,6 @@ set(SRC_SIMULATION include/antares/solver/simulation/adequacy_patch_runtime_data.h adequacy_patch_runtime_data.cpp include/antares/solver/simulation/ITimeSeriesNumbersWriter.h - include/antares/solver/simulation/hydro-final-reservoir-level-functions.h - hydro-final-reservoir-level-functions.cpp TimeSeriesNumbersWriter.cpp include/antares/solver/simulation/BindingConstraintsTimeSeriesNumbersWriter.h include/antares/solver/simulation/ISimulationObserver.h diff --git a/src/solver/simulation/hydro-final-reservoir-level-functions.cpp b/src/solver/simulation/hydro-final-reservoir-level-functions.cpp deleted file mode 100644 index 32f2d4dfa2..0000000000 --- a/src/solver/simulation/hydro-final-reservoir-level-functions.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* -** Copyright 2007-2023 RTE -** Authors: RTE-international / Redstork / Antares_Simulator Team -** -** This file is part of Antares_Simulator. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** There are special exceptions to the terms and conditions of the -** license as they are applied to this software. View the full text of -** the exceptions in file COPYING.txt in the directory of this software -** distribution -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with Antares_Simulator. If not, see . -** -** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions -*/ - -#include "antares/solver/simulation/hydro-final-reservoir-level-functions.h" -#include "antares/study/parts/hydro/finalLevelValidator.h" -#include - -namespace Antares::Solver -{ - -void CheckFinalReservoirLevelsConfiguration(const Data::Study& study) -{ - study.areas.each([&study](Data::Area &area) - { - uint nbYears = study.parameters.nbYears; - for (uint year = 0; year != nbYears; ++year) - { - if (! study.parameters.yearsFilter.at(year)) - continue; - - double initialLevel = study.scenarioInitialHydroLevels.entry[area.index][year]; - double finalLevel = study.scenarioFinalHydroLevels.entry[area.index][year]; - - Data::FinalLevelValidator validator(area.hydro, - area.index, - area.name, - initialLevel, - finalLevel, - year, - study.parameters.simulationDays.end, - study.parameters.firstMonthInYear); - if (! validator.check()) - { - throw FatalError("hydro final level : infeasibility"); - } - if (validator.finalLevelFineForUse()) - { - area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; - } - } - }); -} // End function CheckFinalReservoirLevelsConfiguration - -} // namespace Antares::Solver \ No newline at end of file diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.h b/src/solver/simulation/include/antares/solver/simulation/solver.h index cd2abfa366..6dc6f85eb8 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver.h @@ -127,7 +127,7 @@ class ISimulation: public Impl ** Storing these costs to compute std deviation later. */ void computeAnnualCostsStatistics(std::vector& state, - std::vector::iterator& set_it); + setOfParallelYears& batch); /*! ** \brief Iterate through all MC years diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 57dff06fd9..093cb1e350 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -33,14 +33,13 @@ #include "antares/concurrency/concurrency.h" #include "antares/solver/variable/constants.h" #include "antares/solver/variable/print.h" -#include "antares/solver/hydro/management/management.h" // Added for use of randomReservoirLevel(...) -#include "antares/solver/simulation/apply-scenario.h" +#include "antares/solver/hydro/management/HydroInputsChecker.h" +#include "antares/solver/hydro/management/management.h" #include "antares/solver/simulation/opt_time_writer.h" #include "antares/solver/simulation/timeseries-numbers.h" #include "antares/solver/ts-generator/generator.h" -#include "hydro-final-reservoir-level-functions.h" namespace Antares::Solver::Simulation { @@ -307,8 +306,6 @@ void ISimulation::run() ImplementationType::setNbPerformedYearsInParallel(pNbMaxPerformedYearsInParallel); - TSGenerator::ResizeGeneratedTimeSeries(study.areas, study.parameters); - if (settings.tsGeneratorsOnly) { // Only the preprocessors can be used @@ -334,29 +331,6 @@ void ISimulation::run() // For beauty logs.info(); - // Sampled time-series Numbers - // We will resize all matrix related to the time-series numbers - // This operation can be done once since the number of years is constant - // for a single simulation - study.resizeAllTimeseriesNumbers(1 + study.runtime->rangeLimits.year[Data::rangeEnd]); - // Now, we will prepare the time-series numbers - if (not TimeSeriesNumbers::CheckNumberOfColumns(study.areas)) - { - throw FatalError( - "Inconsistent number of time-series detected. Please check your input data."); - } - - if (not TimeSeriesNumbers::Generate(study)) - { - throw FatalError("An unrecoverable error has occured. Can not continue."); - } - - if (study.parameters.useCustomScenario) - { - ApplyCustomScenario(study); - CheckFinalReservoirLevelsConfiguration(study); - } - // Launching the simulation for all years logs.info() << "MC-Years : [" << (study.runtime->rangeLimits.year[Data::rangeBegin] + 1) << " .. " << (1 + study.runtime->rangeLimits.year[Data::rangeEnd]) @@ -370,7 +344,6 @@ void ISimulation::run() ImplementationType::initializeState(state[numSpace], numSpace); } - logs.info() << " Starting the simulation"; uint finalYear = 1 + study.runtime->rangeLimits.year[Data::rangeEnd]; { pDurationCollector("mc_years") @@ -915,18 +888,15 @@ void ISimulation::computeRandomNumbers( template void ISimulation::computeAnnualCostsStatistics( std::vector& state, - std::vector::iterator& set_it) + setOfParallelYears& batch) { // Loop over years contained in the set - std::vector::iterator year_it; - for (year_it = set_it->yearsIndices.begin(); year_it != set_it->yearsIndices.end(); ++year_it) + for (auto y: batch.yearsIndices) { - // Get the index of the year - unsigned int y = *year_it; - if (set_it->isYearPerformed[y]) + if (batch.isYearPerformed[y]) { // Get space number associated to the performed year - uint numSpace = set_it->performedYearToSpace[y]; + uint numSpace = batch.performedYearToSpace[y]; const Variable::State& s = state[numSpace]; pAnnualStatistics.systemCost.addCost(s.annualSystemCost); pAnnualStatistics.criterionCost1.addCost(s.optimalSolutionCost1); @@ -990,66 +960,78 @@ void ISimulation::loopThroughYears(uint firstYear, // Number of threads to perform the jobs waiting in the queue pQueueService->maximumThreadCount(pNbMaxPerformedYearsInParallel); + HydroInputsChecker hydroInputsChecker(study); + + logs.info() << " Doing hydro validation"; - // Loop over sets of parallel years - std::vector::iterator set_it; - for (set_it = setsOfParallelYears.begin(); set_it != setsOfParallelYears.end(); ++set_it) + // Loop over sets of parallel years to check hydro inputs + for (const auto& batch: setsOfParallelYears) + { + if (batch.regenerateTS) + { + break; + } + for (auto year: batch.yearsIndices) + { + hydroInputsChecker.Execute(year); + } + } + + logs.info() << " Starting the simulation"; + + // Loop over sets of parallel years to run the simulation + for (auto& batch: setsOfParallelYears) { // 1 - We may want to regenerate the time-series this year. // This is the case when the preprocessors are enabled from the // interface and/or the refresh is enabled. - if (set_it->regenerateTS) + if (batch.regenerateTS) { - regenerateTimeSeries(set_it->yearForTSgeneration); + regenerateTimeSeries(batch.yearForTSgeneration); } - computeRandomNumbers(randomForParallelYears, - set_it->yearsIndices, - set_it->isYearPerformed, + batch.yearsIndices, + batch.isYearPerformed, randomHydroGenerator); - std::vector::iterator year_it; - bool yearPerformed = false; Concurrency::FutureSet results; - for (year_it = set_it->yearsIndices.begin(); year_it != set_it->yearsIndices.end(); - ++year_it) + for (auto y: batch.yearsIndices) { - // Get the index of the year - unsigned int y = *year_it; - - bool performCalculations = set_it->isYearPerformed[y]; + // for each year not handled earlier + hydroInputsChecker.Execute(y); + bool performCalculations = batch.isYearPerformed[y]; unsigned int numSpace = 999999; if (performCalculations) { yearPerformed = true; - numSpace = set_it->performedYearToSpace[y]; + numSpace = batch.performedYearToSpace[y]; } // If the year has not to be rerun, we skip the computation of the year. // Note that, when we enter for the first time in the "for" loop, all years of the set - // have to be rerun (meaning : they must be run once). if(!set_it->yearFailed[y]) + // have to be rerun (meaning : they must be run once). if(!batch.yearFailed[y]) // continue; auto task = std::make_shared>( - this, - y, - set_it->yearFailed, - set_it->isFirstPerformedYearOfASet, - pFirstSetParallelWithAPerformedYearWasRun, - numSpace, - randomForParallelYears, - performCalculations, - study, - state[numSpace], - pYearByYear, - pDurationCollector, + this, + y, + batch.yearFailed, + batch.isFirstPerformedYearOfASet, + pFirstSetParallelWithAPerformedYearWasRun, + numSpace, + randomForParallelYears, + performCalculations, + study, + state[numSpace], + pYearByYear, + pDurationCollector, pResultWriter, simulationObserver_.get()); results.add(Concurrency::AddTask(*pQueueService, task)); } // End loop over years of the current set of parallel years - logPerformedYearsInAset(*set_it); + logPerformedYearsInAset(batch); pQueueService->start(); @@ -1058,14 +1040,15 @@ void ISimulation::loopThroughYears(uint firstYear, results.join(); pResultWriter.flush(); - // At this point, the first set of parallel year(s) was run with at least one year performed + // At this point, the first set of parallel year(s) was run with at least one year + // performed if (!pFirstSetParallelWithAPerformedYearWasRun && yearPerformed) { pFirstSetParallelWithAPerformedYearWasRun = true; } // On regarde si au moins une année du lot n'a pas trouvé de solution - for (auto& [year, failed]: set_it->yearFailed) + for (auto& [year, failed]: batch.yearFailed) { // Si une année du lot d'années n'a pas trouvé de solution, on arrête tout if (failed) @@ -1077,17 +1060,17 @@ void ISimulation::loopThroughYears(uint firstYear, } // Computing the summary : adding the contribution of MC years // previously computed in parallel - ImplementationType::variables.computeSummary(set_it->spaceToPerformedYear, - set_it->nbPerformedYears); + ImplementationType::variables.computeSummary(batch.spaceToPerformedYear, + batch.nbPerformedYears); // Computing summary of spatial aggregations ImplementationType::variables.computeSpatialAggregatesSummary(ImplementationType::variables, - set_it->spaceToPerformedYear, - set_it->nbPerformedYears); + batch.spaceToPerformedYear, + batch.nbPerformedYears); // Computes statistics on annual (system and solution) costs, to be printed in output into // separate files - computeAnnualCostsStatistics(state, set_it); + computeAnnualCostsStatistics(state, batch); // Set to zero the random numbers of all parallel years randomForParallelYears.reset(); diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index 7992165af2..1def8eded6 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -107,7 +107,6 @@ BOOST_AUTO_TEST_SUITE(ONE_AREA__ONE_THERMAL_CLUSTER) BOOST_FIXTURE_TEST_CASE(thermal_cluster_fullfills_area_demand, StudyFixture) { setNumberMCyears(1); - simulation->create(); simulation->run(); @@ -283,13 +282,13 @@ BOOST_FIXTURE_TEST_CASE(error_on_wrong_hydro_data, StudyFixture) { StudyBuilder builder; builder.simulationBetweenDays(0, 7); - builder.setNumberMCyears(1); Area& area = *builder.addAreaToStudy("A"); PartHydro& hydro = area.hydro; TimeSeriesConfigurer(hydro.series->storage.timeSeries) .setColumnCount(1) .fillColumnWith(0, -1.0); // Negative inflow will cause a consistency error with mingen + builder.setNumberMCyears(1); auto simulation = builder.simulation; simulation->create(); BOOST_CHECK_THROW(simulation->run(), Antares::FatalError); diff --git a/src/tests/inmemory-study/CMakeLists.txt b/src/tests/inmemory-study/CMakeLists.txt index 36c757f717..bb7cd26e13 100644 --- a/src/tests/inmemory-study/CMakeLists.txt +++ b/src/tests/inmemory-study/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(in-memory-study PUBLIC ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} antares-solver-simulation + Antares::application PRIVATE Antares::infoCollection ) diff --git a/src/tests/inmemory-study/in-memory-study.cpp b/src/tests/inmemory-study/in-memory-study.cpp index 77b984fb45..4b4e65c100 100644 --- a/src/tests/inmemory-study/in-memory-study.cpp +++ b/src/tests/inmemory-study/in-memory-study.cpp @@ -19,8 +19,9 @@ * along with Antares_Simulator. If not, see . */ #define WIN32_LEAN_AND_MEAN -#include "in-memory-study.h" +#include "antares/application/ScenarioBuilderOwner.h" +#include "in-memory-study.h" void initializeStudy(Study* study) { @@ -193,6 +194,8 @@ void SimulationHandler::create() durationCollector_, resultWriter_, observer_); + Antares::Solver::ScenarioBuilderOwner(study_).callScenarioBuilder(); + SIM_AllocationTableaux(study_); } diff --git a/src/tests/src/solver/simulation/CMakeLists.txt b/src/tests/src/solver/simulation/CMakeLists.txt index 3ba8f09755..294005454b 100644 --- a/src/tests/src/solver/simulation/CMakeLists.txt +++ b/src/tests/src/solver/simulation/CMakeLists.txt @@ -1,5 +1,6 @@ # Useful variables definitions set(src_solver_simulation "${CMAKE_SOURCE_DIR}/solver/simulation") +set(src_solver_hydro "${CMAKE_SOURCE_DIR}/solver/hydro") set(src_libs_antares_study "${CMAKE_SOURCE_DIR}/libs/antares/study") set(SRC_TS_NUMBERS @@ -99,6 +100,7 @@ target_include_directories(test-hydro_final PRIVATE "${src_solver_simulation}" "${src_libs_antares_study}" + "${src_solver_hydro}" ) target_link_libraries(test-hydro_final PRIVATE diff --git a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp index d4a6c3512b..70e4b62357 100644 --- a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp +++ b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp @@ -6,10 +6,11 @@ #define WIN32_LEAN_AND_MEAN #include -#include "include/antares/solver/simulation/hydro-final-reservoir-level-functions.h" -#include "include/antares/study/parts/hydro/finalLevelValidator.h" #include +#include "include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h" +#include "include/antares/study/parts/hydro/finalLevelValidator.h" + using namespace Antares::Solver; using namespace Antares::Data; @@ -257,7 +258,16 @@ BOOST_AUTO_TEST_CASE(final_level_unreachable_because_of_too_few_inflows___check_ BOOST_AUTO_TEST_CASE(check_all_areas_final_levels_when_config_is_ok___all_checks_succeed) { - CheckFinalReservoirLevelsConfiguration(*study); + for (uint year : {0, 1}) + { + CheckFinalReservoirLevelsConfiguration(study->areas, + study->parameters, + study->scenarioInitialHydroLevels, + study->scenarioFinalHydroLevels, + year); + } + // CheckFinalReservoirLevelsConfiguration(*study, 0); + // CheckFinalReservoirLevelsConfiguration(*study, 1); // Checks on Area 1 modifier BOOST_CHECK_EQUAL(area_1->hydro.deltaBetweenFinalAndInitialLevels[0].has_value(), true); @@ -272,4 +282,4 @@ BOOST_AUTO_TEST_CASE(check_all_areas_final_levels_when_config_is_ok___all_checks BOOST_CHECK_EQUAL(area_2->hydro.deltaBetweenFinalAndInitialLevels[1].value(), 4.3 - 2.4); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END() From 54954cd8e488c7b855ba54a39404b2936317794f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jason=20Mar=C3=A9chal?= <45510813+JasonMarechal25@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:17:00 +0200 Subject: [PATCH 047/127] Resize data collections in PROBLEME_A_RESOUDRE (#2189) Some collections in PROBLEME_A_RESOUDRE are optimistically sized early but never resized to their proper size. When exporting those collections to clients by API it unnecessarily. Resizing for NombreDeVariables could be done earlier but for NombreDeContraintes we need to wait until we have build all constraints with ConstraintBuilder. ConstraintsMatrixCoeff and ColumnIndexes collections are initially oversized (By a large factor). Before exporting data through API we properly dimension them and remove extra 0 padding --- .../HebdoProblemToLpsTranslator.cpp | 49 ++++++++++++------- ...onstruction_variables_couts_demarrages.cpp | 41 ++++++++-------- ...truction_variables_optimisees_lineaire.cpp | 38 +++++++------- .../opt_decompte_variables_et_contraintes.cpp | 38 +++++++------- .../opt_optimisation_lineaire.cpp | 42 +++++++++++++--- .../translator/test_translator.cpp | 4 +- 6 files changed, 130 insertions(+), 82 deletions(-) diff --git a/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp b/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp index 1109e9c780..d4c6e4b6b0 100644 --- a/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp +++ b/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp @@ -21,6 +21,7 @@ */ #include "antares/solver/optimisation/HebdoProblemToLpsTranslator.h" + #include "antares/solver/utils/filename.h" namespace Antares::Solver @@ -31,7 +32,8 @@ namespace /** * @brief Copies elements from one container to another. * - * This function takes two containers as arguments. It copies elements from the first container to the second one. + * This function takes two containers as arguments. It copies elements from the first container to + * the second one. * * @param in The container from which to copy elements. * @param out The container to which to copy elements. @@ -41,14 +43,16 @@ void copy(const T& in, U& out) { std::ranges::copy(in, std::back_inserter(out)); } -} +} // namespace WeeklyDataFromAntares HebdoProblemToLpsTranslator::translate( const PROBLEME_ANTARES_A_RESOUDRE* problem, std::string_view name) const { if (problem == nullptr) + { return {}; + } auto ret = WeeklyDataFromAntares(); copy(problem->CoutLineaire, ret.LinearCost); @@ -64,23 +68,33 @@ WeeklyDataFromAntares HebdoProblemToLpsTranslator::translate( return ret; } -ConstantDataFromAntares HebdoProblemToLpsTranslator::commonProblemData(const PROBLEME_ANTARES_A_RESOUDRE* problem) const { +ConstantDataFromAntares HebdoProblemToLpsTranslator::commonProblemData( + const PROBLEME_ANTARES_A_RESOUDRE* problem) const +{ if (problem == nullptr) + { return ConstantDataFromAntares(); + } - if (problem->NombreDeVariables <= 0) { + if (problem->NombreDeVariables <= 0) + { throw WeeklyProblemTranslationException("VariablesCount must be strictly positive"); } - if (problem->NombreDeContraintes <= 0) { + if (problem->NombreDeContraintes <= 0) + { throw WeeklyProblemTranslationException("ConstraintesCount must be strictly positive"); } - if (problem->NombreDeContraintes > problem->IndicesDebutDeLigne.size()) { - throw WeeklyProblemTranslationException("ConstraintesCount exceed IndicesDebutDeLigne size"); + if (problem->NombreDeContraintes > problem->IndicesDebutDeLigne.size()) + { + throw WeeklyProblemTranslationException( + "ConstraintesCount exceed IndicesDebutDeLigne size"); } - if (problem->NombreDeContraintes > problem->NombreDeTermesDesLignes.size()) { - throw WeeklyProblemTranslationException("ConstraintesCount exceed NombreDeTermesDesLignes size"); + if (problem->NombreDeContraintes > problem->NombreDeTermesDesLignes.size()) + { + throw WeeklyProblemTranslationException( + "ConstraintesCount exceed NombreDeTermesDesLignes size"); } ConstantDataFromAntares ret; @@ -88,22 +102,23 @@ ConstantDataFromAntares HebdoProblemToLpsTranslator::commonProblemData(const PRO ret.VariablesCount = problem->NombreDeVariables; ret.ConstraintesCount = problem->NombreDeContraintes; - ret.CoeffCount = problem->IndicesDebutDeLigne[problem->NombreDeContraintes - 1] + - problem->NombreDeTermesDesLignes[problem->NombreDeContraintes - 1]; + ret.CoeffCount = problem->IndicesDebutDeLigne[problem->NombreDeContraintes - 1] + + problem->NombreDeTermesDesLignes[problem->NombreDeContraintes - 1]; copy(problem->TypeDeVariable, ret.VariablesType); - copy(problem->CoefficientsDeLaMatriceDesContraintes, - ret.ConstraintsMatrixCoeff); + copy(problem->CoefficientsDeLaMatriceDesContraintes, ret.ConstraintsMatrixCoeff); + ret.ConstraintsMatrixCoeff.resize(ret.CoeffCount); copy(problem->IndicesColonnes, ret.ColumnIndexes); - + ret.ColumnIndexes.resize(ret.CoeffCount); copy(problem->IndicesDebutDeLigne, ret.Mdeb); + ret.Mdeb.push_back(ret.CoeffCount); return ret; } WeeklyProblemTranslationException::WeeklyProblemTranslationException( - const std::string& string) noexcept -: std::runtime_error{string} + const std::string& string) noexcept: + std::runtime_error{string} { } -} // namespace Antares::Solver \ No newline at end of file +} // namespace Antares::Solver diff --git a/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp b/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp index 6fe7e353da..98a259540d 100644 --- a/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp +++ b/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/optimisation/opt_rename_problem.h" @@ -35,7 +35,7 @@ void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaireCoutsDeDemarra int nombreDePasDeTempsPourUneOptimisation = problemeHebdo ->NombreDePasDeTempsPourUneOptimisation; - int& nombreDeVariables = ProblemeAResoudre->NombreDeVariables; + int nombreDeVariables = ProblemeAResoudre->NombreDeVariables; VariableNamer variableNamer(ProblemeAResoudre->NomDesVariables); const bool intVariables = problemeHebdo->OptimisationAvecVariablesEntieres; for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) @@ -94,4 +94,5 @@ void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaireCoutsDeDemarra } } } + ProblemeAResoudre->NombreDeVariables = nombreDeVariables; } diff --git a/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp b/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp index 8b082d5b50..40736b5428 100644 --- a/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp +++ b/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include #include "antares/solver/optimisation/opt_fonctions.h" diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp index 3df1cc9d99..1f773bb9ea 100644 --- a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp +++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include #include diff --git a/src/solver/optimisation/opt_optimisation_lineaire.cpp b/src/solver/optimisation/opt_optimisation_lineaire.cpp index d3635ff326..b3ca1a3daa 100644 --- a/src/solver/optimisation/opt_optimisation_lineaire.cpp +++ b/src/solver/optimisation/opt_optimisation_lineaire.cpp @@ -76,15 +76,14 @@ void notifyProblemHebdo(const PROBLEME_HEBDO* problemeHebdo, createMPSfilename(*optPeriodStringGenerator, optimizationNumber)); } -} +} // namespace bool runWeeklyOptimization(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, int optimizationNumber, - Solver::Simulation::ISimulationObserver& simulationObserver - ) + Solver::Simulation::ISimulationObserver& simulationObserver) { const int NombreDePasDeTempsPourUneOptimisation = problemeHebdo ->NombreDePasDeTempsPourUneOptimisation; @@ -121,7 +120,10 @@ bool runWeeklyOptimization(const OptimizationOptions& options, problemeHebdo->weekInTheYear, problemeHebdo->year); - notifyProblemHebdo(problemeHebdo, optimizationNumber, simulationObserver, optPeriodStringGenerator.get()); + notifyProblemHebdo(problemeHebdo, + optimizationNumber, + simulationObserver, + optPeriodStringGenerator.get()); if (!OPT_AppelDuSimplexe(options, problemeHebdo, @@ -158,14 +160,39 @@ void runThermalHeuristic(PROBLEME_HEBDO* problemeHebdo) OPT_CalculerLesPminThermiquesEnFonctionDeMUTetMDT(problemeHebdo); } } + +void resizeProbleme(PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre, + unsigned nombreDeVariables, + unsigned nombreDeContraintes) +{ + ProblemeAResoudre->CoutQuadratique.resize(nombreDeVariables); + ProblemeAResoudre->CoutLineaire.resize(nombreDeVariables); + ProblemeAResoudre->TypeDeVariable.resize(nombreDeVariables); + ProblemeAResoudre->Xmin.resize(nombreDeVariables); + ProblemeAResoudre->Xmax.resize(nombreDeVariables); + ProblemeAResoudre->X.resize(nombreDeVariables); + ProblemeAResoudre->AdresseOuPlacerLaValeurDesVariablesOptimisees.resize(nombreDeVariables); + ProblemeAResoudre->AdresseOuPlacerLaValeurDesCoutsReduits.resize(nombreDeVariables); + ProblemeAResoudre->PositionDeLaVariable.resize(nombreDeVariables); + ProblemeAResoudre->NomDesVariables.resize(nombreDeVariables); + ProblemeAResoudre->VariablesEntieres.resize(nombreDeVariables); + + ProblemeAResoudre->Sens.resize(nombreDeContraintes); + ProblemeAResoudre->IndicesDebutDeLigne.resize(nombreDeContraintes); + ProblemeAResoudre->NombreDeTermesDesLignes.resize(nombreDeContraintes); + ProblemeAResoudre->SecondMembre.resize(nombreDeContraintes); + ProblemeAResoudre->AdresseOuPlacerLaValeurDesCoutsMarginaux.resize(nombreDeContraintes); + ProblemeAResoudre->CoutsMarginauxDesContraintes.resize(nombreDeContraintes); + ProblemeAResoudre->ComplementDeLaBase.resize(nombreDeContraintes); + ProblemeAResoudre->NomDesContraintes.resize(nombreDeContraintes); +} } // namespace bool OPT_OptimisationLineaire(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, - Solver::Simulation::ISimulationObserver& simulationObserver - ) + Solver::Simulation::ISimulationObserver& simulationObserver) { if (!problemeHebdo->OptimisationAuPasHebdomadaire) { @@ -189,6 +216,9 @@ bool OPT_OptimisationLineaire(const OptimizationOptions& options, ConstraintBuilder builder(builder_data); LinearProblemMatrix linearProblemMatrix(problemeHebdo, builder); linearProblemMatrix.Run(); + resizeProbleme(problemeHebdo->ProblemeAResoudre.get(), + problemeHebdo->ProblemeAResoudre->NombreDeVariables, + problemeHebdo->ProblemeAResoudre->NombreDeContraintes); if (problemeHebdo->ExportStructure && problemeHebdo->firstWeekOfSimulation) { OPT_ExportStructures(problemeHebdo, writer); diff --git a/src/tests/src/solver/optimisation/translator/test_translator.cpp b/src/tests/src/solver/optimisation/translator/test_translator.cpp index 6fdc32c8fd..2430c74cb0 100644 --- a/src/tests/src/solver/optimisation/translator/test_translator.cpp +++ b/src/tests/src/solver/optimisation/translator/test_translator.cpp @@ -130,7 +130,9 @@ BOOST_AUTO_TEST_CASE(common_data_properly_copied) BOOST_CHECK(std::ranges::equal(ret.VariablesType, problemHebdo.TypeDeVariable)); BOOST_CHECK(ret.ConstraintsMatrixCoeff == problemHebdo.CoefficientsDeLaMatriceDesContraintes); BOOST_CHECK(std::ranges::equal(ret.ColumnIndexes, problemHebdo.IndicesColonnes)); - BOOST_CHECK(std::ranges::equal(ret.Mdeb, problemHebdo.IndicesDebutDeLigne)); + auto expectedMdeb = problemHebdo.IndicesDebutDeLigne; + expectedMdeb.push_back(problemHebdo.CoefficientsDeLaMatriceDesContraintes.size()); + BOOST_CHECK(std::ranges::equal(ret.Mdeb, expectedMdeb)); } // throw exception if NombreDeVariables is 0 From 69a64bd8640d90226364ed73db8099426d1319ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 28 Jun 2024 18:08:08 +0200 Subject: [PATCH 048/127] Remove unused CMake option BUILD_MINIZIP (#2210) --- src/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 44715f0650..0148e31899 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -183,9 +183,6 @@ message(STATUS "Build antares tools: ${BUILD_TOOLS}") option(BUILD_ORTOOLS "Build OR-Tools" OFF) message(STATUS "Build OR-Tools: ${BUILD_ORTOOLS}") -option(BUILD_MINIZIP "Build minizip" OFF) -message(STATUS "Build minizip: ${BUILD_MINIZIP}") - option(WITH_ANTLR4 "With antlr4" OFF) message(STATUS "With antlr4: ${WITH_ANTLR4}") From 9c725f5f01fe9ad2402fa821da817c8f6228fd11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 09:16:10 +0200 Subject: [PATCH 049/127] Bump SonarSource/sonarcloud-github-c-cpp from 2 to 3 (#2213) Bumps [SonarSource/sonarcloud-github-c-cpp](https://github.com/sonarsource/sonarcloud-github-c-cpp) from 2 to 3. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/sonarcloud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index e72287894d..4587c17919 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -43,7 +43,7 @@ jobs: echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@v2 + uses: SonarSource/sonarcloud-github-c-cpp@v3 - name: ccache uses: hendrikmuhs/ccache-action@v1.2 From c86b1dd6a8928bc414849f7e33b733d74da48d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 1 Jul 2024 10:22:57 +0200 Subject: [PATCH 050/127] Replace NULL -> nullptr in *.cpp (#2209) Co-authored-by: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> --- src/analyzer/atsp/cache.cpp | 2 +- src/analyzer/atsp/load.cpp | 6 +-- src/ext/yuni/src/yuni/core/any/any.cpp | 4 +- .../yuni/src/yuni/core/charset/charset.cpp | 2 +- .../src/yuni/core/dynamiclibrary/file.cpp | 2 +- src/ext/yuni/src/yuni/core/getopt/parser.cpp | 4 +- .../yuni/src/yuni/core/system/environment.cpp | 6 +-- .../src/yuni/core/system/gettimeofday.cpp | 4 +- src/ext/yuni/src/yuni/core/system/memory.cpp | 4 +- .../yuni/src/yuni/core/system/username.cpp | 4 +- src/ext/yuni/src/yuni/datetime/timestamp.cpp | 4 +- .../src/yuni/io/directory/info/platform.cpp | 26 +++++------ .../yuni/io/directory/iterator/iterator.cpp | 6 +-- src/ext/yuni/src/yuni/io/directory/remove.cpp | 2 +- src/ext/yuni/src/yuni/io/file/file.cpp | 4 +- src/ext/yuni/src/yuni/io/file/stream.cpp | 4 +- src/ext/yuni/src/yuni/job/job.cpp | 6 +-- src/ext/yuni/src/yuni/job/queue/service.cpp | 6 +-- src/ext/yuni/src/yuni/thread/signal.cpp | 10 ++-- src/ext/yuni/src/yuni/thread/thread.cpp | 4 +- src/ext/yuni/src/yuni/uuid/uuid.cpp | 2 +- src/libs/antares/args/args_to_utf8.cpp | 4 +- src/libs/antares/correlation/correlation.cpp | 4 +- src/libs/antares/locale/locale.cpp | 4 +- src/libs/antares/resources/resources.cpp | 2 +- src/libs/fswalker/fswalker.cpp | 4 +- src/solver/constraints-builder/cbuilder.cpp | 4 +- .../daily/h2o_j_construire_les_variables.cpp | 4 +- .../h2o_j_resoudre_le_probleme_lineaire.cpp | 2 +- .../h2o2_j_resoudre_le_probleme_lineaire.cpp | 2 +- .../h2o_m_resoudre_le_probleme_lineaire.cpp | 2 +- ...ction_variables_optimisees_quadratique.cpp | 2 +- .../opt_gestion_des_bornes_cas_lineaire.cpp | 38 +++++++-------- .../opt_liberation_problemes_simplexe.cpp | 6 +-- src/solver/ts-generator/xcast/math.cpp | 2 +- .../solver/simulation/tests-ts-numbers.cpp | 2 +- src/tools/yby-aggregator/result.cpp | 2 +- .../handler/antares-study/area/create.cpp | 2 +- .../antares-study/constraint/create.cpp | 2 +- .../antares-study/constraint/offsets.cpp | 2 +- .../antares-study/constraint/weights.cpp | 2 +- .../antares-study/thermal-cluster/create.cpp | 2 +- src/ui/common/component/panel/panel.cpp | 6 +-- .../common/component/spotlight/spotlight.cpp | 6 +-- .../main/build/economic-optimization.cpp | 2 +- .../simulator/application/main/build/load.cpp | 2 +- .../application/main/build/notes.cpp | 2 +- .../simulator/application/main/build/sets.cpp | 2 +- .../application/main/build/solar.cpp | 2 +- .../simulator/application/main/build/wind.cpp | 2 +- .../application/main/internal-data.cpp | 2 +- src/ui/simulator/application/main/logs.cpp | 4 +- src/ui/simulator/application/main/notes.cpp | 8 ++-- src/ui/simulator/application/main/options.cpp | 2 +- src/ui/simulator/application/main/refresh.cpp | 2 +- .../toolbox/components/button/button.cpp | 2 +- .../toolbox/components/datagrid/component.cpp | 2 +- .../components/datagrid/filter/operator.cpp | 2 +- .../datagrid/filter/parameter/parameter.cpp | 10 ++-- .../components/datagrid/filter/static.cpp | 2 +- .../components/datagrid/gridhelper.cpp | 2 +- .../components/datagrid/renderer/area/dsm.cpp | 2 +- .../datagrid/renderer/area/misc.cpp | 2 +- .../datagrid/renderer/area/timeseries.cpp | 4 +- .../toolbox/components/map/component.cpp | 4 +- .../toolbox/components/map/nodes/item.cpp | 2 +- .../toolbox/components/map/tools/tool.cpp | 4 +- .../components/notebook/mapnotebook.cpp | 4 +- src/ui/simulator/toolbox/create.cpp | 2 +- src/ui/simulator/toolbox/ext-source/apply.cpp | 4 +- src/ui/simulator/toolbox/input/connection.cpp | 2 +- src/ui/simulator/toolbox/jobs/job.cpp | 46 ++++++++++--------- src/ui/simulator/toolbox/spotlight/area.cpp | 2 +- .../toolbox/spotlight/constraint.cpp | 2 +- .../windows/correlation/correlation.cpp | 2 +- src/ui/simulator/windows/hydro/management.cpp | 2 +- .../adequacy-patch/adequacy-patch-options.cpp | 2 +- .../windows/options/advanced/advanced.cpp | 2 +- .../options/optimization/optimization.cpp | 6 +-- .../options/temp-folder/temp-folder.cpp | 2 +- src/ui/simulator/windows/output/output.cpp | 2 +- .../output/panel/area-link-renderer.cpp | 2 +- .../windows/output/panel/area-link.cpp | 6 +-- src/ui/simulator/windows/simulation/run.cpp | 2 +- 84 files changed, 189 insertions(+), 187 deletions(-) diff --git a/src/analyzer/atsp/cache.cpp b/src/analyzer/atsp/cache.cpp index 312dafe442..07ecd37803 100644 --- a/src/analyzer/atsp/cache.cpp +++ b/src/analyzer/atsp/cache.cpp @@ -37,7 +37,7 @@ void ATSP::cacheCreate() void ATSP::cacheDestroy() { delete[] pCacheMatrix; - pCacheMatrix = NULL; + pCacheMatrix = nullptr; } void ATSP::cacheClear() diff --git a/src/analyzer/atsp/load.cpp b/src/analyzer/atsp/load.cpp index f7a08f4d1a..0f8b92311f 100644 --- a/src/analyzer/atsp/load.cpp +++ b/src/analyzer/atsp/load.cpp @@ -54,12 +54,12 @@ bool ATSP::loadFromINIFile(const String& filename) CString<50, false> key; CString<50, false> value; - for (section = ini.firstSection; section != NULL; section = section->next) + for (section = ini.firstSection; section; section = section->next) { if (section->name == ".general") { IniFile::Property* p = section->firstProperty; - for (; p != NULL; p = p->next) + for (; p ; p = p->next) { key = p->key; key.toLower(); @@ -180,7 +180,7 @@ bool ATSP::loadFromINIFile(const String& filename) info->distribution = Data::XCast::dtBeta; IniFile::Property* p = section->firstProperty; - for (; p != NULL; p = p->next) + for (; p; p = p->next) { key = p->key; key.toLower(); diff --git a/src/ext/yuni/src/yuni/core/any/any.cpp b/src/ext/yuni/src/yuni/core/any/any.cpp index 47017ed8d1..36e2257c32 100644 --- a/src/ext/yuni/src/yuni/core/any/any.cpp +++ b/src/ext/yuni/src/yuni/core/any/any.cpp @@ -16,7 +16,7 @@ namespace Yuni Any::Any() { pTable = Private::Any::Table::Get(); - pObject = NULL; + pObject = nullptr; } Any::Any(const Any& rhs) @@ -59,7 +59,7 @@ void Any::reset() { pTable->staticDelete(&pObject); pTable = Private::Any::Table::Get(); - pObject = NULL; + pObject = nullptr; } } diff --git a/src/ext/yuni/src/yuni/core/charset/charset.cpp b/src/ext/yuni/src/yuni/core/charset/charset.cpp index 2323581439..30c63e0bd2 100644 --- a/src/ext/yuni/src/yuni/core/charset/charset.cpp +++ b/src/ext/yuni/src/yuni/core/charset/charset.cpp @@ -61,7 +61,7 @@ void Converter::reset() { if (!valid()) return; - iconv((iconv_t)pContext, NULL, NULL, NULL, NULL); + iconv((iconv_t)pContext, nullptr, nullptr, nullptr, nullptr); } const char* Converter::Name(Charset::Type type) diff --git a/src/ext/yuni/src/yuni/core/dynamiclibrary/file.cpp b/src/ext/yuni/src/yuni/core/dynamiclibrary/file.cpp index 54f35580a4..0f673490b3 100644 --- a/src/ext/yuni/src/yuni/core/dynamiclibrary/file.cpp +++ b/src/ext/yuni/src/yuni/core/dynamiclibrary/file.cpp @@ -215,7 +215,7 @@ bool File::loadFromRawFilename(const AnyString& filename, File::Relocation r, Fi bool File::hasSymbol(const AnyString& name) const { return NullHandle != pHandle - and NULL != reinterpret_cast(YUNI_DYNLIB_DLSYM(pHandle, name.c_str())); + && reinterpret_cast(YUNI_DYNLIB_DLSYM(pHandle, name.c_str())); } Symbol File::resolve(const AnyString& name) const diff --git a/src/ext/yuni/src/yuni/core/getopt/parser.cpp b/src/ext/yuni/src/yuni/core/getopt/parser.cpp index c34443c470..c3e31f7d72 100644 --- a/src/ext/yuni/src/yuni/core/getopt/parser.cpp +++ b/src/ext/yuni/src/yuni/core/getopt/parser.cpp @@ -118,7 +118,7 @@ inline Context::Context(Parser& parser) : pParser(parser), pTokenIndex(1), pPara bool Context::findNextParameter(IOption* option, int argc, char* argv[]) { - assert(option != NULL); + assert(option); if (not option->requireAdditionalParameter()) { @@ -343,7 +343,7 @@ GetOpt::ReturnCode Parser::operator()(int argc, char* argv[]) void Parser::helpUsage(const char* argv0) { - assert(argv0 != NULL); // just in case + assert(argv0); // just in case// OK std::cout.write("Usage: ", 7); std::cout << ExtractFilenameOnly(argv0); diff --git a/src/ext/yuni/src/yuni/core/system/environment.cpp b/src/ext/yuni/src/yuni/core/system/environment.cpp index 8f278e971e..cb5a5c9800 100644 --- a/src/ext/yuni/src/yuni/core/system/environment.cpp +++ b/src/ext/yuni/src/yuni/core/system/environment.cpp @@ -45,7 +45,7 @@ inline bool ReadImpl(const AnyString& name, StringT& out, bool emptyBefore) if (size != 0) { int sizeRequired - = WideCharToMultiByte(CP_UTF8, 0, buffer, (int)size - 1, NULL, 0, NULL, NULL); + = WideCharToMultiByte(CP_UTF8, 0, buffer, (int)size - 1, nullptr, 0, nullptr, nullptr); if (sizeRequired > 0) { out.reserve(out.size() + sizeRequired); @@ -55,8 +55,8 @@ inline bool ReadImpl(const AnyString& name, StringT& out, bool emptyBefore) (int)size - 1, out.data() + out.size(), size, - NULL, - NULL); + nullptr, + nullptr); ::free(buffer); out.resize(out.size() + (uint)sizeRequired); return true; diff --git a/src/ext/yuni/src/yuni/core/system/gettimeofday.cpp b/src/ext/yuni/src/yuni/core/system/gettimeofday.cpp index a8d3ec2aee..18ff782ed8 100644 --- a/src/ext/yuni/src/yuni/core/system/gettimeofday.cpp +++ b/src/ext/yuni/src/yuni/core/system/gettimeofday.cpp @@ -19,7 +19,7 @@ namespace Yuni { int gettimeofday(struct timeval* tv, struct timezone* tz) { - if (NULL != tv) + if (tv) { struct _timeb timebuffer; _ftime64_s(&timebuffer); @@ -27,7 +27,7 @@ int gettimeofday(struct timeval* tv, struct timezone* tz) tv->tv_usec = (int64_t)(timebuffer.millitm * 1000); } - if (NULL != tz) + if (tz) { static int tzflag = 0; if (!tzflag) diff --git a/src/ext/yuni/src/yuni/core/system/memory.cpp b/src/ext/yuni/src/yuni/core/system/memory.cpp index a872a46b02..4e1bfbce29 100644 --- a/src/ext/yuni/src/yuni/core/system/memory.cpp +++ b/src/ext/yuni/src/yuni/core/system/memory.cpp @@ -268,7 +268,7 @@ uint64_t Total() int mib[2] = {CTL_HW, HW_MEMSIZE}; uint64_t memory; size_t len = sizeof(uint64_t); - return (!sysctl(mib, 2, &memory, &len, NULL, 0)) ? memory : (uint64_t)defaultTotal; + return (!sysctl(mib, 2, &memory, &len, nullptr, 0)) ? memory : (uint64_t)defaultTotal; } uint64_t Available() @@ -298,7 +298,7 @@ bool Usage::update() int mib[2] = {CTL_HW, HW_MEMSIZE}; size_t len = sizeof(uint64_t); size_t sttotal; - if (sysctl(mib, 2, &sttotal, &len, NULL, 0)) + if (sysctl(mib, 2, &sttotal, &len, nullptr, 0)) { total = (uint64_t)defaultTotal; return false; diff --git a/src/ext/yuni/src/yuni/core/system/username.cpp b/src/ext/yuni/src/yuni/core/system/username.cpp index 9e5b57cf7c..1348b2e02c 100644 --- a/src/ext/yuni/src/yuni/core/system/username.cpp +++ b/src/ext/yuni/src/yuni/core/system/username.cpp @@ -37,12 +37,12 @@ uint WindowsUsername(char* cstring, uint size) // The variable `unwsize` contains the final zero --unwsize; // Getting the size of the buffer into UTF8 - int sizeRequired = WideCharToMultiByte(CP_UTF8, 0, unw, unwsize, NULL, 0, NULL, NULL); + int sizeRequired = WideCharToMultiByte(CP_UTF8, 0, unw, unwsize, nullptr, 0, nullptr, nullptr); if (sizeRequired > 0) { if (static_cast(sizeRequired) > size) sizeRequired = size; - WideCharToMultiByte(CP_UTF8, 0, unw, unwsize, cstring, sizeRequired, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, unw, unwsize, cstring, sizeRequired, nullptr, nullptr); return static_cast(sizeRequired); } } diff --git a/src/ext/yuni/src/yuni/datetime/timestamp.cpp b/src/ext/yuni/src/yuni/datetime/timestamp.cpp index 90c1b26496..06c2fa68e9 100644 --- a/src/ext/yuni/src/yuni/datetime/timestamp.cpp +++ b/src/ext/yuni/src/yuni/datetime/timestamp.cpp @@ -97,9 +97,9 @@ char* FormatTimestampToString(const AnyString& format, int64_t timestamp) if (timestamp <= 0) { #ifdef YUNI_OS_MSVC - timestamp = (int64_t)::_time64(NULL); + timestamp = (int64_t)::_time64(nullptr); #else - timestamp = (int64_t)::time(NULL); + timestamp = (int64_t)::time(nullptr); #endif } diff --git a/src/ext/yuni/src/yuni/io/directory/info/platform.cpp b/src/ext/yuni/src/yuni/io/directory/info/platform.cpp index 7a330da911..516a344f41 100644 --- a/src/ext/yuni/src/yuni/io/directory/info/platform.cpp +++ b/src/ext/yuni/src/yuni/io/directory/info/platform.cpp @@ -189,12 +189,12 @@ class DirInfo final : private Yuni::NonCopyable } const int sizeRequired - = WideCharToMultiByte(CP_UTF8, 0, data.name, -1, NULL, 0, NULL, NULL); + = WideCharToMultiByte(CP_UTF8, 0, data.name, -1, nullptr, 0, nullptr, nullptr); if (sizeRequired <= 0) continue; name.reserve((uint)sizeRequired); WideCharToMultiByte( - CP_UTF8, 0, data.name, -1, (char*)name.data(), sizeRequired, NULL, NULL); + CP_UTF8, 0, data.name, -1, (char*)name.data(), sizeRequired, nullptr, nullptr); name.resize(((uint)sizeRequired) - 1); filename.clear(); @@ -341,12 +341,12 @@ IteratorData* IteratorDataCreate(const AnyString& folder, uint flags) data->push(folder); return data; } - return NULL; + return nullptr; } IteratorData* IteratorDataCopy(const IteratorData* data) { - return (data) ? (new IteratorData(*data)) : NULL; + return (data) ? (new IteratorData(*data)) : nullptr; } void IteratorDataFree(const IteratorData* data) @@ -356,52 +356,52 @@ void IteratorDataFree(const IteratorData* data) IteratorData* IteratorDataNext(IteratorData* data) { - assert(data != NULL); + assert(data); if (data->next()) return data; delete data; - return NULL; + return nullptr; } const String& IteratorDataFilename(const IteratorData* data) { - assert(data != NULL); + assert(data); return data->dirinfo.front().filename; } const String& IteratorDataParentName(const IteratorData* data) { - assert(data != NULL); + assert(data); return data->dirinfo.front().parent; } const String& IteratorDataName(const IteratorData* data) { - assert(data != NULL); + assert(data); return data->dirinfo.front().name; } uint64_t IteratorDataSize(const IteratorData* data) { - assert(data != NULL); + assert(data); return data->dirinfo.front().size; } int64_t IteratorDataModified(const IteratorData* data) { - assert(data != NULL); + assert(data); return data->dirinfo.front().modified; } bool IteratorDataIsFolder(const IteratorData* data) { - assert(data != NULL); + assert(data); return data->dirinfo.front().isFolder; } bool IteratorDataIsFile(const IteratorData* data) { - assert(data != NULL); + assert(data); return !data->dirinfo.front().isFolder; } diff --git a/src/ext/yuni/src/yuni/io/directory/iterator/iterator.cpp b/src/ext/yuni/src/yuni/io/directory/iterator/iterator.cpp index 2bcbd5743c..c4ddc8f573 100644 --- a/src/ext/yuni/src/yuni/io/directory/iterator/iterator.cpp +++ b/src/ext/yuni/src/yuni/io/directory/iterator/iterator.cpp @@ -148,7 +148,7 @@ Flow TraverseWindowsFolder(const String& filename, bool files) { // Convertir the filename - assert(opts.wbuffer != NULL); + assert(opts.wbuffer); opts.wbuffer[0] = L'\\'; opts.wbuffer[1] = L'\\'; opts.wbuffer[2] = L'?'; @@ -199,12 +199,12 @@ Flow TraverseWindowsFolder(const String& filename, } const int sizeRequired - = WideCharToMultiByte(CP_UTF8, 0, data.cFileName, -1, NULL, 0, NULL, NULL); + = WideCharToMultiByte(CP_UTF8, 0, data.cFileName, -1, nullptr, 0, nullptr, nullptr); if (sizeRequired <= 0) continue; newName.reserve((uint)sizeRequired); WideCharToMultiByte( - CP_UTF8, 0, data.cFileName, -1, (char*)newName.data(), sizeRequired, NULL, NULL); + CP_UTF8, 0, data.cFileName, -1, (char*)newName.data(), sizeRequired, nullptr, nullptr); newName.resize(((uint)sizeRequired) - 1); newFilename.clear(); diff --git a/src/ext/yuni/src/yuni/io/directory/remove.cpp b/src/ext/yuni/src/yuni/io/directory/remove.cpp index e35f9664f9..e5a936599a 100644 --- a/src/ext/yuni/src/yuni/io/directory/remove.cpp +++ b/src/ext/yuni/src/yuni/io/directory/remove.cpp @@ -73,7 +73,7 @@ static bool RmDirRecursiveInternal(const AnyString& path) buffer.clear() << path << SEP << (const char*)ep->d_name; ::unlink(buffer.c_str()); } - } while (NULL != (ep = ::readdir(dp))); + } while (nullptr != (ep = ::readdir(dp))); } (void)::closedir(dp); } diff --git a/src/ext/yuni/src/yuni/io/file/file.cpp b/src/ext/yuni/src/yuni/io/file/file.cpp index efe0dc80f8..9613b25b1d 100644 --- a/src/ext/yuni/src/yuni/io/file/file.cpp +++ b/src/ext/yuni/src/yuni/io/file/file.cpp @@ -71,7 +71,7 @@ bool Size(const AnyString& filename, uint64_t& value) } HANDLE hndl = CreateFileW( - wstr.c_str(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + wstr.c_str(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hndl == INVALID_HANDLE_VALUE) { value = 0u; @@ -158,7 +158,7 @@ bool GetLastWriteTime(HANDLE hFile) // Convert the last-write time to local time. if (!FileTimeToSystemTime(&ftWrite, &stUTC)) return false; - if (!SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal)) + if (!SystemTimeToTzSpecificLocalTime(nullptr, &stUTC, &stLocal)) return false; return true; diff --git a/src/ext/yuni/src/yuni/io/file/stream.cpp b/src/ext/yuni/src/yuni/io/file/stream.cpp index 8815990c22..6d5c2cf375 100644 --- a/src/ext/yuni/src/yuni/io/file/stream.cpp +++ b/src/ext/yuni/src/yuni/io/file/stream.cpp @@ -121,7 +121,7 @@ bool Stream::open(const AnyString& filename, int mode) pFd = ::fopen(filename.c_str(), OpenMode::ToCString(mode)); #endif - return (NULL != pFd); + return (pFd); } bool Stream::close() @@ -130,7 +130,7 @@ bool Stream::close() { if (0 == ::fclose(pFd)) { - pFd = NULL; + pFd = nullptr; return true; } return false; diff --git a/src/ext/yuni/src/yuni/job/job.cpp b/src/ext/yuni/src/yuni/job/job.cpp index bef4051930..125bae6f51 100644 --- a/src/ext/yuni/src/yuni/job/job.cpp +++ b/src/ext/yuni/src/yuni/job/job.cpp @@ -21,14 +21,14 @@ IJob::IJob() : pThread(nullptr) IJob::~IJob() { - assert(this != NULL and "IJob: Destructor: Oo `this' is null !?"); - assert(pThread == NULL and "A job can not be attached to a thread when destroyed"); + assert(this && "IJob: Destructor: Oo `this' is null !?"); + assert(!pThread && "A job can not be attached to a thread when destroyed"); } bool IJob::suspend(uint delay) const { // This method must only be called from a thread - assert(pThread and "Job: The pointer to the attached thread must not be NULL"); + assert(pThread and "Job: The pointer to the attached thread must not be nullptr"); // We can suspend the job only if it is running if (pState == stateRunning) diff --git a/src/ext/yuni/src/yuni/job/queue/service.cpp b/src/ext/yuni/src/yuni/job/queue/service.cpp index 775f456cd3..18fe860903 100644 --- a/src/ext/yuni/src/yuni/job/queue/service.cpp +++ b/src/ext/yuni/src/yuni/job/queue/service.cpp @@ -37,14 +37,14 @@ static inline uint OptimalCPUCount() return count; } -QueueService::QueueService() : pStatus(sStopped), pThreads(NULL) +QueueService::QueueService() : pStatus(sStopped), pThreads(nullptr) { uint count = OptimalCPUCount(); pMinimumThreadCount = count; pMaximumThreadCount = count; } -QueueService::QueueService(bool autostart) : pStatus(sStopped), pThreads(NULL) +QueueService::QueueService(bool autostart) : pStatus(sStopped), pThreads(nullptr) { uint count = OptimalCPUCount(); pMinimumThreadCount = count; @@ -172,7 +172,7 @@ void QueueService::stop(uint timeout) return; threads = (ThreadArray*)pThreads; - pThreads = NULL; + pThreads = nullptr; pStatus = sStopping; } diff --git a/src/ext/yuni/src/yuni/thread/signal.cpp b/src/ext/yuni/src/yuni/thread/signal.cpp index 335d61fd20..9da95f2dde 100644 --- a/src/ext/yuni/src/yuni/thread/signal.cpp +++ b/src/ext/yuni/src/yuni/thread/signal.cpp @@ -33,10 +33,10 @@ Signal::Signal() // Making sure that our pseudo HANDLE type is valid assert(sizeof(HANDLE) >= sizeof(void*) and "Invalid type for Signal::pHandle"); - pHandle = (void*)CreateEvent(NULL, // default security attributes + pHandle = (void*)CreateEvent(nullptr, // default security attributes TRUE, // manual-reset event FALSE, // initial state is nonsignaled - NULL); // unamed + nullptr); // unamed #else pSignalled = false; @@ -53,10 +53,10 @@ Signal::Signal(const Signal&) // Making sure that our pseudo HANDLE type is valid assert(sizeof(HANDLE) >= sizeof(void*) and "Invalid type for Signal::pHandle"); - pHandle = (void*)CreateEvent(NULL, // default security attributes + pHandle = (void*)CreateEvent(nullptr, // default security attributes TRUE, // manual-reset event FALSE, // initial state is nonsignaled - NULL); // unamed + nullptr); // unamed #else pSignalled = false; @@ -194,7 +194,7 @@ bool Signal::wait(uint timeout) // Set the timespec t at [timeout] milliseconds in the future. assert(timeout < 2147483648u and "Invalid range for timeout (Signal::wait(timeout))"); - YUNI_SYSTEM_GETTIMEOFDAY(&now, NULL); + YUNI_SYSTEM_GETTIMEOFDAY(&now, nullptr); t.tv_nsec = (long)(now.tv_usec * 1000 + (((int)timeout % 1000) * 1000000)); t.tv_sec = (time_t)(now.tv_sec + timeout / 1000 + (t.tv_nsec / 1000000000L)); t.tv_nsec %= 1000000000L; diff --git a/src/ext/yuni/src/yuni/thread/thread.cpp b/src/ext/yuni/src/yuni/thread/thread.cpp index 048455b281..c8eb06dd9f 100644 --- a/src/ext/yuni/src/yuni/thread/thread.cpp +++ b/src/ext/yuni/src/yuni/thread/thread.cpp @@ -89,8 +89,8 @@ extern "C" YUNI_THREAD_FNC_RETURN threadCallbackExecute(void* arg) #ifndef YUNI_OS_WINDOWS // pthread - Adjust cancellation behaviors - // ::pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - ::pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + // ::pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); + ::pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr); #endif if (thread.onStarting()) diff --git a/src/ext/yuni/src/yuni/uuid/uuid.cpp b/src/ext/yuni/src/yuni/uuid/uuid.cpp index be2e1cc2db..d151ceca1b 100644 --- a/src/ext/yuni/src/yuni/uuid/uuid.cpp +++ b/src/ext/yuni/src/yuni/uuid/uuid.cpp @@ -69,7 +69,7 @@ void UUID::writeToCString(char cstring[42]) const bool UUID::initializeFromCString(const char* cstring) { - assert(cstring != NULL); + assert(cstring != nullptr); #ifndef YUNI_OS_WINDOWS // Why uuid_parse takes a char* and not a const char* ?? diff --git a/src/libs/antares/args/args_to_utf8.cpp b/src/libs/antares/args/args_to_utf8.cpp index 522c176565..15b7db618b 100644 --- a/src/libs/antares/args/args_to_utf8.cpp +++ b/src/libs/antares/args/args_to_utf8.cpp @@ -53,10 +53,10 @@ std::pair IntoUTF8ArgsTranslator::convert() for (int i = 0; i != argc_; ++i) { const uint len = (uint)wcslen(wargv[i]); - const uint newLen = WideCharToMultiByte(CP_UTF8, 0, wargv[i], len, NULL, 0, NULL, NULL); + const uint newLen = WideCharToMultiByte(CP_UTF8, 0, wargv[i], len, nullptr, 0, nullptr, nullptr); argv_[i] = (char*)malloc((newLen + 1) * sizeof(char)); memset(argv_[i], 0, (newLen + 1) * sizeof(char)); - WideCharToMultiByte(CP_UTF8, 0, wargv[i], len, argv_[i], newLen, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, wargv[i], len, argv_[i], newLen, nullptr, nullptr); argv_[i][newLen] = '\0'; } #endif diff --git a/src/libs/antares/correlation/correlation.cpp b/src/libs/antares/correlation/correlation.cpp index 84c39b974f..50b4084bf1 100644 --- a/src/libs/antares/correlation/correlation.cpp +++ b/src/libs/antares/correlation/correlation.cpp @@ -212,13 +212,13 @@ int InterAreaCorrelationLoadFromIniFile(Matrix<>* m, AreaList* l, IniFile* ini, if (ini) { IniFile::Section* s; - for (s = ini->firstSection; s != NULL; s = s->next) /* Each section */ + for (s = ini->firstSection; s; s = s->next) /* Each section */ { Area* from = AreaListLFind(l, s->name.c_str()); if (from) { IniFile::Property* p; - for (p = s->firstProperty; p != NULL; p = p->next) /* Each property*/ + for (p = s->firstProperty; p; p = p->next) /* Each property*/ { Area* to = AreaListLFind(l, p->key.c_str()); if (to and to != from) diff --git a/src/libs/antares/locale/locale.cpp b/src/libs/antares/locale/locale.cpp index 7fcbc420ba..fd74ea2af4 100644 --- a/src/libs/antares/locale/locale.cpp +++ b/src/libs/antares/locale/locale.cpp @@ -31,13 +31,13 @@ namespace Antares void InitializeDefaultLocale() { #ifdef YUNI_OS_WINDOWS - if (NULL == std::setlocale(LC_ALL, "English")) + if (!std::setlocale(LC_ALL, "English")) { std::cerr << "impossible to set locale to English" << std::endl; } #else - if (NULL == std::setlocale(LC_ALL, "en_US.utf8")) + if (! std::setlocale(LC_ALL, "en_US.utf8")) { std::cerr << "impossible to set locale to en_US.utf8" << std::endl; } diff --git a/src/libs/antares/resources/resources.cpp b/src/libs/antares/resources/resources.cpp index cbd3122d18..650d10e99a 100644 --- a/src/libs/antares/resources/resources.cpp +++ b/src/libs/antares/resources/resources.cpp @@ -136,7 +136,7 @@ bool FindExampleFolder(Yuni::String& folder) void Initialize(int argc, char** argv, bool initializeSearchPath) { - if (argc < 1 or argv[0] == NULL) + if (argc < 1 or !argv[0]) { logs.error() << "Impossible to find the root folder"; return; diff --git a/src/libs/fswalker/fswalker.cpp b/src/libs/fswalker/fswalker.cpp index 25a188798e..f1022fe1bd 100644 --- a/src/libs/fswalker/fswalker.cpp +++ b/src/libs/fswalker/fswalker.cpp @@ -267,7 +267,7 @@ bool WalkerThread::triggerFileEvent(const String& filename, int64_t modified, uint64_t size) { - assert(pFileJob != NULL); + assert(pFileJob); // Statistics ++statistics.fileCount; @@ -320,7 +320,7 @@ void WalkerThread::walk(const String& path) do { - assert(pContext.top() != NULL); + assert(pContext.top() ); auto& context = *(pContext.top()); if (pShouldStop) diff --git a/src/solver/constraints-builder/cbuilder.cpp b/src/solver/constraints-builder/cbuilder.cpp index a49806ff16..d713aa7307 100644 --- a/src/solver/constraints-builder/cbuilder.cpp +++ b/src/solver/constraints-builder/cbuilder.cpp @@ -399,12 +399,12 @@ bool CBuilder::completeCBuilderFromFile(const std::string& filename) CString<50, false> key; CString<50, false> value; - for (section = ini.firstSection; section != NULL; section = section->next) + for (section = ini.firstSection; section ; section = section->next) { if (section->name == ".general") { IniFile::Property* p = section->firstProperty; - for (; p != NULL; p = p->next) + for (; p ; p = p->next) { key = p->key; key.toLower(); diff --git a/src/solver/hydro/daily/h2o_j_construire_les_variables.cpp b/src/solver/hydro/daily/h2o_j_construire_les_variables.cpp index 117d8ace5a..98ab62116c 100644 --- a/src/solver/hydro/daily/h2o_j_construire_les_variables.cpp +++ b/src/solver/hydro/daily/h2o_j_construire_les_variables.cpp @@ -57,14 +57,14 @@ void H2O_j_ConstruireLesVariables( Xmin[Var] = 0.0; Xmax[Var] = LINFINI; TypeDeVariable[Var] = VARIABLE_BORNEE_INFERIEUREMENT; - AdresseOuPlacerLaValeurDesVariablesOptimisees[Var] = NULL; + AdresseOuPlacerLaValeurDesVariablesOptimisees[Var] = nullptr; Var++; CorrespondanceDesVariables.NumeroDeLaVariableXi = Var; Xmin[Var] = 0.0; Xmax[Var] = LINFINI; TypeDeVariable[Var] = VARIABLE_BORNEE_INFERIEUREMENT; - AdresseOuPlacerLaValeurDesVariablesOptimisees[Var] = NULL; + AdresseOuPlacerLaValeurDesVariablesOptimisees[Var] = nullptr; Var++; return; diff --git a/src/solver/hydro/daily/h2o_j_resoudre_le_probleme_lineaire.cpp b/src/solver/hydro/daily/h2o_j_resoudre_le_probleme_lineaire.cpp index f4e727adc9..1786428cef 100644 --- a/src/solver/hydro/daily/h2o_j_resoudre_le_probleme_lineaire.cpp +++ b/src/solver/hydro/daily/h2o_j_resoudre_le_probleme_lineaire.cpp @@ -135,7 +135,7 @@ void H2O_J_ResoudreLeProblemeLineaire(DONNEES_MENSUELLES* DonneesMensuelles, int { SPX_LibererProbleme(ProbSpx); - ProbSpx = NULL; + ProbSpx = nullptr; PremierPassage = false; goto RESOLUTION; } diff --git a/src/solver/hydro/daily2/h2o2_j_resoudre_le_probleme_lineaire.cpp b/src/solver/hydro/daily2/h2o2_j_resoudre_le_probleme_lineaire.cpp index e5b4f7411f..a0366dce53 100644 --- a/src/solver/hydro/daily2/h2o2_j_resoudre_le_probleme_lineaire.cpp +++ b/src/solver/hydro/daily2/h2o2_j_resoudre_le_probleme_lineaire.cpp @@ -135,7 +135,7 @@ void H2O2_J_ResoudreLeProblemeLineaire(DONNEES_MENSUELLES_ETENDUES& DonneesMensu { SPX_LibererProbleme(ProbSpx); - ProbSpx = NULL; + ProbSpx = nullptr; premierPassage = false; goto RESOLUTION; } diff --git a/src/solver/hydro/monthly/h2o_m_resoudre_le_probleme_lineaire.cpp b/src/solver/hydro/monthly/h2o_m_resoudre_le_probleme_lineaire.cpp index 75f8178c79..f65ec03e6e 100644 --- a/src/solver/hydro/monthly/h2o_m_resoudre_le_probleme_lineaire.cpp +++ b/src/solver/hydro/monthly/h2o_m_resoudre_le_probleme_lineaire.cpp @@ -132,7 +132,7 @@ void H2O_M_ResoudreLeProblemeLineaire(DONNEES_ANNUELLES& DonneesAnnuelles, int N { SPX_LibererProbleme(ProbSpx); - ProbSpx = NULL; + ProbSpx = nullptr; PremierPassage = false; goto RESOLUTION; } diff --git a/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp b/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp index b067eb6431..e21039e14f 100644 --- a/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp +++ b/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp @@ -31,7 +31,7 @@ void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeQuadratique(PROBLEME_HEBDO* problemeHebdo) { const auto& ProblemeAResoudre = problemeHebdo->ProblemeAResoudre; - assert(ProblemeAResoudre != NULL); + assert(ProblemeAResoudre ); int nombreDeVariables = 0; auto variableManager = VariableManagerFromProblemHebdo(problemeHebdo); diff --git a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp index 5bdbeef705..398af7b814 100644 --- a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp @@ -308,8 +308,8 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob TypeDeVariable[var] = VARIABLE_BORNEE_INFERIEUREMENT; } Xmin[var] = 0.0; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; var = variableManager.IntercoIndirectCost(interco, pdtJour); if (CoutDeTransport.IntercoGereeAvecLoopFlow) @@ -329,8 +329,8 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob TypeDeVariable[var] = VARIABLE_BORNEE_INFERIEUREMENT; } Xmin[var] = 0.0; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; } } @@ -382,16 +382,16 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob { Xmin[var] = 0.0; Xmax[var] = LINFINI_ANTARES; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; } var = variableManager.HydProdUp(pays, pdtJour); if (var >= 0 && var < ProblemeAResoudre->NombreDeVariables) { Xmin[var] = 0.0; Xmax[var] = LINFINI_ANTARES; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; } } else if (problemeHebdo->TypeDeLissageHydraulique @@ -404,8 +404,8 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob Xmin[var] = 0.0; Xmax[var] = problemeHebdo->CaracteristiquesHydrauliques[pays] .MaxDesPmaxHydrauliques; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; } var = variableManager.HydProdUp(pays, pdtJour); @@ -414,8 +414,8 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob Xmin[var] = 0.0; Xmax[var] = problemeHebdo->CaracteristiquesHydrauliques[pays] .MaxDesPmaxHydrauliques; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; } } } @@ -440,8 +440,8 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob Xmin[var] = 0.0; Xmax[var] = problemeHebdo->CaracteristiquesHydrauliques[pays] .ApportNaturelHoraire[pdtHebdo]; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; } var = variableManager.HydroLevel(pays, pdtJour); @@ -453,7 +453,7 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob .NiveauHoraireSup[pdtHebdo]; double* adresseDuResultat = &( problemeHebdo->ResultatsHoraires[pays].niveauxHoraires[pdtHebdo]); - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = adresseDuResultat; } @@ -492,14 +492,14 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob Xmin[var] = -(LINFINI_ANTARES); Xmax[var] = LINFINI_ANTARES; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; // Note: if there were a single optimization run instead of two; the following // could be used: adresseDuResultat = //&(problemeHebdo->CaracteristiquesHydrauliques[pays].LevelForTimeInterval); // AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = adresseDuResultat; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; } for (uint nblayer = 0; nblayer < 100; nblayer++) { @@ -510,8 +510,8 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob Xmax[var] = problemeHebdo->CaracteristiquesHydrauliques[pays].TailleReservoir / double(100); - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = NULL; - AdresseOuPlacerLaValeurDesCoutsReduits[var] = NULL; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; + AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; } } } diff --git a/src/solver/optimisation/opt_liberation_problemes_simplexe.cpp b/src/solver/optimisation/opt_liberation_problemes_simplexe.cpp index 0ad9462dc4..df0a9b4e37 100644 --- a/src/solver/optimisation/opt_liberation_problemes_simplexe.cpp +++ b/src/solver/optimisation/opt_liberation_problemes_simplexe.cpp @@ -64,12 +64,12 @@ void OPT_LiberationProblemesSimplexe(const OptimizationOptions& options, if (options.ortoolsUsed && solver) { ORTOOLS_LibererProbleme(solver); - solver = NULL; + solver = nullptr; } - else if (ProbSpx != NULL) + else if (ProbSpx) { SPX_LibererProbleme(ProbSpx); - ProbSpx = NULL; + ProbSpx = nullptr; } } } diff --git a/src/solver/ts-generator/xcast/math.cpp b/src/solver/ts-generator/xcast/math.cpp index 0205c170a0..e9d34559ac 100644 --- a/src/solver/ts-generator/xcast/math.cpp +++ b/src/solver/ts-generator/xcast/math.cpp @@ -30,7 +30,7 @@ namespace XCast { void XCast::normal(float& x, float& y) { - assert(random != NULL); + assert(random); double z; double xd; diff --git a/src/tests/src/solver/simulation/tests-ts-numbers.cpp b/src/tests/src/solver/simulation/tests-ts-numbers.cpp index e82d432121..9767cbe525 100644 --- a/src/tests/src/solver/simulation/tests-ts-numbers.cpp +++ b/src/tests/src/solver/simulation/tests-ts-numbers.cpp @@ -55,7 +55,7 @@ void initializeStudy(Study::Ptr study, unsigned int nbYears = 1) Area* addAreaToStudy(Study::Ptr study, const std::string& areaName) { Area* area = study->areaAdd(areaName); - BOOST_CHECK(area != NULL); + BOOST_CHECK(area); return area; } diff --git a/src/tools/yby-aggregator/result.cpp b/src/tools/yby-aggregator/result.cpp index d92dd1c246..fa0fea177a 100644 --- a/src/tools/yby-aggregator/result.cpp +++ b/src/tools/yby-aggregator/result.cpp @@ -61,7 +61,7 @@ ResultMatrix::ResultMatrix(): } ResultMatrix::ResultMatrix(const ResultMatrix&): - columns(NULL), + columns(nullptr), width(0), heightAfterAggregation(0) { diff --git a/src/ui/action/handler/antares-study/area/create.cpp b/src/ui/action/handler/antares-study/area/create.cpp index cc671fec5d..4b9bd41a68 100644 --- a/src/ui/action/handler/antares-study/area/create.cpp +++ b/src/ui/action/handler/antares-study/area/create.cpp @@ -221,7 +221,7 @@ bool Create::performWL(Context& ctx) } } ctx.autoselectAreas.push_back(ctx.area); - return (ctx.area != NULL); + return (ctx.area); } void Create::createActionsForAStandardAreaCopy(Context& ctx, bool copyPosition) diff --git a/src/ui/action/handler/antares-study/constraint/create.cpp b/src/ui/action/handler/antares-study/constraint/create.cpp index 11425b2d51..fe223495e1 100644 --- a/src/ui/action/handler/antares-study/constraint/create.cpp +++ b/src/ui/action/handler/antares-study/constraint/create.cpp @@ -200,7 +200,7 @@ bool Create::performWL(Context& ctx) // ctx.constraint->type(pType); } ctx.autoselectConstraints.push_back(ctx.constraint); - return (ctx.constraint != NULL); + return (ctx.constraint != nullptr); } void Create::createActionsForAStandardConstraintCopy(Context&) diff --git a/src/ui/action/handler/antares-study/constraint/offsets.cpp b/src/ui/action/handler/antares-study/constraint/offsets.cpp index 5ecd0eb35e..8bf90571ec 100644 --- a/src/ui/action/handler/antares-study/constraint/offsets.cpp +++ b/src/ui/action/handler/antares-study/constraint/offsets.cpp @@ -33,7 +33,7 @@ namespace AntaresStudy namespace Constraint { Offsets::Offsets(const AnyString& name, Antares::Data::ConstraintName targetName) : - pOriginalConstraintName(name), targetName(targetName), pCurrentContext(NULL) + pOriginalConstraintName(name), targetName(targetName), pCurrentContext(nullptr) { pInfos.caption << "Offsets"; } diff --git a/src/ui/action/handler/antares-study/constraint/weights.cpp b/src/ui/action/handler/antares-study/constraint/weights.cpp index 865a57ec62..ad9691ace5 100644 --- a/src/ui/action/handler/antares-study/constraint/weights.cpp +++ b/src/ui/action/handler/antares-study/constraint/weights.cpp @@ -33,7 +33,7 @@ namespace AntaresStudy namespace Constraint { Weights::Weights(const AnyString& name, Antares::Data::ConstraintName targetName) : - pOriginalConstraintName(name), targetName(targetName), pCurrentContext(NULL) + pOriginalConstraintName(name), targetName(targetName), pCurrentContext(nullptr) { pInfos.caption << "Weights"; } diff --git a/src/ui/action/handler/antares-study/thermal-cluster/create.cpp b/src/ui/action/handler/antares-study/thermal-cluster/create.cpp index 495d434d5f..6a71b98626 100644 --- a/src/ui/action/handler/antares-study/thermal-cluster/create.cpp +++ b/src/ui/action/handler/antares-study/thermal-cluster/create.cpp @@ -182,7 +182,7 @@ bool Create::performWL(Context& ctx) if (pInfos.behavior == bhOverwrite) (ctx.cluster)->reset(); } - return (ctx.area != NULL); + return (ctx.area != nullptr); } return true; } diff --git a/src/ui/common/component/panel/panel.cpp b/src/ui/common/component/panel/panel.cpp index c2c20c5cf0..03ff527c59 100644 --- a/src/ui/common/component/panel/panel.cpp +++ b/src/ui/common/component/panel/panel.cpp @@ -40,9 +40,9 @@ Panel::Panel(wxWindow* parent) : { assert(parent && "invalid parent"); - Connect(GetId(), wxEVT_MOTION, wxMouseEventHandler(Panel::onInternalMotion), NULL, this); - Connect(GetId(), wxEVT_LEFT_DOWN, wxMouseEventHandler(Panel::onInternalMouseDown), NULL, this); - Connect(GetId(), wxEVT_LEFT_UP, wxMouseEventHandler(Panel::onInternalMouseUp), NULL, this); + Connect(GetId(), wxEVT_MOTION, wxMouseEventHandler(Panel::onInternalMotion), nullptr, this); + Connect(GetId(), wxEVT_LEFT_DOWN, wxMouseEventHandler(Panel::onInternalMouseDown), nullptr, this); + Connect(GetId(), wxEVT_LEFT_UP, wxMouseEventHandler(Panel::onInternalMouseUp), nullptr, this); } Panel::~Panel() diff --git a/src/ui/common/component/spotlight/spotlight.cpp b/src/ui/common/component/spotlight/spotlight.cpp index 661670dfac..09e381034e 100644 --- a/src/ui/common/component/spotlight/spotlight.cpp +++ b/src/ui/common/component/spotlight/spotlight.cpp @@ -122,7 +122,7 @@ void Spotlight::createComponents(Spotlight* parent, bool input, bool results) wxDefaultPosition, wxDefaultSize, 0, - NULL, + nullptr, wxCB_READONLY); pLayerFilter->SetFont(wxFont(wxFontInfo().Bold())); pLayerFilter->AppendString("All"); @@ -429,9 +429,9 @@ void Spotlight::resizeParentWindow() parent->SetSize(parent->GetSize().GetWidth(), idealH); } - assert(parent->GetSizer() != NULL); + assert(parent->GetSizer()); parent->GetSizer()->Layout(); - assert(GetSizer() != NULL); + assert(GetSizer()); GetSizer()->Layout(); Dispatcher::GUI::Refresh(parent); } diff --git a/src/ui/simulator/application/main/build/economic-optimization.cpp b/src/ui/simulator/application/main/build/economic-optimization.cpp index 7c1ddb66c3..f11c7865e2 100644 --- a/src/ui/simulator/application/main/build/economic-optimization.cpp +++ b/src/ui/simulator/application/main/build/economic-optimization.cpp @@ -34,7 +34,7 @@ namespace Forms { void ApplWnd::createNBNodalOptimization() { - assert(NULL != pNotebook); + assert(pNotebook); // Create a standard page with an input selector std::pair page diff --git a/src/ui/simulator/application/main/build/load.cpp b/src/ui/simulator/application/main/build/load.cpp index 98cdfb69e8..917279955b 100644 --- a/src/ui/simulator/application/main/build/load.cpp +++ b/src/ui/simulator/application/main/build/load.cpp @@ -35,7 +35,7 @@ namespace Forms { void ApplWnd::createNBLoad() { - assert(NULL != pNotebook); + assert(pNotebook); // Create a standard page with an input selector std::pair page diff --git a/src/ui/simulator/application/main/build/notes.cpp b/src/ui/simulator/application/main/build/notes.cpp index 9e9f6fb585..fcca4f545b 100644 --- a/src/ui/simulator/application/main/build/notes.cpp +++ b/src/ui/simulator/application/main/build/notes.cpp @@ -30,7 +30,7 @@ namespace Forms { void ApplWnd::createNBNotes() { - assert(NULL != pNotebook); + assert(pNotebook); pUserNotes = new Window::Notes(pNotebook); pNotebook->add(pUserNotes, wxT("notes"), wxT("User's Notes")); diff --git a/src/ui/simulator/application/main/build/sets.cpp b/src/ui/simulator/application/main/build/sets.cpp index bbd139fba1..c6119f3d93 100644 --- a/src/ui/simulator/application/main/build/sets.cpp +++ b/src/ui/simulator/application/main/build/sets.cpp @@ -30,7 +30,7 @@ namespace Forms { void ApplWnd::createNBSets() { - assert(NULL != pNotebook); + assert(pNotebook); pSets = new Window::Sets(pNotebook); pNotebook->add(pSets, wxT("sets"), wxT("")); diff --git a/src/ui/simulator/application/main/build/solar.cpp b/src/ui/simulator/application/main/build/solar.cpp index a2d6d25657..6c9f29cea1 100644 --- a/src/ui/simulator/application/main/build/solar.cpp +++ b/src/ui/simulator/application/main/build/solar.cpp @@ -35,7 +35,7 @@ namespace Forms { void ApplWnd::createNBSolar() { - assert(NULL != pNotebook); + assert(pNotebook); // Create a standard page with an input selector std::pair page diff --git a/src/ui/simulator/application/main/build/wind.cpp b/src/ui/simulator/application/main/build/wind.cpp index c4f28409b6..73dce91d73 100644 --- a/src/ui/simulator/application/main/build/wind.cpp +++ b/src/ui/simulator/application/main/build/wind.cpp @@ -35,7 +35,7 @@ namespace Forms { void ApplWnd::createNBWind() { - assert(NULL != pNotebook); + assert(pNotebook); // Create a standard page with an input selector std::pair page diff --git a/src/ui/simulator/application/main/internal-data.cpp b/src/ui/simulator/application/main/internal-data.cpp index 36468656c6..07a9788001 100644 --- a/src/ui/simulator/application/main/internal-data.cpp +++ b/src/ui/simulator/application/main/internal-data.cpp @@ -32,7 +32,7 @@ MainFormData::MainFormData(ApplWnd& form) : wipEnabled(false), wipPanel(nullptr) void MainFormData::editCurrentLocation(const wxString& string) { - assert(pEditCurrentLocation != NULL); + assert(pEditCurrentLocation); pEditCurrentLocation->SetItemLabel(wxString(wxT("Current tab : ")) << string); } diff --git a/src/ui/simulator/application/main/logs.cpp b/src/ui/simulator/application/main/logs.cpp index 9be770b174..c2e47bd0a4 100644 --- a/src/ui/simulator/application/main/logs.cpp +++ b/src/ui/simulator/application/main/logs.cpp @@ -172,7 +172,7 @@ void ApplWnd::destroyLogs() if (pLogFlusherTimer) { wxTimer* timer = pLogFlusherTimer; - pLogFlusherTimer = NULL; + pLogFlusherTimer = nullptr; delete timer; } } @@ -196,7 +196,7 @@ void ApplWnd::destroyLogsViewer() if (pWndLogs) { pWndLogs->Destroy(); - pWndLogs = NULL; + pWndLogs = nullptr; } } diff --git a/src/ui/simulator/application/main/notes.cpp b/src/ui/simulator/application/main/notes.cpp index 4c0cbb62d5..60e2c17c08 100644 --- a/src/ui/simulator/application/main/notes.cpp +++ b/src/ui/simulator/application/main/notes.cpp @@ -31,25 +31,25 @@ namespace Forms { void ApplWnd::loadUserNotes() { - assert(NULL != pUserNotes); + assert(pUserNotes); pUserNotes->loadFromStudy(); } void ApplWnd::saveUserNotes() { - assert(NULL != pUserNotes); + assert(pUserNotes); pUserNotes->saveToStudy(); } void ApplWnd::loadSets() { - assert(NULL != pSets); + assert(pSets); pSets->loadFromStudy(); } void ApplWnd::saveSets() { - assert(NULL != pSets); + assert(pSets); pSets->saveToStudy(); } diff --git a/src/ui/simulator/application/main/options.cpp b/src/ui/simulator/application/main/options.cpp index eb8389a229..3b8fc01098 100644 --- a/src/ui/simulator/application/main/options.cpp +++ b/src/ui/simulator/application/main/options.cpp @@ -73,7 +73,7 @@ void ApplWnd::evtOnOptionsDistricts(wxCommandEvent&) Forms::Disabler disabler(*this); if (CurrentStudyIsValid()) { - assert(NULL != pNotebook); + assert(pNotebook); pNotebook->select("sets"); } } diff --git a/src/ui/simulator/application/main/refresh.cpp b/src/ui/simulator/application/main/refresh.cpp index 587c38bdbc..88c36a57cb 100644 --- a/src/ui/simulator/application/main/refresh.cpp +++ b/src/ui/simulator/application/main/refresh.cpp @@ -315,7 +315,7 @@ void ApplWnd::refreshMenuOutput() it->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(Forms::ApplWnd::evtOnOpenOutputInExplorer), - NULL, + nullptr, parentForm); } } diff --git a/src/ui/simulator/toolbox/components/button/button.cpp b/src/ui/simulator/toolbox/components/button/button.cpp index 3bdab39981..9fbb2b9118 100644 --- a/src/ui/simulator/toolbox/components/button/button.cpp +++ b/src/ui/simulator/toolbox/components/button/button.cpp @@ -158,7 +158,7 @@ void Button::loadIconFromResource(const char* filename) void Button::precalculateCoordinates() { // Assert - assert(this != NULL && "Button: this must not be null"); + assert(this != nullptr && "Button: this must not be null"); assert(iconMargin <= 128 && "Button: The margin seems suspicious"); if (pCaption.empty()) diff --git a/src/ui/simulator/toolbox/components/datagrid/component.cpp b/src/ui/simulator/toolbox/components/datagrid/component.cpp index e33bb0ea63..75f3196901 100644 --- a/src/ui/simulator/toolbox/components/datagrid/component.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/component.cpp @@ -517,7 +517,7 @@ void InternalState::createAllInternalControls(const CreateOptions& flags) wxDefaultPosition, wxSize(-1, 22), 0, - NULL, + nullptr, wxCB_READONLY); pLayerFilter->SetFont(wxFont(wxFontInfo().Bold())); pLayerFilter->AppendString("All"); diff --git a/src/ui/simulator/toolbox/components/datagrid/filter/operator.cpp b/src/ui/simulator/toolbox/components/datagrid/filter/operator.cpp index d54c277824..ef4d2e1997 100644 --- a/src/ui/simulator/toolbox/components/datagrid/filter/operator.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/filter/operator.cpp @@ -30,7 +30,7 @@ namespace Filter namespace Operator { AOperator::AOperator(AFilterBase* parent, const wxChar* name, const wxChar* caption) : - pParentFilter(parent), pName(name), pCaption(caption), pSizer(NULL) + pParentFilter(parent), pName(name), pCaption(caption), pSizer(nullptr) { parameters.push_back(Parameter(*this).presetInt()); } diff --git a/src/ui/simulator/toolbox/components/datagrid/filter/parameter/parameter.cpp b/src/ui/simulator/toolbox/components/datagrid/filter/parameter/parameter.cpp index 0235fd86fe..1e6711a8ee 100644 --- a/src/ui/simulator/toolbox/components/datagrid/filter/parameter/parameter.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/filter/parameter/parameter.cpp @@ -38,7 +38,7 @@ namespace Filter namespace Operator { Parameter::Parameter(AOperator& parent) : - pOperator(parent), dataType(DataType::dtNone), pSizer(NULL) + pOperator(parent), dataType(DataType::dtNone), pSizer(nullptr) { } @@ -50,7 +50,7 @@ Parameter::Parameter(const Parameter& copy) : dataType(copy.dataType), defaultValues(copy.defaultValues), value(copy.value), - pSizer(NULL) + pSizer(nullptr) { } @@ -70,7 +70,7 @@ Parameter& Parameter::operator=(const Parameter& copy) wxSizer* Parameter::sizer(wxWindow* parent) { - if (NULL == pSizer) + if (nullptr == pSizer) { pSizer = new wxBoxSizer(wxHORIZONTAL); @@ -95,7 +95,7 @@ wxSizer* Parameter::sizer(wxWindow* parent) ch->Connect(ch->GetId(), wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(Parameter::onListChanged), - NULL, + nullptr, this); break; } @@ -125,7 +125,7 @@ wxSizer* Parameter::sizer(wxWindow* parent) edit->Connect(edit->GetId(), wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(Parameter::onChange), - NULL, + nullptr, this); } } diff --git a/src/ui/simulator/toolbox/components/datagrid/filter/static.cpp b/src/ui/simulator/toolbox/components/datagrid/filter/static.cpp index b7d29a319e..b5f055a1ca 100644 --- a/src/ui/simulator/toolbox/components/datagrid/filter/static.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/filter/static.cpp @@ -63,7 +63,7 @@ struct ResultNewInstance using Type = AFilterBase*; static AFilterBase* Default() { - return NULL; + return nullptr; } static T* Value(Input* parent) { diff --git a/src/ui/simulator/toolbox/components/datagrid/gridhelper.cpp b/src/ui/simulator/toolbox/components/datagrid/gridhelper.cpp index 62435e993b..9b6d962f95 100644 --- a/src/ui/simulator/toolbox/components/datagrid/gridhelper.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/gridhelper.cpp @@ -271,7 +271,7 @@ class GridCellAttrProvider final : public wxGridCellAttrProvider attr = pStyles[(uint)style]; } - assert(attr != NULL and "Invalid cell attribute"); + assert(attr &&"Invalid cell attribute"); attr->IncRef(); return attr; } diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/dsm.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/area/dsm.cpp index e249c43e93..8f7835a381 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/dsm.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/dsm.cpp @@ -58,7 +58,7 @@ wxString DSM::columnCaption(int colIndx) const void DSM::internalAreaChanged(Antares::Data::Area* area) { - this->matrix((area) ? &(area->reserves) : NULL); + this->matrix((area) ? &(area->reserves) : nullptr); Renderer::ARendererArea::internalAreaChanged(area); } diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/misc.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/area/misc.cpp index 180b0424bf..c1749b27ae 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/misc.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/misc.cpp @@ -100,7 +100,7 @@ double Misc::cellNumericValue(int x, int y) const void Misc::internalAreaChanged(Antares::Data::Area* area) { - this->matrix((area) ? &(area->miscGen) : NULL); + this->matrix((area) ? &(area->miscGen) : nullptr); Renderer::ARendererArea::internalAreaChanged(area); } diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/timeseries.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/area/timeseries.cpp index df27cabc7c..a1060c1b70 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/timeseries.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/timeseries.cpp @@ -354,7 +354,7 @@ void TimeSeriesThermalClusterFuelCost::onStudyClosed() void TimeSeriesThermalClusterFuelCost::internalThermalClusterChanged( Antares::Data::ThermalCluster* cluster) { - matrix((CurrentStudyIsValid() && cluster) ? &(cluster->ecoInput.fuelcost) : NULL); + matrix((CurrentStudyIsValid() && cluster) ? &(cluster->ecoInput.fuelcost) : nullptr); } // ---------------------- @@ -384,7 +384,7 @@ void TimeSeriesThermalClusterCO2Cost::onStudyClosed() void TimeSeriesThermalClusterCO2Cost::internalThermalClusterChanged( Antares::Data::ThermalCluster* cluster) { - matrix((CurrentStudyIsValid() && cluster) ? &(cluster->ecoInput.co2cost) : NULL); + matrix((CurrentStudyIsValid() && cluster) ? &(cluster->ecoInput.co2cost) : nullptr); } // ---------------------- diff --git a/src/ui/simulator/toolbox/components/map/component.cpp b/src/ui/simulator/toolbox/components/map/component.cpp index 89daf4828a..93de041cb9 100644 --- a/src/ui/simulator/toolbox/components/map/component.cpp +++ b/src/ui/simulator/toolbox/components/map/component.cpp @@ -103,12 +103,12 @@ Component::Component(wxWindow* parent) : pSelectionPopUpMenu->Connect(Antares::Forms::MenusID::mnIDPopupSelectionHide, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(Component::evtOnSelectionHide), - NULL, + nullptr, this); pSelectionPopUpMenu->Connect(Antares::Forms::MenusID::mnIDPopupSelectionShow, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(Component::evtOnSelectionShow), - NULL, + nullptr, this); mainSizer->Layout(); diff --git a/src/ui/simulator/toolbox/components/map/nodes/item.cpp b/src/ui/simulator/toolbox/components/map/nodes/item.cpp index 4eac0ac92e..cb567af5af 100644 --- a/src/ui/simulator/toolbox/components/map/nodes/item.cpp +++ b/src/ui/simulator/toolbox/components/map/nodes/item.cpp @@ -112,7 +112,7 @@ void Item::internalClearAllLinks() if (pLinks && !pLinks->empty()) { Links* lnks = pLinks; - pLinks = NULL; + pLinks = nullptr; const Links::const_iterator end = lnks->end(); for (Links::const_iterator i = lnks->begin(); i != end; ++i) diff --git a/src/ui/simulator/toolbox/components/map/tools/tool.cpp b/src/ui/simulator/toolbox/components/map/tools/tool.cpp index ac957bb56b..3b244b5869 100644 --- a/src/ui/simulator/toolbox/components/map/tools/tool.cpp +++ b/src/ui/simulator/toolbox/components/map/tools/tool.cpp @@ -32,7 +32,7 @@ namespace Tool Tool::Tool(Manager& manager, const char* icon) : pManager(manager), pX(0), pY(0), pWidth(20), pHeight(20) { - pIcon = (icon && *icon != '\0') ? Resources::BitmapLoadFromFile(icon) : NULL; + pIcon = (icon && *icon != '\0') ? Resources::BitmapLoadFromFile(icon) : nullptr; } Tool::~Tool() @@ -43,7 +43,7 @@ Tool::~Tool() void Tool::icon(const char* filename) { delete pIcon; - pIcon = (filename && *filename != '\0') ? Resources::BitmapLoadFromFile(filename) : NULL; + pIcon = (filename && *filename != '\0') ? Resources::BitmapLoadFromFile(filename) : nullptr; } void Tool::draw(DrawingContext& dc, const bool mouseDown, const wxPoint&, const wxPoint&) const diff --git a/src/ui/simulator/toolbox/components/notebook/mapnotebook.cpp b/src/ui/simulator/toolbox/components/notebook/mapnotebook.cpp index 7b709afbe4..f4bee76ce3 100644 --- a/src/ui/simulator/toolbox/components/notebook/mapnotebook.cpp +++ b/src/ui/simulator/toolbox/components/notebook/mapnotebook.cpp @@ -98,8 +98,8 @@ bool MapNotebook::remove(Page* page) MapNotebook::MapTabs::MapTabs(wxWindow* parent, Notebook& notebook) : Tabs(parent, notebook), undrawnLeftTabs(0), remainingRightTabs(0), pTabNameCtrl(nullptr) { - Connect(GetId(), wxEVT_MOTION, wxMouseEventHandler(MapTabs::onMouseMove), NULL, this); - Connect(GetId(), wxEVT_LEAVE_WINDOW, wxMouseEventHandler(MapTabs::onMouseLeave), NULL, this); + Connect(GetId(), wxEVT_MOTION, wxMouseEventHandler(MapTabs::onMouseMove), nullptr, this); + Connect(GetId(), wxEVT_LEAVE_WINDOW, wxMouseEventHandler(MapTabs::onMouseLeave), nullptr, this); // add Page button addPageButton = new tabButton( "images/16x16/white_add_18.png", this, tabButton::btnNone, "images/16x16/grey_add_18.png"); diff --git a/src/ui/simulator/toolbox/create.cpp b/src/ui/simulator/toolbox/create.cpp index be3d23e13d..5687a5fc37 100644 --- a/src/ui/simulator/toolbox/create.cpp +++ b/src/ui/simulator/toolbox/create.cpp @@ -38,7 +38,7 @@ CustomWxButton::CustomWxButton(wxWindow* parent, const wxString& title) : wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent( wxCommandEventFunction, &CustomWxButton::evtOnUserClick), - NULL, + nullptr, this); } diff --git a/src/ui/simulator/toolbox/ext-source/apply.cpp b/src/ui/simulator/toolbox/ext-source/apply.cpp index 4e7f690151..13ea0c43a0 100644 --- a/src/ui/simulator/toolbox/ext-source/apply.cpp +++ b/src/ui/simulator/toolbox/ext-source/apply.cpp @@ -40,12 +40,12 @@ void Apply(Antares::Action::Context::Ptr context, if (windowRequired) { - auto* form = new Antares::Window::ApplyActionsDialog(NULL, context, root); + auto* form = new Antares::Window::ApplyActionsDialog(nullptr, context, root); Dispatcher::GUI::ShowModal(form); } else { - auto* form = new Antares::Window::PerformerDialog(NULL, context, root); + auto* form = new Antares::Window::PerformerDialog(nullptr, context, root); Dispatcher::GUI::ShowModal(form); } } diff --git a/src/ui/simulator/toolbox/input/connection.cpp b/src/ui/simulator/toolbox/input/connection.cpp index 7934b663f0..68e6f39f9f 100644 --- a/src/ui/simulator/toolbox/input/connection.cpp +++ b/src/ui/simulator/toolbox/input/connection.cpp @@ -112,7 +112,7 @@ void Connections::internalBuildSubControls() sizer->AddSpacer(1); // Layer filter pLayerFilter = new wxComboBox( - this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY); pLayerFilter->SetFont(wxFont(wxFontInfo().Bold())); pLayerFilter->AppendString("All"); pLayerFilter->SetValue("All"); diff --git a/src/ui/simulator/toolbox/jobs/job.cpp b/src/ui/simulator/toolbox/jobs/job.cpp index 926764f484..f4c2f4e284 100644 --- a/src/ui/simulator/toolbox/jobs/job.cpp +++ b/src/ui/simulator/toolbox/jobs/job.cpp @@ -1,23 +1,23 @@ -/* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ #include #include @@ -478,7 +478,8 @@ class MessageFlusherTimer final : public wxTimer MessageFlusherTimer(const wxString& messageBuffer, wxStaticText* label, std::mutex& mutex) : wxTimer(), pMessageBuffer(messageBuffer), pLabel(label), pMutex(mutex) { - assert(pLabel != NULL); + assert(pLabel); + } virtual ~MessageFlusherTimer() @@ -513,7 +514,8 @@ class ReadWriteStatsFlusherTimer final : public wxTimer public: ReadWriteStatsFlusherTimer(wxStaticText* label) : wxTimer(), pLabel(label) { - assert(pLabel != NULL); + assert(pLabel); + } virtual ~ReadWriteStatsFlusherTimer() diff --git a/src/ui/simulator/toolbox/spotlight/area.cpp b/src/ui/simulator/toolbox/spotlight/area.cpp index 9d0147e104..64a7589a31 100644 --- a/src/ui/simulator/toolbox/spotlight/area.cpp +++ b/src/ui/simulator/toolbox/spotlight/area.cpp @@ -33,7 +33,7 @@ namespace Spotlight { ItemArea::ItemArea(Data::Area* a) : area(a) { - assert(a != NULL); + assert(a); caption(a->name); group("Area"); diff --git a/src/ui/simulator/toolbox/spotlight/constraint.cpp b/src/ui/simulator/toolbox/spotlight/constraint.cpp index 2917526b13..de73cb889d 100644 --- a/src/ui/simulator/toolbox/spotlight/constraint.cpp +++ b/src/ui/simulator/toolbox/spotlight/constraint.cpp @@ -33,7 +33,7 @@ namespace Spotlight { ItemConstraint::ItemConstraint(Data::BindingConstraint* a) : constraint(a) { - assert(a != NULL); + assert(a); caption(a->name()); group("Constraint"); diff --git a/src/ui/simulator/windows/correlation/correlation.cpp b/src/ui/simulator/windows/correlation/correlation.cpp index 6edf4e095c..762479f64e 100644 --- a/src/ui/simulator/windows/correlation/correlation.cpp +++ b/src/ui/simulator/windows/correlation/correlation.cpp @@ -303,7 +303,7 @@ void CorrelationPanel::assignMatrices(Data::Correlation* corr) { if (pData) { - if (corr == NULL) + if (!corr) { for (uint i = 0; i < 12 + 1; ++i) { diff --git a/src/ui/simulator/windows/hydro/management.cpp b/src/ui/simulator/windows/hydro/management.cpp index 625a6e50a8..7822f58544 100644 --- a/src/ui/simulator/windows/hydro/management.cpp +++ b/src/ui/simulator/windows/hydro/management.cpp @@ -956,7 +956,7 @@ void Management::onToggleInitializeReservoirLevelDate(Component::Button&, wxMenu for (int i = 0; i < 12; i++) { - it = Menu::CreateItem(&menu, i, Antares::Date::MonthToString(i, 0), NULL, wxEmptyString); + it = Menu::CreateItem(&menu, i, Antares::Date::MonthToString(i, 0), nullptr, wxEmptyString); menu.Connect(it->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(Management::onChangingInitializeReservoirLevelDate), diff --git a/src/ui/simulator/windows/options/adequacy-patch/adequacy-patch-options.cpp b/src/ui/simulator/windows/options/adequacy-patch/adequacy-patch-options.cpp index 344a1acc7a..2368e68d13 100644 --- a/src/ui/simulator/windows/options/adequacy-patch/adequacy-patch-options.cpp +++ b/src/ui/simulator/windows/options/adequacy-patch/adequacy-patch-options.cpp @@ -62,7 +62,7 @@ static void updateButton(Component::Button* button, bool value, std::string_view type = (buttonType == "pto") ? 'P' : 'S'; } - assert(button != NULL); + assert(button); if (value) { switch (type) diff --git a/src/ui/simulator/windows/options/advanced/advanced.cpp b/src/ui/simulator/windows/options/advanced/advanced.cpp index a361fc227b..fa21ca6895 100644 --- a/src/ui/simulator/windows/options/advanced/advanced.cpp +++ b/src/ui/simulator/windows/options/advanced/advanced.cpp @@ -283,7 +283,7 @@ AdvancedParameters::AdvancedParameters(wxWindow* parent) : // refresh Connect( - GetId(), wxEVT_MOTION, wxMouseEventHandler(AdvancedParameters::onInternalMotion), NULL, this); + GetId(), wxEVT_MOTION, wxMouseEventHandler(AdvancedParameters::onInternalMotion), nullptr, this); refresh(); SetSizer(sizer); diff --git a/src/ui/simulator/windows/options/optimization/optimization.cpp b/src/ui/simulator/windows/options/optimization/optimization.cpp index f6a6b5bf2a..7c0b01db29 100644 --- a/src/ui/simulator/windows/options/optimization/optimization.cpp +++ b/src/ui/simulator/windows/options/optimization/optimization.cpp @@ -41,7 +41,7 @@ namespace Options { static void ResetButton(Component::Button* button, bool value) { - assert(button != NULL); + assert(button); if (value) { button->image("images/16x16/light_green.png"); @@ -56,7 +56,7 @@ static void ResetButton(Component::Button* button, bool value) static void ResetButton(Component::Button* button, Data::GlobalTransmissionCapacities value) { - assert(button != NULL); + assert(button); button->image(transmissionCapacityIcon(value)); button->caption(GlobalTransmissionCapacitiesToString_Display(value)); } @@ -349,7 +349,7 @@ Optimization::Optimization(wxWindow* parent) : sizer->Add(panel, 0, wxALL | wxEXPAND); // refresh - Connect(GetId(), wxEVT_MOTION, wxMouseEventHandler(Optimization::onInternalMotion), NULL, this); + Connect(GetId(), wxEVT_MOTION, wxMouseEventHandler(Optimization::onInternalMotion), nullptr, this); refresh(); SetSizer(sizer); diff --git a/src/ui/simulator/windows/options/temp-folder/temp-folder.cpp b/src/ui/simulator/windows/options/temp-folder/temp-folder.cpp index 246809bc8f..bc82fd78e0 100644 --- a/src/ui/simulator/windows/options/temp-folder/temp-folder.cpp +++ b/src/ui/simulator/windows/options/temp-folder/temp-folder.cpp @@ -63,7 +63,7 @@ ConfigureTempFolder::ConfigureTempFolder(wxWindow* parent) : pDefaults(nullptr), pText(nullptr) { - assert(NULL != parent); + assert(parent); auto* config = new wxConfig(wxT(LOG_APPLICATION_NAME), wxT(LOG_APPLICATION_VENDOR)); // Title of the Form diff --git a/src/ui/simulator/windows/output/output.cpp b/src/ui/simulator/windows/output/output.cpp index 16ef15b100..28be461e76 100644 --- a/src/ui/simulator/windows/output/output.cpp +++ b/src/ui/simulator/windows/output/output.cpp @@ -502,7 +502,7 @@ void Component::createAllControlsIfNeeded() OnStudyClosed.connect(this, &Component::onStudyClosed); // Layout - assert(GetSizer() != NULL); + assert(GetSizer()); GetSizer()->Layout(); pControlsAlreadyCreated = true; diff --git a/src/ui/simulator/windows/output/panel/area-link-renderer.cpp b/src/ui/simulator/windows/output/panel/area-link-renderer.cpp index e9c675082a..0f6373334c 100644 --- a/src/ui/simulator/windows/output/panel/area-link-renderer.cpp +++ b/src/ui/simulator/windows/output/panel/area-link-renderer.cpp @@ -174,7 +174,7 @@ int AreaLinkRenderer::height() const bool AreaLinkRenderer::valid() const { - return (NULL != pMatrix); + return (nullptr != pMatrix); } wxString AreaLinkRenderer::columnCaption(int colIndx) const diff --git a/src/ui/simulator/windows/output/panel/area-link.cpp b/src/ui/simulator/windows/output/panel/area-link.cpp index eecbbc2bf9..d8830b5784 100644 --- a/src/ui/simulator/windows/output/panel/area-link.cpp +++ b/src/ui/simulator/windows/output/panel/area-link.cpp @@ -152,7 +152,7 @@ class JobMatrix : public Yuni::Job::IJob, public Yuni::IEventObserver } // The loading of the matrix had failed. - // The GUI will be updated with NULL + // The GUI will be updated with nullptr callback.bind(&pPanel, &Panel::loadDataFromMatrix, (MatrixType*)nullptr); if (not shouldAbort) Antares::Dispatcher::GUI::Post(callback, 50); @@ -393,7 +393,7 @@ class JobAggregator : public Yuni::Job::IJob, public Yuni::IEventObserverreset(ops.width, ops.height); @@ -464,7 +464,7 @@ class JobAggregator : public Yuni::Job::IJob, public Yuni::IEventObserverStart(150); // Event - Connect(GetId(), wxEVT_MOTION, wxMouseEventHandler(Run::onInternalMotion), NULL, this); + Connect(GetId(), wxEVT_MOTION, wxMouseEventHandler(Run::onInternalMotion), nullptr, this); } Run::~Run() From 03d94dd6ae42354f510b1d38454a78e558ff75e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 1 Jul 2024 11:23:21 +0200 Subject: [PATCH 051/127] Format code using clang-format==18.3.1 (#2214) ## Ensure workflow "Check cpp formatting" is passing - Add `Yuni::` prefixing after some headers have been re-ordered - Exclude directory antlr-interface (generated code) NB clang-format is obtained using `pip install clang-format==18.3.1` --- src/analyzer/atsp/load.cpp | 2 +- src/format-code.sh | 2 +- src/libs/antares/args/args_to_utf8.cpp | 9 +- .../array/include/antares/array/matrix.hxx | 8 +- .../antares/checks/checkLoadedInputData.h | 1 - .../antares/exception/LoadingError.hpp | 7 +- .../FileTreeStudyLoader.h | 1 + .../include/antares/inifile/inifile.hxx | 3 +- src/libs/antares/inifile/inifile.cpp | 12 +- src/libs/antares/io/file.cpp | 2 +- src/libs/antares/io/include/antares/io/file.h | 4 +- src/libs/antares/locale/locale.cpp | 2 +- .../antares/study-loader/IStudyLoader.h | 1 + src/libs/antares/study/area/area.cpp | 7 +- src/libs/antares/study/area/links.cpp | 12 +- src/libs/antares/study/area/list.cpp | 21 +- .../BindingConstraintGroupRepository.cpp | 18 +- .../antares/study/cleaner/cleaner-v20.cpp | 1 - .../study/include/antares/study/parameters.h | 6 +- .../antares/study/parts/hydro/container.h | 7 +- .../study/scenario-builder/hydroLevelsData.h | 3 +- .../study/include/antares/study/sets.hxx | 8 +- src/libs/antares/study/parameters.cpp | 20 +- .../study/parts/common/cluster_list.cpp | 5 +- .../antares/study/parts/hydro/allocation.cpp | 32 ++- .../antares/study/parts/hydro/container.cpp | 256 ++++++++++-------- .../study/parts/hydro/finalLevelValidator.cpp | 44 ++- src/libs/antares/study/parts/hydro/prepro.cpp | 8 +- src/libs/antares/study/parts/hydro/series.cpp | 2 +- .../study/parts/renewable/cluster_list.cpp | 2 +- .../parts/short-term-storage/container.cpp | 24 +- .../study/parts/thermal/cluster_list.cpp | 45 +-- src/libs/antares/study/runtime/runtime.cpp | 6 +- .../BindingConstraintsTSNumbersData.cpp | 10 +- .../scenario-builder/hydroLevelsData.cpp | 6 +- .../antares/study/scenario-builder/rules.cpp | 5 +- src/libs/antares/study/study.cpp | 21 +- src/libs/antares/study/study.importprepro.cpp | 10 +- src/libs/antares/study/xcast/xcast.cpp | 3 +- src/libs/antares/utils/utils.cpp | 2 +- src/libs/antares/writer/in_memory_writer.cpp | 2 +- src/libs/antares/writer/zip_writer.cpp | 1 - src/libs/fswalker/fswalker.cpp | 2 +- .../application/ScenarioBuilderOwner.cpp | 4 +- src/solver/application/application.cpp | 6 +- src/solver/constraints-builder/cbuilder.cpp | 7 +- .../hydro/management/HydroInputsChecker.h | 1 + .../solver/hydro/management/management.h | 27 +- .../hydro/management/HydroInputsChecker.cpp | 8 +- .../hydro/management/PrepareInflows.cpp | 40 +-- src/solver/hydro/management/daily.cpp | 7 +- .../hydro-final-reservoir-level-functions.cpp | 46 ++-- src/solver/hydro/management/management.cpp | 16 +- src/solver/hydro/management/monthly.cpp | 12 +- .../include/antares/solver/misc/options.h | 2 +- src/solver/misc/options.cpp | 2 +- .../adequacy_patch_weekly_optimization.cpp | 14 +- .../optimisation/base_weekly_optimization.cpp | 19 +- .../optimisation/base_weekly_optimization.h | 8 +- .../solver/optimisation/opt_fonctions.h | 6 +- .../solver/optimisation/weekly_optimization.h | 8 +- ...ction_variables_optimisees_quadratique.cpp | 2 +- .../optimisation/opt_optimisation_hebdo.cpp | 7 +- .../opt_pilotage_optimisation_lineaire.cpp | 6 +- .../optimisation/weekly_optimization.cpp | 28 +- src/solver/simulation/adequacy.cpp | 22 +- src/solver/simulation/adequacy_mode.cpp | 64 ++--- src/solver/simulation/common-eco-adq.cpp | 22 +- src/solver/simulation/common-hydro-levels.cpp | 22 +- src/solver/simulation/common-hydro-remix.cpp | 3 +- src/solver/simulation/economy.cpp | 7 +- src/solver/simulation/economy_mode.cpp | 65 +++-- .../solver/simulation/ISimulationObserver.h | 7 +- .../antares/solver/simulation/adequacy.h | 3 +- .../antares/solver/simulation/economy_mode.h | 3 +- .../antares/solver/simulation/solver.hxx | 43 ++- .../simulation/sim_calcul_economique.cpp | 10 +- src/solver/simulation/timeseries-numbers.cpp | 3 +- src/solver/ts-generator/availability.cpp | 34 ++- .../antares/solver/ts-generator/generator.h | 2 - src/solver/ts-generator/xcast/xcast.cpp | 3 +- src/solver/utils/ortools_utils.cpp | 8 +- .../antares/solver/variable/economy/all.h | 4 +- .../bindingConstraintsMarginalCost.h | 7 +- .../antares/solver/variable/storage/minmax.h | 14 +- src/solver/variable/storage/minmax-data.cpp | 4 +- .../end-to-end/simple_study/simple-study.cpp | 2 +- src/tests/inmemory-study/in-memory-study.cpp | 6 +- .../inmemory-study/include/in-memory-study.h | 3 + .../antlr4-interface/test_antlr_interface.cpp | 8 +- .../test-sc-builder-file-read-line.cpp | 80 +++--- .../test-sc-builder-file-save.cpp | 4 +- src/tests/src/libs/antares/test_utils.cpp | 9 +- .../antares/yaml-parser/test_yaml_parser.cpp | 16 +- .../test-unfeasible-problem-analyzer.cpp | 3 +- ...-hydro-final-reservoir-level-functions.cpp | 15 +- src/tools/ts-generator/main.cpp | 91 ++++--- 97 files changed, 826 insertions(+), 680 deletions(-) diff --git a/src/analyzer/atsp/load.cpp b/src/analyzer/atsp/load.cpp index 0f8b92311f..b23f86f551 100644 --- a/src/analyzer/atsp/load.cpp +++ b/src/analyzer/atsp/load.cpp @@ -59,7 +59,7 @@ bool ATSP::loadFromINIFile(const String& filename) if (section->name == ".general") { IniFile::Property* p = section->firstProperty; - for (; p ; p = p->next) + for (; p; p = p->next) { key = p->key; key.toLower(); diff --git a/src/format-code.sh b/src/format-code.sh index 30b51bd2e2..abac85a423 100755 --- a/src/format-code.sh +++ b/src/format-code.sh @@ -4,7 +4,7 @@ if [ $# -eq 0 ] then # No arguments: format all SOURCE_DIRS="analyzer/ libs/ solver/ tools/ config/ tests/ packaging/" - SOURCE_FILES=$(find $SOURCE_DIRS -regextype egrep -regex ".*/*\.(c|cxx|cpp|cc|h|hxx|hpp)$") + SOURCE_FILES=$(find $SOURCE_DIRS -regextype egrep -regex ".*/*\.(c|cxx|cpp|cc|h|hxx|hpp)$" ! -path '*/antlr-interface/*') else # Format files provided as arguments SOURCE_FILES="$@" diff --git a/src/libs/antares/args/args_to_utf8.cpp b/src/libs/antares/args/args_to_utf8.cpp index 15b7db618b..55a09f00ff 100644 --- a/src/libs/antares/args/args_to_utf8.cpp +++ b/src/libs/antares/args/args_to_utf8.cpp @@ -53,7 +53,14 @@ std::pair IntoUTF8ArgsTranslator::convert() for (int i = 0; i != argc_; ++i) { const uint len = (uint)wcslen(wargv[i]); - const uint newLen = WideCharToMultiByte(CP_UTF8, 0, wargv[i], len, nullptr, 0, nullptr, nullptr); + const uint newLen = WideCharToMultiByte(CP_UTF8, + 0, + wargv[i], + len, + nullptr, + 0, + nullptr, + nullptr); argv_[i] = (char*)malloc((newLen + 1) * sizeof(char)); memset(argv_[i], 0, (newLen + 1) * sizeof(char)); WideCharToMultiByte(CP_UTF8, 0, wargv[i], len, argv_[i], newLen, nullptr, nullptr); diff --git a/src/libs/antares/array/include/antares/array/matrix.hxx b/src/libs/antares/array/include/antares/array/matrix.hxx index 78fef9186a..c95db1bd93 100644 --- a/src/libs/antares/array/include/antares/array/matrix.hxx +++ b/src/libs/antares/array/include/antares/array/matrix.hxx @@ -1044,8 +1044,6 @@ bool Matrix::internalLoadCSVFile(const AnyString& filename, uint options, BufferType* buffer) { - using namespace Yuni; - // Status bool result = false; @@ -1057,7 +1055,7 @@ bool Matrix::internalLoadCSVFile(const AnyString& filename, switch (loadFromFileToBuffer(*buffer, filename)) { - case IO::errNone: + case Yuni::IO::errNone: { // Empty files if (buffer->empty()) @@ -1098,7 +1096,7 @@ bool Matrix::internalLoadCSVFile(const AnyString& filename, } break; } - case IO::errNotFound: + case Yuni::IO::errNotFound: { if (not(options & optQuiet)) { @@ -1106,7 +1104,7 @@ bool Matrix::internalLoadCSVFile(const AnyString& filename, } break; } - case IO::errMemoryLimit: + case Yuni::IO::errMemoryLimit: { if (not(options & optQuiet)) { diff --git a/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h b/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h index 113451410f..62352390bc 100644 --- a/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h +++ b/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h @@ -28,7 +28,6 @@ void checkOrtoolsUsage(Antares::Data::UnitCommitmentMode ucMode, bool ortoolsUsed, const std::string& solverName); - void checkStudyVersion(const AnyString& optStudyFolder); void checkSimplexRangeHydroPricing(Antares::Data::SimplexOptimization optRange, diff --git a/src/libs/antares/exception/include/antares/exception/LoadingError.hpp b/src/libs/antares/exception/include/antares/exception/LoadingError.hpp index ab1ae664d8..c79b1a791e 100644 --- a/src/libs/antares/exception/include/antares/exception/LoadingError.hpp +++ b/src/libs/antares/exception/include/antares/exception/LoadingError.hpp @@ -130,13 +130,14 @@ class InvalidSolver: public LoadingError explicit InvalidSolver(const std::string& solver, const std::string& availableSolverList); }; -class InvalidSolverSpecificParameters : public LoadingError +class InvalidSolverSpecificParameters: public LoadingError { public: - explicit InvalidSolverSpecificParameters(const std::string& solver, const std::string& specificParameters); + explicit InvalidSolverSpecificParameters(const std::string& solver, + const std::string& specificParameters); }; -class InvalidStudy : public LoadingError +class InvalidStudy: public LoadingError { public: explicit InvalidStudy(const Yuni::String& study); diff --git a/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h b/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h index 687afa12ae..7b46a95c3a 100644 --- a/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h +++ b/src/libs/antares/file-tree-study-loader/include/antares/file-tree-study-loader/FileTreeStudyLoader.h @@ -31,6 +31,7 @@ namespace Data { class Study; } + /** * @class FileTreeStudyLoader * @brief A class to load studies from the file tree. diff --git a/src/libs/antares/inifile/include/antares/inifile/inifile.hxx b/src/libs/antares/inifile/include/antares/inifile/inifile.hxx index 64785d1ece..20498c3ee2 100644 --- a/src/libs/antares/inifile/include/antares/inifile/inifile.hxx +++ b/src/libs/antares/inifile/include/antares/inifile/inifile.hxx @@ -32,7 +32,8 @@ inline bool IniFile::empty() const return not firstSection; } -inline IniFile::Section::Section(const AnyString& name): name(name) +inline IniFile::Section::Section(const AnyString& name): + name(name) { } diff --git a/src/libs/antares/inifile/inifile.cpp b/src/libs/antares/inifile/inifile.cpp index 67190a0654..8cfa6b9607 100644 --- a/src/libs/antares/inifile/inifile.cpp +++ b/src/libs/antares/inifile/inifile.cpp @@ -65,9 +65,8 @@ void IniFile::Section::saveToStream(std::ostream& stream_out, uint64_t& written) stream_out << '[' << name << "]\n"; written += 4 /* []\n\n */ + name.size(); - each([&stream_out, &written](const IniFile::Property& p) { - p.saveToStream(stream_out, written); - }); + each([&stream_out, &written](const IniFile::Property& p) + { p.saveToStream(stream_out, written); }); stream_out << '\n'; } @@ -249,7 +248,7 @@ bool IniFile::open(const fs::path& filename, bool warnings) if (std::ifstream file(filename); file.is_open()) { - if (! readStream(file)) + if (!readStream(file)) { logs.error() << "Invalid INI file : " << filename; return false; @@ -266,9 +265,8 @@ bool IniFile::open(const fs::path& filename, bool warnings) void IniFile::saveToStream(std::ostream& stream_out, uint64_t& written) const { - each([&stream_out, &written](const IniFile::Section& s) { - s.saveToStream(stream_out, written); - }); + each([&stream_out, &written](const IniFile::Section& s) + { s.saveToStream(stream_out, written); }); if (written != 0) { diff --git a/src/libs/antares/io/file.cpp b/src/libs/antares/io/file.cpp index 10bf5b30b9..8ef66b3a3d 100644 --- a/src/libs/antares/io/file.cpp +++ b/src/libs/antares/io/file.cpp @@ -27,13 +27,13 @@ #ifdef YUNI_OS_WINDOWS #include + #include #else #include #include #endif #include - #include #include diff --git a/src/libs/antares/io/include/antares/io/file.h b/src/libs/antares/io/include/antares/io/file.h index e9fd0e91dc..b401b1cece 100644 --- a/src/libs/antares/io/include/antares/io/file.h +++ b/src/libs/antares/io/include/antares/io/file.h @@ -21,10 +21,10 @@ #ifndef __LIBS_ANTARES_IO_FILE_H__ #define __LIBS_ANTARES_IO_FILE_H__ -#include - #include +#include + namespace Antares::IO { /*! diff --git a/src/libs/antares/locale/locale.cpp b/src/libs/antares/locale/locale.cpp index fd74ea2af4..238331274a 100644 --- a/src/libs/antares/locale/locale.cpp +++ b/src/libs/antares/locale/locale.cpp @@ -37,7 +37,7 @@ void InitializeDefaultLocale() } #else - if (! std::setlocale(LC_ALL, "en_US.utf8")) + if (!std::setlocale(LC_ALL, "en_US.utf8")) { std::cerr << "impossible to set locale to en_US.utf8" << std::endl; } diff --git a/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h b/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h index 9b4c710ed4..7d6f25373b 100644 --- a/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h +++ b/src/libs/antares/study-loader/include/antares/study-loader/IStudyLoader.h @@ -29,6 +29,7 @@ namespace Data { class Study; } + /** * @class IStudyLoader * @brief The IStudyLoader class is an interface for loading studies. diff --git a/src/libs/antares/study/area/area.cpp b/src/libs/antares/study/area/area.cpp index 929e8653c2..130c56a0d6 100644 --- a/src/libs/antares/study/area/area.cpp +++ b/src/libs/antares/study/area/area.cpp @@ -51,19 +51,20 @@ Area::Area(): internalInitialize(); } -Area::Area(const AnyString& name) : Area() +Area::Area(const AnyString& name): + Area() { internalInitialize(); this->name = name; this->id = Antares::transformNameIntoID(this->name); } -Area::Area(const AnyString& name, const AnyString& id) : Area() +Area::Area(const AnyString& name, const AnyString& id): + Area() { internalInitialize(); this->name = name; this->id = Antares::transformNameIntoID(id); - } Area::~Area() diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 96a304d28e..f7b722da49 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -21,9 +21,9 @@ #include "antares/study/area/links.h" +#include #include #include -#include #include #include @@ -308,9 +308,13 @@ namespace // anonymous bool isPropertyUsedForLinkTSgeneration(const std::string& key) { - std::array listKeys - = {"unitcount", "nominalcapacity", "law.planned", "law.forced", - "volatility.planned", "volatility.forced", "force-no-generation"}; + std::array listKeys = {"unitcount", + "nominalcapacity", + "law.planned", + "law.forced", + "volatility.planned", + "volatility.forced", + "force-no-generation"}; return std::find(listKeys.begin(), listKeys.end(), key) != listKeys.end(); } diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index fd2b3bb5b7..de3c2e9b1f 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -968,8 +968,9 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, ret = hydroSeries->LoadMaxPower(area.id, buffer) && ret; } - hydroSeries->resizeTSinDeratedMode( - study.parameters.derated, studyVersion, study.usedByTheSolver); + hydroSeries->resizeTSinDeratedMode(study.parameters.derated, + studyVersion, + study.usedByTheSolver); } // Wind @@ -1278,7 +1279,7 @@ Area* AreaList::findFromPosition(const int x, const int y) const { auto lastArea = i->second; if (lastArea->ui && std::abs(lastArea->ui->x - x) < nearestDistance - && std::abs(lastArea->ui->y - y) < nearestDistance) + && std::abs(lastArea->ui->y - y) < nearestDistance) { nearestItem = lastArea; } @@ -1326,12 +1327,14 @@ void AreaListEnsureDataLoadPrepro(AreaList* l) /* Asserts */ assert(l); - l->each([](Data::Area& area) { - if (!area.load.prepro) - { - area.load.prepro = new Antares::Data::Load::Prepro(); - } - }); + l->each( + [](Data::Area& area) + { + if (!area.load.prepro) + { + area.load.prepro = new Antares::Data::Load::Prepro(); + } + }); } void AreaListEnsureDataSolarPrepro(AreaList* l) diff --git a/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp b/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp index ff181e7ed8..b29ad4fba2 100644 --- a/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp +++ b/src/libs/antares/study/binding_constraint/BindingConstraintGroupRepository.cpp @@ -60,7 +60,9 @@ bool BindingConstraintGroupRepository::buildFrom(const BindingConstraintsReposit bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const { - bool allConsistent = !std::ranges::any_of(groups_, [](const auto& group) + bool allConsistent = !std::ranges::any_of( + groups_, + [](const auto& group) { const auto& constraints = group->constraints(); if (constraints.empty()) @@ -68,7 +70,8 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const return false; } auto width = (*constraints.begin())->RHSTimeSeries().width; - bool isConsistent = std::ranges::all_of(constraints, + bool isConsistent = std::ranges::all_of( + constraints, [&width](const std::shared_ptr& bc) { bool sameWidth = bc->RHSTimeSeries().width == width; @@ -89,15 +92,16 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const void BindingConstraintGroupRepository::resizeAllTimeseriesNumbers(unsigned int nb_years) { - std::ranges::for_each(groups_, [&nb_years](auto& group) - { group->timeseriesNumbers.reset(nb_years); }); + std::ranges::for_each(groups_, + [&nb_years](auto& group) { group->timeseriesNumbers.reset(nb_years); }); } BindingConstraintGroup* BindingConstraintGroupRepository::operator[](const std::string& name) const { - if (auto group = std::ranges::find_if(groups_, [&name](auto& group_of_constraint) - { return group_of_constraint->name() == name; }); - group != groups_.end()) + if (auto group = std::ranges::find_if(groups_, + [&name](auto& group_of_constraint) + { return group_of_constraint->name() == name; }); + group != groups_.end()) { return group->get(); } diff --git a/src/libs/antares/study/cleaner/cleaner-v20.cpp b/src/libs/antares/study/cleaner/cleaner-v20.cpp index 3c8f183be4..f2fa71b17d 100644 --- a/src/libs/antares/study/cleaner/cleaner-v20.cpp +++ b/src/libs/antares/study/cleaner/cleaner-v20.cpp @@ -391,7 +391,6 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) buffer.clear() << infos->folder << "/input/bindingconstraints/bindingconstraints.ini"; if (ini.open(buffer)) { - ini.each( [&e](const IniFile::Section& section) { diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index 204afcdd0d..1b2ce027d9 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -75,8 +75,7 @@ class Parameters final ** \param version Current study version ** \return True if the settings have been loaded, false if at least one error has occured */ - bool loadFromFile(const AnyString& filename, - const StudyVersion& version); + bool loadFromFile(const AnyString& filename, const StudyVersion& version); /*! ** \brief Prepare all settings for a simulation @@ -501,8 +500,7 @@ class Parameters final private: //! Load data from an INI file - bool loadFromINI(const IniFile& ini, - const StudyVersion& version); + bool loadFromINI(const IniFile& ini, const StudyVersion& version); void resetPlayedYears(uint nbOfYears); diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index 9bece26ff3..01c219b46b 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -22,6 +22,7 @@ #define __ANTARES_LIBS_STUDY_PARTS_HYDRO_CONTAINER_H__ #include + #include "../../fwd.h" #include "allocation.h" #include "prepro.h" @@ -30,7 +31,7 @@ namespace Antares::Data { - //! The maximum number of days in a year +//! The maximum number of days in a year constexpr size_t dayYearCount = 366; struct DailyDemand @@ -233,9 +234,7 @@ class PartHydro // As this function can be called a lot of times, we pass working variables and returned variables // as arguments, so that we don't have to create them locally (as in a classical function) each // time. -double getWaterValue(const double& level, - const Matrix& waterValues, - const uint day); +double getWaterValue(const double& level, const Matrix& waterValues, const uint day); // Interpolates a rate from the credit modulation table according to a level double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */, diff --git a/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h index 42aff6336a..b5cb21073d 100644 --- a/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h +++ b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h @@ -21,9 +21,10 @@ #ifndef __LIBS_STUDY_SCENARIO_BUILDER_DATA_HYDRO_LEVELS_H__ #define __LIBS_STUDY_SCENARIO_BUILDER_DATA_HYDRO_LEVELS_H__ -#include "scBuilderDataInterface.h" #include +#include "scBuilderDataInterface.h" + namespace Antares { namespace Data diff --git a/src/libs/antares/study/include/antares/study/sets.hxx b/src/libs/antares/study/include/antares/study/sets.hxx index d2976252cc..931e044ba0 100644 --- a/src/libs/antares/study/include/antares/study/sets.hxx +++ b/src/libs/antares/study/include/antares/study/sets.hxx @@ -176,8 +176,8 @@ bool Sets::saveToFile(const StringT& filename) const using namespace Yuni; using namespace Antares; - IO::File::Stream file; - if (!file.open(filename, IO::OpenMode::write | IO::OpenMode::truncate)) + Yuni::IO::File::Stream file; + if (!file.open(filename, Yuni::IO::OpenMode::write | Yuni::IO::OpenMode::truncate)) { logs.error() << "I/O Error: " << filename << ": impossible to write the file"; return false; @@ -288,8 +288,8 @@ bool Sets::loadFromFile(const std::filesystem::path& filename) continue; } - logs.warning() << "sets: `" << filename << "`: Invalid property `" - << p->key << '\''; + logs.warning() << "sets: `" << filename << "`: Invalid property `" << p->key + << '\''; } // Add the new group diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index af0aedc14b..628237bbef 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -1111,10 +1111,16 @@ static bool SGDIntLoadFamily_Legacy(Parameters& d, if (key == "initial-reservoir-levels") // ignored since 9.2 { - if (version >= StudyVersion(9,2)) - logs.warning() << "Option initial-reservoir-levels is deprecated, please remove it from the study"; + if (version >= StudyVersion(9, 2)) + { + logs.warning() + << "Option initial-reservoir-levels is deprecated, please remove it from the study"; + } else if (value == "hot start") - logs.warning() << "Hydro hot start not supported with this solver, please use a version < 9.2"; + { + logs.warning() + << "Hydro hot start not supported with this solver, please use a version < 9.2"; + } return true; } @@ -1127,8 +1133,7 @@ bool firstKeyLetterIsValid(const String& name) return (firstLetter >= 'a' && firstLetter <= 'z'); } -bool Parameters::loadFromINI(const IniFile& ini, - const StudyVersion& version) +bool Parameters::loadFromINI(const IniFile& ini, const StudyVersion& version) { // Reset inner data reset(); @@ -1294,7 +1299,9 @@ void Parameters::fixBadValues() } if (simulationDays.first == 0) + { simulationDays.first = 1; + } else { simulationDays.first = std::clamp(simulationDays.first, 1u, 365u); @@ -1958,8 +1965,7 @@ void Parameters::saveToINI(IniFile& ini) const } } -bool Parameters::loadFromFile(const AnyString& filename, - const StudyVersion& version) +bool Parameters::loadFromFile(const AnyString& filename, const StudyVersion& version) { // Loading the INI file IniFile ini; diff --git a/src/libs/antares/study/parts/common/cluster_list.cpp b/src/libs/antares/study/parts/common/cluster_list.cpp index 9be5c2ca57..9c39ca7c8b 100644 --- a/src/libs/antares/study/parts/common/cluster_list.cpp +++ b/src/libs/antares/study/parts/common/cluster_list.cpp @@ -263,8 +263,9 @@ bool ClusterList::saveDataSeriesToFolder(const AnyString& folder) cons template bool ClusterList::loadDataSeriesFromFolder(Study& s, const AnyString& folder) { - return std::ranges::all_of(allClusters_, [&s, &folder](auto c) - { return c->loadDataSeriesFromFolder(s, folder); }); + return std::ranges::all_of(allClusters_, + [&s, &folder](auto c) + { return c->loadDataSeriesFromFolder(s, folder); }); } template diff --git a/src/libs/antares/study/parts/hydro/allocation.cpp b/src/libs/antares/study/parts/hydro/allocation.cpp index 597264cf20..052bc3411d 100644 --- a/src/libs/antares/study/parts/hydro/allocation.cpp +++ b/src/libs/antares/study/parts/hydro/allocation.cpp @@ -164,8 +164,7 @@ void HydroAllocation::clear() #endif } -bool HydroAllocation::loadFromFile(const AreaName& referencearea, - const fs::path& filename) +bool HydroAllocation::loadFromFile(const AreaName& referencearea, const fs::path& filename) { clear(); @@ -177,21 +176,24 @@ bool HydroAllocation::loadFromFile(const AreaName& referencearea, } if (ini.empty()) + { return true; + } - ini.each([this](const IniFile::Section& section) - { - for (auto* p = section.firstProperty; p; p = p->next) - { - double coeff = p->value.to(); - if (!Utils::isZero(coeff)) - { - AreaName areaname = p->key; - areaname.toLower(); - pValues[areaname] = coeff; - } - } - }); + ini.each( + [this](const IniFile::Section& section) + { + for (auto* p = section.firstProperty; p; p = p->next) + { + double coeff = p->value.to(); + if (!Utils::isZero(coeff)) + { + AreaName areaname = p->key; + areaname.toLower(); + pValues[areaname] = coeff; + } + } + }); return true; } diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index e09ae5a8fb..92d13a586e 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -32,7 +32,7 @@ using namespace Yuni; namespace Antares::Data { -PartHydro::PartHydro() : +PartHydro::PartHydro(): interDailyBreakdown(0.), intraDailyModulation(2.), intermonthlyBreakdown(0), @@ -113,7 +113,9 @@ static bool loadProperties(Study& study, T PartHydro::*ptr) { if (!property) + { return false; + } bool ret = true; @@ -242,52 +244,74 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if (IniFile::Section* section = ini.find("inter-daily-breakdown")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::interDailyBreakdown) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::interDailyBreakdown) + && ret; } if (IniFile::Section* section = ini.find("intra-daily-modulation")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::intraDailyModulation) && ret; + ret = loadProperties(study, + section->firstProperty, + buffer, + &PartHydro::intraDailyModulation) + && ret; } if (IniFile::Section* section = ini.find("reservoir")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirManagement) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirManagement) + && ret; } if (IniFile::Section* section = ini.find("reservoir capacity")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirCapacity) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirCapacity) + && ret; } if (IniFile::Section* section = ini.find("follow load")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::followLoadModulations) && ret; + ret = loadProperties(study, + section->firstProperty, + buffer, + &PartHydro::followLoadModulations) + && ret; } if (IniFile::Section* section = ini.find("use water")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useWaterValue) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useWaterValue) + && ret; } if (IniFile::Section* section = ini.find("hard bounds")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::hardBoundsOnRuleCurves) && ret; + ret = loadProperties(study, + section->firstProperty, + buffer, + &PartHydro::hardBoundsOnRuleCurves) + && ret; } if (IniFile::Section* section = ini.find("use heuristic")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useHeuristicTarget) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useHeuristicTarget) + && ret; } if (IniFile::Section* section = ini.find("power to level")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::powerToLevel) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::powerToLevel) + && ret; } if (IniFile::Section* section = ini.find("initialize reservoir date")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::initializeReservoirLevelDate) && ret; + ret = loadProperties(study, + section->firstProperty, + buffer, + &PartHydro::initializeReservoirLevelDate) + && ret; } if (IniFile::Section* section = ini.find("use leeway")) @@ -297,17 +321,20 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if (IniFile::Section* section = ini.find("leeway low")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayLowerBound) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayLowerBound) + && ret; } if (IniFile::Section* section = ini.find("leeway up")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayUpperBound) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayUpperBound) + && ret; } if (IniFile::Section* section = ini.find("pumping efficiency")) { - ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) + && ret; } return ret; @@ -317,10 +344,12 @@ bool PartHydro::checkReservoirLevels(const Study& study) { bool ret = true; - for (const auto& [areaName, area] : study.areas) + for (const auto& [areaName, area]: study.areas) { if (!study.usedByTheSolver) + { return true; + } auto& col = area->hydro.inflowPattern[0]; bool errorInflow = false; @@ -340,8 +369,8 @@ bool PartHydro::checkReservoirLevels(const Study& study) for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) { if (!errorLevels - && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] - || colAvg[day] > 100 || colMax[day] > 100)) + && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] + || colAvg[day] > 100 || colMax[day] > 100)) { logs.error() << areaName << ": invalid reservoir level value"; errorLevels = true; @@ -352,7 +381,7 @@ bool PartHydro::checkReservoirLevels(const Study& study) for (int i = 0; i < 101; i++) { if ((area->hydro.creditModulation[i][0] < 0) - || (area->hydro.creditModulation[i][1] < 0)) + || (area->hydro.creditModulation[i][1] < 0)) { logs.error() << areaName << ": invalid credit modulation value"; ret = false; @@ -372,75 +401,73 @@ bool PartHydro::checkProperties(Study& study) // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and // capacity = 0 because of further division by capacity. reservoir management = no and capacity // = 0 is possible (no use of capacity further) - study.areas.each([&ret](Data::Area& area) - { - if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) - { - logs.error() << area.name - << ": reservoir capacity not defined. Impossible to manage."; - ret = false; - } + study.areas.each( + [&ret](Data::Area& area) + { + if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) + { + logs.error() << area.name + << ": reservoir capacity not defined. Impossible to manage."; + ret = false; + } - if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) - { - logs.error() << area.name - << " : use water value = no conflicts with use heuristic target = no"; - ret = false; - } + if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) + { + logs.error() << area.name + << " : use water value = no conflicts with use heuristic target = no"; + ret = false; + } - if (area.hydro.intraDailyModulation < 1.) - { - logs.error() - << area.id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " - << area.hydro.intraDailyModulation << " (truncated to 1)"; - area.hydro.intraDailyModulation = 1.; - } + if (area.hydro.intraDailyModulation < 1.) + { + logs.error() << area.id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " + << area.hydro.intraDailyModulation << " (truncated to 1)"; + area.hydro.intraDailyModulation = 1.; + } - if (area.hydro.reservoirCapacity < 0) - { - logs.error() << area.id << ": Invalid reservoir capacity."; - area.hydro.reservoirCapacity = 0.; - } + if (area.hydro.reservoirCapacity < 0) + { + logs.error() << area.id << ": Invalid reservoir capacity."; + area.hydro.reservoirCapacity = 0.; + } - if (area.hydro.intermonthlyBreakdown < 0) - { - logs.error() << area.id << ": Invalid intermonthly breakdown"; - area.hydro.intermonthlyBreakdown = 0.; - } + if (area.hydro.intermonthlyBreakdown < 0) + { + logs.error() << area.id << ": Invalid intermonthly breakdown"; + area.hydro.intermonthlyBreakdown = 0.; + } - if (area.hydro.initializeReservoirLevelDate < 0) - { - logs.error() << area.id << ": Invalid initialize reservoir date"; - area.hydro.initializeReservoirLevelDate = 0; - } + if (area.hydro.initializeReservoirLevelDate < 0) + { + logs.error() << area.id << ": Invalid initialize reservoir date"; + area.hydro.initializeReservoirLevelDate = 0; + } - if (area.hydro.leewayLowerBound < 0.) - { - logs.error() - << area.id << ": Invalid leeway lower bound. It must be >= 0.0, Got " - << area.hydro.leewayLowerBound; - area.hydro.leewayLowerBound = 0.; - } + if (area.hydro.leewayLowerBound < 0.) + { + logs.error() << area.id << ": Invalid leeway lower bound. It must be >= 0.0, Got " + << area.hydro.leewayLowerBound; + area.hydro.leewayLowerBound = 0.; + } - if (area.hydro.leewayUpperBound < 0.) - { - logs.error() - << area.id << ": Invalid leeway upper bound. It must be >= 0.0, Got " - << area.hydro.leewayUpperBound; - area.hydro.leewayUpperBound = 0.; - } + if (area.hydro.leewayUpperBound < 0.) + { + logs.error() << area.id << ": Invalid leeway upper bound. It must be >= 0.0, Got " + << area.hydro.leewayUpperBound; + area.hydro.leewayUpperBound = 0.; + } - if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) - { + if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) + { logs.error() << area.id << ": Leeway lower bound greater than leeway upper bound."; - } + } - if (area.hydro.pumpingEfficiency < 0) - { - logs.error() << area.id << ": Invalid pumping efficiency"; - area.hydro.pumpingEfficiency = 0.; - } - }); + if (area.hydro.pumpingEfficiency < 0) + { + logs.error() << area.id << ": Invalid pumping efficiency"; + area.hydro.pumpingEfficiency = 0.; + } + }); return ret; } @@ -465,40 +492,40 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) struct AllSections { - IniFile::Section* s; - IniFile::Section* smod; - IniFile::Section* sIMB; - IniFile::Section* sreservoir; - IniFile::Section* sreservoirCapacity; - IniFile::Section* sFollowLoad; - IniFile::Section* sUseWater; - IniFile::Section* sHardBounds; - IniFile::Section* sInitializeReservoirDate; - IniFile::Section* sUseHeuristic; - IniFile::Section* sUseLeeway; - IniFile::Section* sPowerToLevel; - IniFile::Section* sLeewayLow; - IniFile::Section* sLeewayUp; - IniFile::Section* spumpingEfficiency; - - AllSections(IniFile& ini) : - s(ini.addSection("inter-daily-breakdown")), - smod(ini.addSection("intra-daily-modulation")), - sIMB(ini.addSection("inter-monthly-breakdown")), - sreservoir(ini.addSection("reservoir")), - sreservoirCapacity(ini.addSection("reservoir capacity")), - sFollowLoad(ini.addSection("follow load")), - sUseWater(ini.addSection("use water")), - sHardBounds(ini.addSection("hard bounds")), - sInitializeReservoirDate(ini.addSection("initialize reservoir date")), - sUseHeuristic(ini.addSection("use heuristic")), - sUseLeeway(ini.addSection("use leeway")), - sPowerToLevel(ini.addSection("power to level")), - sLeewayLow(ini.addSection("leeway low")), - sLeewayUp(ini.addSection("leeway up")), - spumpingEfficiency(ini.addSection("pumping efficiency")) + IniFile::Section* s; + IniFile::Section* smod; + IniFile::Section* sIMB; + IniFile::Section* sreservoir; + IniFile::Section* sreservoirCapacity; + IniFile::Section* sFollowLoad; + IniFile::Section* sUseWater; + IniFile::Section* sHardBounds; + IniFile::Section* sInitializeReservoirDate; + IniFile::Section* sUseHeuristic; + IniFile::Section* sUseLeeway; + IniFile::Section* sPowerToLevel; + IniFile::Section* sLeewayLow; + IniFile::Section* sLeewayUp; + IniFile::Section* spumpingEfficiency; + + AllSections(IniFile& ini): + s(ini.addSection("inter-daily-breakdown")), + smod(ini.addSection("intra-daily-modulation")), + sIMB(ini.addSection("inter-monthly-breakdown")), + sreservoir(ini.addSection("reservoir")), + sreservoirCapacity(ini.addSection("reservoir capacity")), + sFollowLoad(ini.addSection("follow load")), + sUseWater(ini.addSection("use water")), + sHardBounds(ini.addSection("hard bounds")), + sInitializeReservoirDate(ini.addSection("initialize reservoir date")), + sUseHeuristic(ini.addSection("use heuristic")), + sUseLeeway(ini.addSection("use leeway")), + sPowerToLevel(ini.addSection("power to level")), + sLeewayLow(ini.addSection("leeway low")), + sLeewayUp(ini.addSection("leeway up")), + spumpingEfficiency(ini.addSection("pumping efficiency")) { - } + } }; // Init @@ -515,7 +542,8 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) allSections.s->add(area.id, area.hydro.interDailyBreakdown); allSections.smod->add(area.id, area.hydro.intraDailyModulation); allSections.sIMB->add(area.id, area.hydro.intermonthlyBreakdown); - allSections.sInitializeReservoirDate->add(area.id, area.hydro.initializeReservoirLevelDate); + allSections.sInitializeReservoirDate->add(area.id, + area.hydro.initializeReservoirLevelDate); allSections.sLeewayLow->add(area.id, area.hydro.leewayLowerBound); allSections.sLeewayUp->add(area.id, area.hydro.leewayUpperBound); allSections.spumpingEfficiency->add(area.id, area.hydro.pumpingEfficiency); @@ -740,8 +768,8 @@ bool PartHydro::CheckDailyMaxEnergy(const AnyString& areaName) } double getWaterValue(const double& level /* format : in % of reservoir capacity */, - const Matrix& waterValues, - const uint day) + const Matrix& waterValues, + const uint day) { assert((level >= 0. && level <= 100.) && "getWaterValue function : invalid level"); double levelUp = ceil(level); @@ -752,7 +780,7 @@ double getWaterValue(const double& level /* format : in % of reservoir capacity return waterValues[(int)(levelUp)][day]; } return waterValues[(int)(levelUp)][day] * (level - levelDown) - + waterValues[(int)(levelDown)][day] * (levelUp - level); + + waterValues[(int)(levelDown)][day] * (levelUp - level); } double getWeeklyModulation(const double& level /* format : in % of reservoir capacity */, diff --git a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp index c3ea96ca08..c0834441a1 100644 --- a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp +++ b/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp @@ -37,7 +37,7 @@ FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, double finalLevel, const unsigned int year, const unsigned int lastSimulationDay, - const unsigned int firstMonthOfSimulation) : + const unsigned int firstMonthOfSimulation): year_(year), lastSimulationDay_(lastSimulationDay), firstMonthOfSimulation_(firstMonthOfSimulation), @@ -52,36 +52,46 @@ FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, bool FinalLevelValidator::check() { if (skippingFinalLevelUse()) + { return true; - if (! checkForInfeasibility()) + } + if (!checkForInfeasibility()) + { return false; + } finalLevelFineForUse_ = true; return true; } bool FinalLevelValidator::skippingFinalLevelUse() { - if(! wasSetInScenarioBuilder()) + if (!wasSetInScenarioBuilder()) + { return true; - if (! compatibleWithReservoirProperties()) + } + if (!compatibleWithReservoirProperties()) + { return true; + } return false; } bool FinalLevelValidator::wasSetInScenarioBuilder() { - return ! isnan(finalLevel_); + return !isnan(finalLevel_); } bool FinalLevelValidator::compatibleWithReservoirProperties() { if (hydro_.reservoirManagement && !hydro_.useWaterValue) + { return true; + } - logs.warning() << "Final reservoir level not applicable! Year:" << year_ + 1 - << ", Area:" << areaName_ - << ". Check: Reservoir management = Yes, Use water values = No and proper initial " - "reservoir level is provided "; + logs.warning() + << "Final reservoir level not applicable! Year:" << year_ + 1 << ", Area:" << areaName_ + << ". Check: Reservoir management = Yes, Use water values = No and proper initial " + "reservoir level is provided "; return false; } @@ -98,10 +108,12 @@ bool FinalLevelValidator::hydroAllocationStartMatchesSimulation() const { unsigned initReservoirLvlMonth = hydro_.initializeReservoirLevelDate; // month [0-11] if (lastSimulationDay_ == DAYS_PER_YEAR && initReservoirLvlMonth == firstMonthOfSimulation_) + { return true; + } - logs.error() << "Year " << year_ + 1 << ", area '" << areaName_ << "' : " - << "Hydro allocation must start on the 1st simulation month and " + logs.error() << "Year " << year_ + 1 << ", area '" << areaName_ + << "' : " << "Hydro allocation must start on the 1st simulation month and " << "simulation last a whole year"; return false; } @@ -115,8 +127,8 @@ bool FinalLevelValidator::isFinalLevelReachable() const { logs.error() << "Year: " << year_ + 1 << ". Area: " << areaName_ << ". Incompatible total inflows: " << totalYearInflows - << " with initial: " << initialLevel_ - << " and final: " << finalLevel_ << " reservoir levels."; + << " with initial: " << initialLevel_ << " and final: " << finalLevel_ + << " reservoir levels."; return false; } return true; @@ -125,17 +137,19 @@ bool FinalLevelValidator::isFinalLevelReachable() const double FinalLevelValidator::calculateTotalInflows() const { // calculate yearly inflows - auto const& srcinflows = hydro_.series->storage.getColumn(year_); + const auto& srcinflows = hydro_.series->storage.getColumn(year_); double totalYearInflows = 0.0; for (unsigned int day = 0; day < DAYS_PER_YEAR; ++day) + { totalYearInflows += srcinflows[day]; + } return totalYearInflows; } bool FinalLevelValidator::isBetweenRuleCurves() const { - double lowLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::minimum][DAYS_PER_YEAR - 1]; + double lowLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::minimum][DAYS_PER_YEAR - 1]; double highLevelLastDay = hydro_.reservoirLevel[Data::PartHydro::maximum][DAYS_PER_YEAR - 1]; if (finalLevel_ < lowLevelLastDay || finalLevel_ > highLevelLastDay) diff --git a/src/libs/antares/study/parts/hydro/prepro.cpp b/src/libs/antares/study/parts/hydro/prepro.cpp index 9370c562fa..13711759f4 100644 --- a/src/libs/antares/study/parts/hydro/prepro.cpp +++ b/src/libs/antares/study/parts/hydro/prepro.cpp @@ -151,6 +151,7 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::st { mtrxOption = Matrix<>::optFixedSize | Matrix<>::optImmediate, }; + constexpr int maxNbOfLineToLoad = 12; data.resize(hydroPreproMax, 12, true); @@ -160,7 +161,8 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::st bool ret = PreproHydroLoadSettings(this, buffer); buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; - ret = data.loadFromCSVFile(buffer, hydroPreproMax, maxNbOfLineToLoad, mtrxOption, &s.dataBuffer) && ret; + ret = data.loadFromCSVFile(buffer, hydroPreproMax, maxNbOfLineToLoad, mtrxOption, &s.dataBuffer) + && ret; return ret; } @@ -203,8 +205,8 @@ bool PreproHydro::validate(const std::string& areaID) { ret = false; logs.error() << "Hydro: Prepro: `" << areaID - << "`: minimum energy: At least one value is negative (line: " - << (i + 1) << ')'; + << "`: minimum energy: At least one value is negative (line: " << (i + 1) + << ')'; continue; } if (colMin[i] > colMax[i]) diff --git a/src/libs/antares/study/parts/hydro/series.cpp b/src/libs/antares/study/parts/hydro/series.cpp index 3eda6d5fc3..8c73772565 100644 --- a/src/libs/antares/study/parts/hydro/series.cpp +++ b/src/libs/antares/study/parts/hydro/series.cpp @@ -54,7 +54,7 @@ static void ConvertDailyTSintoHourlyTS(const Matrix::ColumnType& dailyCo { uint hour = 0; uint day = 0; - + while (hour < HOURS_PER_YEAR && day < DAYS_PER_YEAR) { for (uint i = 0; i < HOURS_PER_DAY; ++i) diff --git a/src/libs/antares/study/parts/renewable/cluster_list.cpp b/src/libs/antares/study/parts/renewable/cluster_list.cpp index 62db61a900..aa1c915a75 100644 --- a/src/libs/antares/study/parts/renewable/cluster_list.cpp +++ b/src/libs/antares/study/parts/renewable/cluster_list.cpp @@ -223,7 +223,7 @@ bool RenewableClusterList::loadFromFolder(const AnyString& folder, Area* area) bool RenewableClusterList::validateClusters() const { bool ret = true; - for (const auto& cluster : allClusters_) + for (const auto& cluster: allClusters_) { ret = cluster->integrityCheck() && ret; } diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 749613a14b..9a27233064 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -37,8 +37,7 @@ namespace Antares::Data::ShortTermStorage { bool STStorageInput::validate() const { - return std::ranges::all_of(storagesByIndex, [](auto& cluster) - { return cluster.validate(); }); + return std::ranges::all_of(storagesByIndex, [](auto& cluster) { return cluster.validate(); }); } bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) @@ -68,8 +67,9 @@ bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) storagesByIndex.push_back(cluster); } - std::ranges::sort(storagesByIndex, [](const auto& a, const auto& b) - { return a.properties.name < b.properties.name; }); + std::ranges::sort(storagesByIndex, + [](const auto& a, const auto& b) + { return a.properties.name < b.properties.name; }); return true; } @@ -100,8 +100,8 @@ bool STStorageInput::saveToFolder(const std::string& folder) const IniFile ini; logs.debug() << "saving file " << pathIni; - std::ranges::for_each(storagesByIndex, [&ini](auto& storage) - { return storage.saveProperties(ini); }); + std::ranges::for_each(storagesByIndex, + [&ini](auto& storage) { return storage.saveProperties(ini); }); return ini.save(pathIni); } @@ -109,20 +109,20 @@ bool STStorageInput::saveToFolder(const std::string& folder) const bool STStorageInput::saveDataSeriesToFolder(const std::string& folder) const { Yuni::IO::Directory::Create(folder); - return std::ranges::all_of(storagesByIndex, [&folder](auto& storage) - { return storage.saveSeries(folder + SEP + storage.id); }); + return std::ranges::all_of(storagesByIndex, + [&folder](auto& storage) + { return storage.saveSeries(folder + SEP + storage.id); }); } std::size_t STStorageInput::count() const { - return std::ranges::count_if(storagesByIndex, [](const STStorageCluster& st) - { return st.properties.enabled; }); + return std::ranges::count_if(storagesByIndex, + [](const STStorageCluster& st) { return st.properties.enabled; }); } uint STStorageInput::removeDisabledClusters() { - return std::erase_if(storagesByIndex, [](const auto& c) - { return !c.enabled(); }); + return std::erase_if(storagesByIndex, [](const auto& c) { return !c.enabled(); }); } } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/parts/thermal/cluster_list.cpp b/src/libs/antares/study/parts/thermal/cluster_list.cpp index 4bf2e042c2..8435870d0a 100644 --- a/src/libs/antares/study/parts/thermal/cluster_list.cpp +++ b/src/libs/antares/study/parts/thermal/cluster_list.cpp @@ -162,7 +162,8 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A ret = cluster->modulation.loadFromCSVFile(modulationFile, thermalModulationMax, HOURS_PER_YEAR, - options) && ret; + options) + && ret; // Check the data integrity of the cluster addToCompleteList(cluster); @@ -174,12 +175,11 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A return ret; } - bool ThermalClusterList::validateClusters(const Parameters& parameters) const { bool ret = true; - for (const auto& cluster : allClusters_) + for (const auto& cluster: allClusters_) { cluster->minUpTime = std::clamp(cluster->minUpTime, 1u, 168u); cluster->minDownTime = std::clamp(cluster->minDownTime, 1u, 168u); @@ -206,7 +206,6 @@ bool ThermalClusterList::validateClusters(const Parameters& parameters) const cluster->nominalCapacityWithSpinning = cluster->nominalCapacity; ret = cluster->integrityCheck() && ret; - } return ret; @@ -377,7 +376,7 @@ void ThermalClusterList::reverseCalculationOfSpinning() void ThermalClusterList::enableMustrunForEveryone() { - for (const auto& c : allClusters_) + for (const auto& c: allClusters_) { c->mustrun = true; } @@ -541,7 +540,6 @@ bool ThermalClusterList::saveToFolder(const AnyString& folder) const { ret = false; } - } // Write the ini file @@ -598,27 +596,32 @@ bool ThermalClusterList::loadPreproFromFolder(Study& study, const AnyString& fol return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), loadPrepro); } -bool ThermalClusterList::validatePrepro(const Study& study) { +bool ThermalClusterList::validatePrepro(const Study& study) +{ auto hasPrepro = [](auto c) { return (bool)c->prepro; }; - const bool globalThermalTSgeneration = - study.parameters.timeSeriesToGenerate & timeSeriesThermal; + const bool globalThermalTSgeneration = study.parameters.timeSeriesToGenerate + & timeSeriesThermal; if (!study.usedByTheSolver) + { return true; + } - return std::ranges::all_of( - allClusters_ | std::views::filter(hasPrepro), - [&globalThermalTSgeneration](auto& c) { - if (globalThermalTSgeneration && !c->prepro->validate()) { - return false; - } - - if (c->doWeGenerateTS(globalThermalTSgeneration)) { - return c->prepro->normalizeAndCheckNPO(); - } - return true; - }); + return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), + [&globalThermalTSgeneration](auto& c) + { + if (globalThermalTSgeneration && !c->prepro->validate()) + { + return false; + } + + if (c->doWeGenerateTS(globalThermalTSgeneration)) + { + return c->prepro->normalizeAndCheckNPO(); + } + return true; + }); } bool ThermalClusterList::loadEconomicCosts(Study& study, const AnyString& folder) diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index 1b093f4d2a..1bb7e46386 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -214,8 +214,7 @@ void StudyRuntimeInfos::initializeRangeLimits(const Study& study, StudyRangeLimi } else { - simulationDaysPerMonth[ca.month] = study.calendar.months[ca.month].days - - ca.dayMonth; + simulationDaysPerMonth[ca.month] = study.calendar.months[ca.month].days - ca.dayMonth; simulationDaysPerMonth[cb.month] = cb.dayMonth + 1; for (uint i = ca.month + 1; i < cb.month; ++i) { @@ -442,7 +441,8 @@ void StudyRangeLimits::checkIntegrity() const void StudyRuntimeInfos::disableAllFilters(Study& study) { - study.areas.each([](Data::Area& area) + study.areas.each( + [](Data::Area& area) { area.filterSynthesis = filterAll; area.filterYearByYear = filterAll; diff --git a/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp b/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp index 46a0694a58..5ffef13e98 100644 --- a/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp +++ b/src/libs/antares/study/scenario-builder/BindingConstraintsTSNumbersData.cpp @@ -81,11 +81,11 @@ bool BindingConstraintsTSNumberData::reset(const Study& study) { const uint nbYears = study.parameters.nbYears; std::ranges::for_each(study.bindingConstraintsGroups, - [this, &nbYears](const auto& group) - { - auto& ts_numbers = rules_[group->name()]; - ts_numbers.reset(1, nbYears); - }); + [this, &nbYears](const auto& group) + { + auto& ts_numbers = rules_[group->name()]; + ts_numbers.reset(1, nbYears); + }); return true; } diff --git a/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp b/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp index 3295df4503..8d0575b96a 100644 --- a/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp +++ b/src/libs/antares/study/scenario-builder/hydroLevelsData.cpp @@ -29,9 +29,9 @@ namespace Antares::Data::ScenarioBuilder { hydroLevelsData::hydroLevelsData(const std::string& iniFilePrefix, - std::function applyToTarget) : - addToPrefix_(iniFilePrefix), - applyToTarget_(applyToTarget) + std::function applyToTarget): + addToPrefix_(iniFilePrefix), + applyToTarget_(applyToTarget) { } diff --git a/src/libs/antares/study/scenario-builder/rules.cpp b/src/libs/antares/study/scenario-builder/rules.cpp index fd79f07f7c..2037eede6b 100644 --- a/src/libs/antares/study/scenario-builder/rules.cpp +++ b/src/libs/antares/study/scenario-builder/rules.cpp @@ -288,7 +288,9 @@ bool Rules::readFinalHydroLevels(const AreaName::Vector& splitKey, String value, const Data::Area* area = getArea(areaname, updaterMode); if (!area) + { return false; + } double finalLevel = fromStringToHydroLevel(value, 1.); hydroFinalLevels.setTSnumber(area->index, year, finalLevel); @@ -450,8 +452,7 @@ bool Rules::apply() void Rules::sendWarningsForDisabledClusters() { - for (auto it = disabledClustersOnRuleActive.begin(); - it != disabledClustersOnRuleActive.end(); + for (auto it = disabledClustersOnRuleActive.begin(); it != disabledClustersOnRuleActive.end(); it++) { std::vector& scenariiForCurrentCluster = it->second; diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 511e61a592..5b1dde8c5f 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -856,7 +856,8 @@ void Study::areaDelete(Area::Vector& arealist) << area.name; // Updating all hydro allocation - areas.each([&area](Data::Area& areait) { areait.hydro.allocation.remove(area.id); }); + areas.each([&area](Data::Area& areait) + { areait.hydro.allocation.remove(area.id); }); // Remove all binding constraints attached to the area bindingConstraints.remove(*i); @@ -956,7 +957,7 @@ bool Study::areaRename(Area* area, AreaName newName) // Updating all hydro allocation areas.each([&oldid, &newid](Data::Area& areait) - { areait.hydro.allocation.rename(oldid, newid); }); + { areait.hydro.allocation.rename(oldid, newid); }); ScenarioBuilderUpdater updaterSB(*this); bool ret = true; @@ -1109,13 +1110,14 @@ void Study::destroyAllWindTSGeneratorData() void Study::destroyAllThermalTSGeneratorData() { - areas.each([](const Data::Area& area) - { - for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) - { - FreeAndNil(cluster->prepro); - } - }); + areas.each( + [](const Data::Area& area) + { + for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) + { + FreeAndNil(cluster->prepro); + } + }); } void Study::ensureDataAreLoadedForAllBindingConstraints() @@ -1358,7 +1360,6 @@ bool Study::checkForFilenameLimits(bool output, const String& chfolder) const areas.each( [&output, &linkname, &areaname](const Area& area) { - if (areaname.size() < area.id.size()) { areaname = area.id; diff --git a/src/libs/antares/study/study.importprepro.cpp b/src/libs/antares/study/study.importprepro.cpp index 3b8263eadf..f7c8082050 100644 --- a/src/libs/antares/study/study.importprepro.cpp +++ b/src/libs/antares/study/study.importprepro.cpp @@ -50,7 +50,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesLoad)) { logs.info() << "Importing load timeseries..."; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { logs.info() << "Importing load timeseries : " << areaName; buffer.clear() << folderInput << SEP << "load" << SEP << "series"; @@ -63,7 +63,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesSolar)) { logs.info() << "Importing solar timeseries..."; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { logs.info() << "Importing solar timeseries : " << areaName; buffer.clear() << folderInput << SEP << "solar" << SEP << "series"; @@ -76,7 +76,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesHydro)) { logs.info() << "Importing hydro timeseries..."; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { logs.info() << "Importing hydro timeseries : " << areaName; buffer.clear() << folderInput << SEP << "hydro" << SEP << "series"; @@ -89,7 +89,7 @@ bool Study::importTimeseriesIntoInput() if (parameters.haveToImport(timeSeriesWind)) { logs.info() << "Importing wind timeseries..."; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { logs.info() << "Importing wind timeseries : " << areaName; buffer.clear() << folderInput << SEP << "wind" << SEP << "series"; @@ -104,7 +104,7 @@ bool Study::importTimeseriesIntoInput() logs.info() << "Importing thermal timeseries..."; String msg; - for (const auto& [areaName, area] : areas) + for (const auto& [areaName, area]: areas) { msg.clear() << "Importing thermal timeseries : " << areaName; diff --git a/src/libs/antares/study/xcast/xcast.cpp b/src/libs/antares/study/xcast/xcast.cpp index 51ed1624b0..0f2e05956b 100644 --- a/src/libs/antares/study/xcast/xcast.cpp +++ b/src/libs/antares/study/xcast/xcast.cpp @@ -207,7 +207,8 @@ bool XCast::loadFromFolder(const AnyString& folder) // For each property if (section.name == "general") { - for (const IniFile::Property* p = section.firstProperty; p != nullptr; p = p->next) + for (const IniFile::Property* p = section.firstProperty; p != nullptr; + p = p->next) { CString<30, false> key = p->key; key.toLower(); diff --git a/src/libs/antares/utils/utils.cpp b/src/libs/antares/utils/utils.cpp index 5f5efc9e9e..31992d6020 100644 --- a/src/libs/antares/utils/utils.cpp +++ b/src/libs/antares/utils/utils.cpp @@ -117,7 +117,7 @@ std::vector> splitStringIntoPairs(const std: { logs.warning() << "Error while parsing: " << token; logs.warning() << "Correct format is: \"object1" << delimiter2 << "object2" - << delimiter1 << "object3" << delimiter2 << "object4\""; + << delimiter1 << "object3" << delimiter2 << "object4\""; } } diff --git a/src/libs/antares/writer/in_memory_writer.cpp b/src/libs/antares/writer/in_memory_writer.cpp index e3e643a74f..182fee1927 100644 --- a/src/libs/antares/writer/in_memory_writer.cpp +++ b/src/libs/antares/writer/in_memory_writer.cpp @@ -24,9 +24,9 @@ #include #include +#include #include #include -#include namespace fs = std::filesystem; diff --git a/src/libs/antares/writer/zip_writer.cpp b/src/libs/antares/writer/zip_writer.cpp index 362d0e730e..6359460f8a 100644 --- a/src/libs/antares/writer/zip_writer.cpp +++ b/src/libs/antares/writer/zip_writer.cpp @@ -51,7 +51,6 @@ static void logErrorAndThrow [[noreturn]] (const std::string& errorMessage) throw std::runtime_error(errorMessage); } - // Class ZipWriteJob template ZipWriteJob::ZipWriteJob(ZipWriter& writer, diff --git a/src/libs/fswalker/fswalker.cpp b/src/libs/fswalker/fswalker.cpp index f1022fe1bd..403572bb3e 100644 --- a/src/libs/fswalker/fswalker.cpp +++ b/src/libs/fswalker/fswalker.cpp @@ -320,7 +320,7 @@ void WalkerThread::walk(const String& path) do { - assert(pContext.top() ); + assert(pContext.top()); auto& context = *(pContext.top()); if (pShouldStop) diff --git a/src/solver/application/ScenarioBuilderOwner.cpp b/src/solver/application/ScenarioBuilderOwner.cpp index ef6084fed5..69f9d11799 100644 --- a/src/solver/application/ScenarioBuilderOwner.cpp +++ b/src/solver/application/ScenarioBuilderOwner.cpp @@ -31,7 +31,8 @@ Antares::Solver::ScenarioBuilderOwner::ScenarioBuilderOwner(Data::Study& study): { } -void Antares::Solver::ScenarioBuilderOwner::callScenarioBuilder() { +void Antares::Solver::ScenarioBuilderOwner::callScenarioBuilder() +{ TSGenerator::ResizeGeneratedTimeSeries(study_.areas, study_.parameters); // Sampled time-series Numbers @@ -54,4 +55,3 @@ void Antares::Solver::ScenarioBuilderOwner::callScenarioBuilder() { ApplyCustomScenario(study_); } } - diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index 4a47abd1ff..a55873ea09 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -338,10 +338,14 @@ void Application::prepare(int argc, char* argv[]) // don't de-allocate these. if (!parseCommandLine(options)) // --help + { return; + } if (!handleOptions(options)) // --version, --list-solvers - return; + { + return; + } // Perform some checks checkAndCorrectSettingsAndOptions(pSettings, options); diff --git a/src/solver/constraints-builder/cbuilder.cpp b/src/solver/constraints-builder/cbuilder.cpp index d713aa7307..2a1e1b8dce 100644 --- a/src/solver/constraints-builder/cbuilder.cpp +++ b/src/solver/constraints-builder/cbuilder.cpp @@ -364,8 +364,7 @@ bool CBuilder::saveCBuilderToFile(const String& filename) const if (filename == "") { - fs::path path = fs::path(pStudy.folder.c_str()) / "settings" - / "constraintbuilder.ini"; + fs::path path = fs::path(pStudy.folder.c_str()) / "settings" / "constraintbuilder.ini"; return ini.save(path.string()); } @@ -399,12 +398,12 @@ bool CBuilder::completeCBuilderFromFile(const std::string& filename) CString<50, false> key; CString<50, false> value; - for (section = ini.firstSection; section ; section = section->next) + for (section = ini.firstSection; section; section = section->next) { if (section->name == ".general") { IniFile::Property* p = section->firstProperty; - for (; p ; p = p->next) + for (; p; p = p->next) { key = p->key; key.toLower(); diff --git a/src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h b/src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h index f45f1712ca..0308779170 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h @@ -24,6 +24,7 @@ #include "antares/solver/hydro/management/MinGenerationScaling.h" #include "antares/solver/hydro/management/PrepareInflows.h" #include "antares/study/study.h" + namespace Antares { diff --git a/src/solver/hydro/include/antares/solver/hydro/management/management.h b/src/solver/hydro/include/antares/solver/hydro/management/management.h index 7d8f5360c5..a8576248b4 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -80,20 +80,16 @@ class HydroManagement final private: //! Prepare the net demand for each area - void prepareNetDemand( - uint year, - Data::SimulationMode mode, - const Antares::Data::Area::ScratchMap& scratchmap, - HydroSpecificMap& hydro_specific_map); + void prepareNetDemand(uint year, + Data::SimulationMode mode, + const Antares::Data::Area::ScratchMap& scratchmap, + HydroSpecificMap& hydro_specific_map); //! Prepare the effective demand for each area - void prepareEffectiveDemand( - uint year, - HydroSpecificMap& hydro_specific_map); + void prepareEffectiveDemand(uint year, HydroSpecificMap& hydro_specific_map); //! Monthly Optimal generations - void prepareMonthlyOptimalGenerations( - double* random_reservoir_level, - uint y, - HydroSpecificMap& hydro_specific_map); + void prepareMonthlyOptimalGenerations(double* random_reservoir_level, + uint y, + HydroSpecificMap& hydro_specific_map); //! Monthly target generations // note: inflows may have two different types, if in swap mode or not @@ -103,10 +99,9 @@ class HydroManagement final Antares::Data::AreaDependantHydroManagementData& data, Antares::Data::TimeDependantHydroManagementData& hydro_specific); - void prepareDailyOptimalGenerations( - uint y, - Antares::Data::Area::ScratchMap& scratchmap, - HydroSpecificMap& hydro_specific_map); + void prepareDailyOptimalGenerations(uint y, + Antares::Data::Area::ScratchMap& scratchmap, + HydroSpecificMap& hydro_specific_map); void prepareDailyOptimalGenerations( Data::Area& area, diff --git a/src/solver/hydro/management/HydroInputsChecker.cpp b/src/solver/hydro/management/HydroInputsChecker.cpp index 613e760f74..c249cdabe3 100644 --- a/src/solver/hydro/management/HydroInputsChecker.cpp +++ b/src/solver/hydro/management/HydroInputsChecker.cpp @@ -53,11 +53,15 @@ void HydroInputsChecker::Execute(uint year) if (!checksOnGenerationPowerBounds(year)) { - throw FatalError("hydro inputs checks: invalid minimum generation"); + throw FatalError("hydro inputs checks: invalid minimum generation"); } if (parameters_.useCustomScenario) { - CheckFinalReservoirLevelsConfiguration(areas_, parameters_, scenarioInitialHydroLevels_, scenarioFinalHydroLevels_, year); + CheckFinalReservoirLevelsConfiguration(areas_, + parameters_, + scenarioInitialHydroLevels_, + scenarioFinalHydroLevels_, + year); } } diff --git a/src/solver/hydro/management/PrepareInflows.cpp b/src/solver/hydro/management/PrepareInflows.cpp index f1a43e71fd..c13d11a64b 100644 --- a/src/solver/hydro/management/PrepareInflows.cpp +++ b/src/solver/hydro/management/PrepareInflows.cpp @@ -10,10 +10,12 @@ PrepareInflows::PrepareInflows(Data::AreaList& areas, const Date::Calendar& cale { } -void PrepareInflows::Run(uint year){ +void PrepareInflows::Run(uint year) +{ LoadInflows(year); ChangeInflowsToAccommodateFinalLevels(year); } + void PrepareInflows::LoadInflows(uint year) { areas_.each( @@ -66,21 +68,27 @@ void PrepareInflows::LoadInflows(uint year) void PrepareInflows::ChangeInflowsToAccommodateFinalLevels(uint year) { - areas_.each([this, &year](Data::Area& area) - { - auto& data = area.hydro.managementData[year]; - - if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) - return; - - // Must be done before prepareMonthlyTargetGenerations - double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); - if (delta < 0) - data.inflows[0] -= delta; - else if (delta > 0) - data.inflows[11] -= delta; - }); -} + areas_.each( + [this, &year](Data::Area& area) + { + auto& data = area.hydro.managementData[year]; + if (!area.hydro.deltaBetweenFinalAndInitialLevels[year].has_value()) + { + return; + } + + // Must be done before prepareMonthlyTargetGenerations + double delta = area.hydro.deltaBetweenFinalAndInitialLevels[year].value(); + if (delta < 0) + { + data.inflows[0] -= delta; + } + else if (delta > 0) + { + data.inflows[11] -= delta; + } + }); +} } // namespace Antares diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index d1947d6d52..64072a5097 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -557,10 +557,9 @@ inline void HydroManagement::prepareDailyOptimalGenerations( } } -void HydroManagement::prepareDailyOptimalGenerations( - uint y, - Antares::Data::Area::ScratchMap& scratchmap, - HydroSpecificMap& hydro_specific_map) +void HydroManagement::prepareDailyOptimalGenerations(uint y, + Antares::Data::Area::ScratchMap& scratchmap, + HydroSpecificMap& hydro_specific_map) { areas_.each( [this, &scratchmap, &y, &hydro_specific_map](Data::Area& area) diff --git a/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp b/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp index 3aa1d7e426..6e9a53ce95 100644 --- a/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp +++ b/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp @@ -40,30 +40,34 @@ void CheckFinalReservoirLevelsConfiguration(Data::AreaList& areas, uint year) { if (!parameters.yearsFilter.at(year)) + { return; + } - areas.each([&areas, ¶meters, &scenarioInitialHydroLevels, &scenarioFinalHydroLevels, year](Data::Area &area) - { - double initialLevel = scenarioInitialHydroLevels.entry[area.index][year]; - double finalLevel = scenarioFinalHydroLevels.entry[area.index][year]; + areas.each( + [&areas, ¶meters, &scenarioInitialHydroLevels, &scenarioFinalHydroLevels, year]( + Data::Area& area) + { + double initialLevel = scenarioInitialHydroLevels.entry[area.index][year]; + double finalLevel = scenarioFinalHydroLevels.entry[area.index][year]; - Data::FinalLevelValidator validator(area.hydro, - area.index, - area.name, - initialLevel, - finalLevel, - year, - parameters.simulationDays.end, - parameters.firstMonthInYear); - if (!validator.check()) - { - throw FatalError("hydro final level : infeasibility"); - } - if (validator.finalLevelFineForUse()) - { - area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; - } - }); + Data::FinalLevelValidator validator(area.hydro, + area.index, + area.name, + initialLevel, + finalLevel, + year, + parameters.simulationDays.end, + parameters.firstMonthInYear); + if (!validator.check()) + { + throw FatalError("hydro final level : infeasibility"); + } + if (validator.finalLevelFineForUse()) + { + area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; + } + }); } // End function CheckFinalReservoirLevelsConfiguration } // namespace Antares::Solver diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 98b3b0b562..e4aeecde1e 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -140,11 +140,10 @@ HydroManagement::HydroManagement(const Data::AreaList& areas, } } -void HydroManagement::prepareNetDemand( - uint year, - Data::SimulationMode mode, - const Antares::Data::Area::ScratchMap& scratchmap, - HydroSpecificMap& hydro_specific_map) +void HydroManagement::prepareNetDemand(uint year, + Data::SimulationMode mode, + const Antares::Data::Area::ScratchMap& scratchmap, + HydroSpecificMap& hydro_specific_map) { areas_.each( [this, &year, &scratchmap, &mode, &hydro_specific_map](Data::Area& area) @@ -197,9 +196,7 @@ void HydroManagement::prepareNetDemand( }); } -void HydroManagement::prepareEffectiveDemand( - uint year, - HydroSpecificMap& hydro_specific_map) +void HydroManagement::prepareEffectiveDemand(uint year, HydroSpecificMap& hydro_specific_map) { areas_.each( [this, &year, &hydro_specific_map](Data::Area& area) @@ -216,7 +213,8 @@ void HydroManagement::prepareEffectiveDemand( double effectiveDemand = 0; // area.hydro.allocation is indexed by area index area.hydro.allocation.eachNonNull( - [this, &effectiveDemand, &day, &hydro_specific_map](unsigned areaIndex, double value) + [this, &effectiveDemand, &day, &hydro_specific_map](unsigned areaIndex, + double value) { const auto* area = areas_.byIndex[areaIndex]; effectiveDemand += hydro_specific_map[area].daily[day].DLN * value; diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index 5804782531..684ac4db16 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -151,10 +151,9 @@ double HydroManagement::prepareMonthlyTargetGenerations( return total; } -void HydroManagement::prepareMonthlyOptimalGenerations( - double* random_reservoir_level, - uint y, - HydroSpecificMap& hydro_specific_map) +void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_level, + uint y, + HydroSpecificMap& hydro_specific_map) { uint indexArea = 0; areas_.each( @@ -291,9 +290,8 @@ void HydroManagement::prepareMonthlyOptimalGenerations( writeSolutionCost("Solution cost (noised) : ", solutionCostNoised); buffer << "\n\n"; - buffer << '\t' << "\tInflows" << '\t' << "\tTarget Gen." - << "\tTurbined" - << "\tLevels" << '\t' << "\tLvl min" << '\t' << "\tLvl max\n"; + buffer << '\t' << "\tInflows" << '\t' << "\tTarget Gen." << "\tTurbined" << "\tLevels" + << '\t' << "\tLvl min" << '\t' << "\tLvl max\n"; for (uint month = 0; month != 12; ++month) { uint realmonth = (initReservoirLvlMonth + month) % 12; diff --git a/src/solver/misc/include/antares/solver/misc/options.h b/src/solver/misc/include/antares/solver/misc/options.h index 2560a74d1c..00daf5aec7 100644 --- a/src/solver/misc/include/antares/solver/misc/options.h +++ b/src/solver/misc/include/antares/solver/misc/options.h @@ -27,8 +27,8 @@ #include #include -#include #include +#include /*! ** \brief Command line settings for launching the simulation diff --git a/src/solver/misc/options.cpp b/src/solver/misc/options.cpp index a09b83e17d..960b0dda6c 100644 --- a/src/solver/misc/options.cpp +++ b/src/solver/misc/options.cpp @@ -22,8 +22,8 @@ #include "antares/solver/misc/options.h" #include -#include #include +#include #include #include diff --git a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp index 174d32564d..8129d10845 100644 --- a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp +++ b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp @@ -22,8 +22,8 @@ #include "antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h" #include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/simulation/adequacy_patch_runtime_data.h" #include "antares/solver/simulation/ISimulationObserver.h" +#include "antares/solver/simulation/adequacy_patch_runtime_data.h" #include "antares/study/fwd.h" using namespace Antares::Data::AdequacyPatch; @@ -47,7 +47,11 @@ void AdequacyPatchOptimization::solve() { Simulation::NullSimulationObserver nullSimulationObserver; problemeHebdo_->adequacyPatchRuntimeData->AdequacyFirstStep = true; - OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_, nullSimulationObserver); + OPT_OptimisationHebdomadaire(options_, + problemeHebdo_, + adqPatchParams_, + writer_, + nullSimulationObserver); problemeHebdo_->adequacyPatchRuntimeData->AdequacyFirstStep = false; for (uint32_t pays = 0; pays < problemeHebdo_->NombreDePays; ++pays) @@ -64,7 +68,11 @@ void AdequacyPatchOptimization::solve() } } - OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_, nullSimulationObserver); + OPT_OptimisationHebdomadaire(options_, + problemeHebdo_, + adqPatchParams_, + writer_, + nullSimulationObserver); } } // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/base_weekly_optimization.cpp b/src/solver/optimisation/base_weekly_optimization.cpp index 80efece4b9..623331485e 100644 --- a/src/solver/optimisation/base_weekly_optimization.cpp +++ b/src/solver/optimisation/base_weekly_optimization.cpp @@ -35,8 +35,7 @@ WeeklyOptimization::WeeklyOptimization(const OptimizationOptions& options, AdqPatchParams& adqPatchParams, uint thread_number, IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver - ) : + Simulation::ISimulationObserver& simulationObserver): options_(options), problemeHebdo_(problemesHebdo), adqPatchParams_(adqPatchParams), @@ -46,14 +45,14 @@ WeeklyOptimization::WeeklyOptimization(const OptimizationOptions& options, { } -std::unique_ptr WeeklyOptimization::create(const Antares::Data::Study& study, - const OptimizationOptions& options, - AdqPatchParams& adqPatchParams, - PROBLEME_HEBDO* problemeHebdo, - uint thread_number, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver - ) +std::unique_ptr WeeklyOptimization::create( + const Antares::Data::Study& study, + const OptimizationOptions& options, + AdqPatchParams& adqPatchParams, + PROBLEME_HEBDO* problemeHebdo, + uint thread_number, + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver) { if (adqPatchParams.enabled && adqPatchParams.localMatching.enabled) { diff --git a/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h b/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h index e25ffca086..acae5d8aed 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h @@ -41,9 +41,8 @@ class WeeklyOptimization Antares::Data::AdequacyPatch::AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemesHebdo, uint numSpace, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver - ); + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver); protected: explicit WeeklyOptimization(const OptimizationOptions& options, @@ -51,8 +50,7 @@ class WeeklyOptimization Antares::Data::AdequacyPatch::AdqPatchParams&, uint numSpace, IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver - ); + Simulation::ISimulationObserver& simulationObserver); Antares::Solver::Optimization::OptimizationOptions options_; PROBLEME_HEBDO* const problemeHebdo_ = nullptr; Antares::Data::AdequacyPatch::AdqPatchParams& adqPatchParams_; diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h index 2150ea991a..4be6b8e1d7 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h @@ -70,8 +70,7 @@ bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, - Solver::Simulation::ISimulationObserver& simulationObserver - ); + Solver::Simulation::ISimulationObserver& simulationObserver); void OPT_VerifierPresenceReserveJmoins1(PROBLEME_HEBDO*); bool OPT_PilotageOptimisationQuadratique(PROBLEME_HEBDO*); @@ -92,8 +91,7 @@ bool OPT_OptimisationLineaire(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, - Solver::Simulation::ISimulationObserver& simulationObserver - ); + Solver::Simulation::ISimulationObserver& simulationObserver); void OPT_RestaurerLesDonnees(PROBLEME_HEBDO*); /*------------------------------*/ diff --git a/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h b/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h index d0f33adb39..2206d35a25 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h @@ -21,9 +21,8 @@ #pragma once -#include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "antares/solver/simulation/ISimulationObserver.h" - +#include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "base_weekly_optimization.h" @@ -36,9 +35,8 @@ class DefaultWeeklyOptimization: public WeeklyOptimization PROBLEME_HEBDO* problemeHebdo, Antares::Data::AdequacyPatch::AdqPatchParams&, uint numSpace, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver - ); + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver); ~DefaultWeeklyOptimization() override = default; void solve() override; }; diff --git a/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp b/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp index e21039e14f..10018bf29d 100644 --- a/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp +++ b/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp @@ -31,7 +31,7 @@ void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeQuadratique(PROBLEME_HEBDO* problemeHebdo) { const auto& ProblemeAResoudre = problemeHebdo->ProblemeAResoudre; - assert(ProblemeAResoudre ); + assert(ProblemeAResoudre); int nombreDeVariables = 0; auto variableManager = VariableManagerFromProblemHebdo(problemeHebdo); diff --git a/src/solver/optimisation/opt_optimisation_hebdo.cpp b/src/solver/optimisation/opt_optimisation_hebdo.cpp index 6883089378..0abed9ff13 100644 --- a/src/solver/optimisation/opt_optimisation_hebdo.cpp +++ b/src/solver/optimisation/opt_optimisation_hebdo.cpp @@ -45,8 +45,11 @@ void OPT_OptimisationHebdomadaire(const OptimizationOptions& options, { if (pProblemeHebdo->TypeDOptimisation == OPTIMISATION_LINEAIRE) { - if (!OPT_PilotageOptimisationLineaire( - options, pProblemeHebdo, adqPatchParams, writer, simulationObserver)) + if (!OPT_PilotageOptimisationLineaire(options, + pProblemeHebdo, + adqPatchParams, + writer, + simulationObserver)) { logs.error() << "Linear optimization failed"; throw UnfeasibleProblemError("Linear optimization failed"); diff --git a/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp b/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp index 2ca9c71d56..7d6bff0d80 100644 --- a/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp +++ b/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp @@ -77,5 +77,9 @@ bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, OPT_InitialiserNombreMinEtMaxDeGroupesCoutsDeDemarrage(problemeHebdo); } - return OPT_OptimisationLineaire(options, problemeHebdo, adqPatchParams, writer, simulationObserver); + return OPT_OptimisationLineaire(options, + problemeHebdo, + adqPatchParams, + writer, + simulationObserver); } diff --git a/src/solver/optimisation/weekly_optimization.cpp b/src/solver/optimisation/weekly_optimization.cpp index cf943b2125..8f36d762d2 100644 --- a/src/solver/optimisation/weekly_optimization.cpp +++ b/src/solver/optimisation/weekly_optimization.cpp @@ -17,7 +17,7 @@ * * You should have received a copy of the Mozilla Public Licence 2.0 * along with Antares_Simulator. If not, see . -*/ + */ #include "antares/solver/optimisation/weekly_optimization.h" @@ -25,19 +25,29 @@ namespace Antares::Solver::Optimization { -DefaultWeeklyOptimization::DefaultWeeklyOptimization(const OptimizationOptions& options, - PROBLEME_HEBDO* problemeHebdo, - AdqPatchParams& adqPatchParams, - uint thread_number, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver) : - WeeklyOptimization(options, problemeHebdo, adqPatchParams, thread_number, writer, simulationObserver) +DefaultWeeklyOptimization::DefaultWeeklyOptimization( + const OptimizationOptions& options, + PROBLEME_HEBDO* problemeHebdo, + AdqPatchParams& adqPatchParams, + uint thread_number, + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver): + WeeklyOptimization(options, + problemeHebdo, + adqPatchParams, + thread_number, + writer, + simulationObserver) { } void DefaultWeeklyOptimization::solve() { - OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_, simulationObserver_.get()); + OPT_OptimisationHebdomadaire(options_, + problemeHebdo_, + adqPatchParams_, + writer_, + simulationObserver_.get()); } } // namespace Antares::Solver::Optimization diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index 8ba97fde33..f4759a0ab1 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -31,8 +31,10 @@ namespace Antares::Solver::Simulation { Adequacy::Adequacy(Data::Study& study, IResultWriter& resultWriter, - Simulation::ISimulationObserver& simulationObserver) : - study(study), resultWriter(resultWriter), simulationObserver_(simulationObserver) + Simulation::ISimulationObserver& simulationObserver): + study(study), + resultWriter(resultWriter), + simulationObserver_(simulationObserver) { } @@ -68,7 +70,10 @@ bool Adequacy::simulationBegin() pProblemesHebdo.resize(pNbMaxPerformedYearsInParallel); for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) { - SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], nbHoursInAWeek, numSpace); + SIM_InitialisationProblemeHebdo(study, + pProblemesHebdo[numSpace], + nbHoursInAWeek, + numSpace); } } @@ -405,8 +410,8 @@ void Adequacy::prepareClustersInMustRunMode(Data::Area::ScratchMap& scratchmap, { for (uint i = 0; i < study.areas.size(); ++i) { - auto &area = *study.areas[i]; - auto &scratchpad = scratchmap.at(&area); + auto& area = *study.areas[i]; + auto& scratchpad = scratchmap.at(&area); std::ranges::fill(scratchpad.mustrunSum, 0); std::ranges::fill(scratchpad.originalMustrunSum, 0); @@ -414,9 +419,9 @@ void Adequacy::prepareClustersInMustRunMode(Data::Area::ScratchMap& scratchmap, auto& mrs = scratchpad.mustrunSum; auto& adq = scratchpad.originalMustrunSum; - for (const auto &cluster: area.thermal.list.each_mustrun_and_enabled()) + for (const auto& cluster: area.thermal.list.each_mustrun_and_enabled()) { - const auto &availableProduction = cluster->series.getColumn(year); + const auto& availableProduction = cluster->series.getColumn(year); for (uint h = 0; h != cluster->series.timeSeries.height; ++h) { mrs[h] += availableProduction[h]; @@ -426,7 +431,8 @@ void Adequacy::prepareClustersInMustRunMode(Data::Area::ScratchMap& scratchmap, { for (uint h = 0; h != cluster->series.timeSeries.height; ++h) { - adq[h] += 2 * availableProduction[h]; // Why do we add the available production twice ? + adq[h] += 2 * availableProduction[h]; // Why do we add the available production + // twice ? } } } diff --git a/src/solver/simulation/adequacy_mode.cpp b/src/solver/simulation/adequacy_mode.cpp index 86435743ce..c0dd81b176 100644 --- a/src/solver/simulation/adequacy_mode.cpp +++ b/src/solver/simulation/adequacy_mode.cpp @@ -1,23 +1,23 @@ /* -* Copyright 2007-2024, RTE (https://www.rte-france.com) -* See AUTHORS.txt -* SPDX-License-Identifier: MPL-2.0 -* This file is part of Antares-Simulator, -* Adequacy and Performance assessment for interconnected energy networks. -* -* Antares_Simulator is free software: you can redistribute it and/or modify -* it under the terms of the Mozilla Public Licence 2.0 as published by -* the Mozilla Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Antares_Simulator is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* Mozilla Public Licence 2.0 for more details. -* -* You should have received a copy of the Mozilla Public Licence 2.0 -* along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/simulation/adequacy_mode.h" @@ -27,24 +27,24 @@ namespace Antares::Solver { void runSimulationInAdequacyMode(Antares::Data::Study& study, - const Settings& settings, + const Settings& settings, Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info, - Simulation::ISimulationObserver& simulationObserver) + IResultWriter& resultWriter, + Benchmarking::OptimizationInfo& info, + Simulation::ISimulationObserver& simulationObserver) { - // Type of the simulation - typedef Solver::Simulation::ISimulation SimulationType; - SimulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); - simulation.checkWriter(); - simulation.run(); + // Type of the simulation + typedef Solver::Simulation::ISimulation SimulationType; + SimulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); + simulation.checkWriter(); + simulation.run(); - if (!(settings.noOutput || settings.tsGeneratorsOnly)) - { + if (!(settings.noOutput || settings.tsGeneratorsOnly)) + { durationCollector("synthesis_export") << [&simulation] { simulation.writeResults(/*synthesis:*/ true); }; - info = simulation.getOptimizationInfo(); - } + info = simulation.getOptimizationInfo(); + } } } // namespace Antares::Solver diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index 4917e76f09..27d2cdae6c 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -338,21 +338,23 @@ void PrepareRandomNumbers(Data::Study& study, }); } - void SetInitialHydroLevel(Data::Study& study, PROBLEME_HEBDO& problem, const HYDRO_VENTILATION_RESULTS& hydroVentilationResults) { uint firstDaySimu = study.parameters.simulationDays.first; - study.areas.each([&problem, &firstDaySimu, &hydroVentilationResults](const Data::Area& area) - { - if (area.hydro.reservoirManagement) - { - double capacity = area.hydro.reservoirCapacity; - problem.previousSimulationFinalLevel[area.index] = - hydroVentilationResults[area.index].NiveauxReservoirsDebutJours[firstDaySimu] * capacity; - } - }); + study.areas.each( + [&problem, &firstDaySimu, &hydroVentilationResults](const Data::Area& area) + { + if (area.hydro.reservoirManagement) + { + double capacity = area.hydro.reservoirCapacity; + problem.previousSimulationFinalLevel[area.index] = hydroVentilationResults[area.index] + .NiveauxReservoirsDebutJours + [firstDaySimu] + * capacity; + } + }); } void BuildThermalPartOfWeeklyProblem(Data::Study& study, diff --git a/src/solver/simulation/common-hydro-levels.cpp b/src/solver/simulation/common-hydro-levels.cpp index 81602073a1..b0ba258b0e 100644 --- a/src/solver/simulation/common-hydro-levels.cpp +++ b/src/solver/simulation/common-hydro-levels.cpp @@ -33,7 +33,7 @@ void computingHydroLevels(const Data::AreaList& areas, bool remixWasRun, bool computeAnyway) { - for (const auto& [_, area] : areas) + for (const auto& [_, area]: areas) { if (!area->hydro.reservoirManagement) { @@ -50,7 +50,7 @@ void computingHydroLevels(const Data::AreaList& areas, double reservoirCapacity = area->hydro.reservoirCapacity; std::vector& inflows = problem.CaracteristiquesHydrauliques[index] - .ApportNaturelHoraire; + .ApportNaturelHoraire; RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; @@ -65,7 +65,7 @@ void computingHydroLevels(const Data::AreaList& areas, std::vector& ovf = weeklyResults.debordementsHoraires; computeTimeStepLevel - computeLvlObj(nivInit, inflows, ovf, turb, pumpingRatio, pump, reservoirCapacity); + computeLvlObj(nivInit, inflows, ovf, turb, pumpingRatio, pump, reservoirCapacity); for (uint h = 0; h < nbHoursInAWeek - 1; h++) { @@ -94,7 +94,7 @@ void interpolateWaterValue(const Data::AreaList& areas, daysOfWeek[d] = weekFirstDay + d; } - for (const auto& [_, area] : areas) + for (const auto& [_, area]: areas) { uint index = area->index; @@ -118,22 +118,22 @@ void interpolateWaterValue(const Data::AreaList& areas, std::vector& niv = weeklyResults.niveauxHoraires; waterVal[0] = Data::getWaterValue(problem.previousSimulationFinalLevel[index] * 100 - / reservoirCapacity, - area->hydro.waterValues, - weekFirstDay); + / reservoirCapacity, + area->hydro.waterValues, + weekFirstDay); for (uint h = 1; h < nbHoursInAWeek; h++) { waterVal[h] = Data::getWaterValue(niv[h - 1], - area->hydro.waterValues, - daysOfWeek[h / 24]); + area->hydro.waterValues, + daysOfWeek[h / 24]); } } } void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& problem) { - for (const auto& [_, area] : areas) + for (const auto& [_, area]: areas) { if (!area->hydro.reservoirManagement) { @@ -149,7 +149,7 @@ void updatingWeeklyFinalHydroLevel(const Data::AreaList& areas, PROBLEME_HEBDO& std::vector& niv = weeklyResults.niveauxHoraires; problem.previousSimulationFinalLevel[index] = niv[nbHoursInAWeek - 1] * reservoirCapacity - / 100; + / 100; } } diff --git a/src/solver/simulation/common-hydro-remix.cpp b/src/solver/simulation/common-hydro-remix.cpp index dcf39052ce..de8e3f5328 100644 --- a/src/solver/simulation/common-hydro-remix.cpp +++ b/src/solver/simulation/common-hydro-remix.cpp @@ -51,8 +51,7 @@ static bool Remix(const Data::AreaList& areas, bool status = true; areas.each( - [&HE, &DE, &remix, &G, &status, &problem, &numSpace, &hourInYear] - (const Data::Area& area) + [&HE, &DE, &remix, &G, &status, &problem, &numSpace, &hourInYear](const Data::Area& area) { auto index = area.index; diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 1fa0b63625..f14d4cabf0 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -35,7 +35,7 @@ namespace Antares::Solver::Simulation { Economy::Economy(Data::Study& study, IResultWriter& resultWriter, - Simulation::ISimulationObserver& simulationObserver) : + Simulation::ISimulationObserver& simulationObserver): study(study), preproOnly(false), resultWriter(resultWriter), @@ -76,7 +76,10 @@ bool Economy::simulationBegin() for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) { - SIM_InitialisationProblemeHebdo(study, pProblemesHebdo[numSpace], nbHoursInAWeek, numSpace); + SIM_InitialisationProblemeHebdo(study, + pProblemesHebdo[numSpace], + nbHoursInAWeek, + numSpace); auto options = createOptimizationOptions(study); weeklyOptProblems_[numSpace] = Antares::Solver::Optimization::WeeklyOptimization:: diff --git a/src/solver/simulation/economy_mode.cpp b/src/solver/simulation/economy_mode.cpp index 816eb1a212..12a1b24297 100644 --- a/src/solver/simulation/economy_mode.cpp +++ b/src/solver/simulation/economy_mode.cpp @@ -1,23 +1,23 @@ /* -* Copyright 2007-2024, RTE (https://www.rte-france.com) -* See AUTHORS.txt -* SPDX-License-Identifier: MPL-2.0 -* This file is part of Antares-Simulator, -* Adequacy and Performance assessment for interconnected energy networks. -* -* Antares_Simulator is free software: you can redistribute it and/or modify -* it under the terms of the Mozilla Public Licence 2.0 as published by -* the Mozilla Foundation, either version 2 of the License, or -* (at your option) any later version. -* -* Antares_Simulator is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* Mozilla Public Licence 2.0 for more details. -* -* You should have received a copy of the Mozilla Public Licence 2.0 -* along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/simulation/economy_mode.h" @@ -27,25 +27,24 @@ namespace Antares::Solver { void runSimulationInEconomicMode(Antares::Data::Study& study, - const Settings& settings, + const Settings& settings, Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info, - Simulation::ISimulationObserver& simulationObserver -) + IResultWriter& resultWriter, + Benchmarking::OptimizationInfo& info, + Simulation::ISimulationObserver& simulationObserver) { - // Type of the simulation - typedef Solver::Simulation::ISimulation SimulationType; - SimulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); - simulation.checkWriter(); - simulation.run(); + // Type of the simulation + typedef Solver::Simulation::ISimulation SimulationType; + SimulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); + simulation.checkWriter(); + simulation.run(); - if (!(settings.noOutput || settings.tsGeneratorsOnly)) - { + if (!(settings.noOutput || settings.tsGeneratorsOnly)) + { durationCollector("synthesis_export") << [&simulation] { simulation.writeResults(/*synthesis:*/ true); }; - info = simulation.getOptimizationInfo(); - } + info = simulation.getOptimizationInfo(); + } } } // namespace Antares::Solver diff --git a/src/solver/simulation/include/antares/solver/simulation/ISimulationObserver.h b/src/solver/simulation/include/antares/solver/simulation/ISimulationObserver.h index 414695a580..fe6145dd0f 100644 --- a/src/solver/simulation/include/antares/solver/simulation/ISimulationObserver.h +++ b/src/solver/simulation/include/antares/solver/simulation/ISimulationObserver.h @@ -53,13 +53,14 @@ class ISimulationObserver * @brief The NullSimulationObserver class is a null object for the ISimulationObserver interface. * @details It overrides the notifyHebdoProblem method with an empty implementation. */ -class NullSimulationObserver : public ISimulationObserver +class NullSimulationObserver: public ISimulationObserver { public: ~NullSimulationObserver() override = default; + void notifyHebdoProblem(const PROBLEME_HEBDO&, int, std::string_view) override { - //null object pattern + // null object pattern } }; -} // namespace Antares::Solver::Simulation \ No newline at end of file +} // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/include/antares/solver/simulation/adequacy.h b/src/solver/simulation/include/antares/solver/simulation/adequacy.h index 130f3c18f5..4e04acdcbe 100644 --- a/src/solver/simulation/include/antares/solver/simulation/adequacy.h +++ b/src/solver/simulation/include/antares/solver/simulation/adequacy.h @@ -48,7 +48,8 @@ class Adequacy ** ** \param study The current study */ - Adequacy(Data::Study& study, IResultWriter& resultWriter, + Adequacy(Data::Study& study, + IResultWriter& resultWriter, Simulation::ISimulationObserver& simulationObserver); //! Destructor ~Adequacy() = default; diff --git a/src/solver/simulation/include/antares/solver/simulation/economy_mode.h b/src/solver/simulation/include/antares/solver/simulation/economy_mode.h index 7437d39cf1..e26ebbb7e0 100644 --- a/src/solver/simulation/include/antares/solver/simulation/economy_mode.h +++ b/src/solver/simulation/include/antares/solver/simulation/economy_mode.h @@ -34,6 +34,5 @@ void runSimulationInEconomicMode(Antares::Data::Study& study, Benchmarking::DurationCollector& durationCollector, IResultWriter& resultWriter, Benchmarking::OptimizationInfo& info, - Simulation::ISimulationObserver& simulationObserver -); + Simulation::ISimulationObserver& simulationObserver); } diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 093cb1e350..cd4ddfc0a9 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -31,15 +31,13 @@ #include #include #include "antares/concurrency/concurrency.h" -#include "antares/solver/variable/constants.h" -#include "antares/solver/variable/print.h" #include "antares/solver/hydro/management/HydroInputsChecker.h" #include "antares/solver/hydro/management/management.h" #include "antares/solver/simulation/opt_time_writer.h" #include "antares/solver/simulation/timeseries-numbers.h" #include "antares/solver/ts-generator/generator.h" - - +#include "antares/solver/variable/constants.h" +#include "antares/solver/variable/print.h" namespace Antares::Solver::Simulation { @@ -76,10 +74,7 @@ public: pDurationCollector(durationCollector), pResultWriter(resultWriter), simulationObserver_(simulationObserver), - hydroManagement(study.areas, - study.parameters, - study.calendar, - resultWriter) + hydroManagement(study.areas, study.parameters, study.calendar, resultWriter) { scratchmap = study.areas.buildScratchMap(numSpace); } @@ -164,11 +159,8 @@ public: simulation_->prepareClustersInMustRunMode(scratchmap, y); // 4 - Hydraulic ventilation - pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] { - hydroManagement.makeVentilation(randomReservoirLevel, - y, - scratchmap); - }; + pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] + { hydroManagement.makeVentilation(randomReservoirLevel, y, scratchmap); }; // Updating the state state.year = y; @@ -723,15 +715,15 @@ void ISimulation::computeRandomNumbers( max[firstDayOfMonth], randomHydroGenerator); - // Possibly update the intial level from scenario builder - if (study.parameters.useCustomScenario) - { - double levelFromScenarioBuilder = study.scenarioInitialHydroLevels[areaIndex][y]; - if (levelFromScenarioBuilder >= 0.) - { - randomLevel = levelFromScenarioBuilder; - } - } + // Possibly update the intial level from scenario builder + if (study.parameters.useCustomScenario) + { + double levelFromScenarioBuilder = study.scenarioInitialHydroLevels[areaIndex][y]; + if (levelFromScenarioBuilder >= 0.) + { + randomLevel = levelFromScenarioBuilder; + } + } // Current area's hydro starting (or initial) level computation // (no matter if the year is performed or not, we always draw a random initial @@ -755,7 +747,12 @@ void ISimulation::computeRandomNumbers( bool SpilledEnergySeedIsDefault = (currentSpilledEnergySeed == defaultSpilledEnergySeed); areaIndex = 0; study.areas.each( - [&isPerformed, &areaIndex, &randomUnsupplied, &randomSpilled, &randomForYears, &indexYear, + [&isPerformed, + &areaIndex, + &randomUnsupplied, + &randomSpilled, + &randomForYears, + &indexYear, &SpilledEnergySeedIsDefault](Data::Area& area) { (void)area; // Avoiding warnings at compilation (unused variable) on linux diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index ed13d54fe1..7fb3336599 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -513,11 +513,11 @@ void SIM_RenseignementProblemeHebdo(const Study& study, if (area.hydro.useWaterValue) { - problem.CaracteristiquesHydrauliques[k].WeeklyWaterValueStateRegular = - getWaterValue( - problem.previousSimulationFinalLevel[k] * 100 / area.hydro.reservoirCapacity, - area.hydro.waterValues, - weekFirstDay); + problem.CaracteristiquesHydrauliques[k].WeeklyWaterValueStateRegular + = getWaterValue(problem.previousSimulationFinalLevel[k] * 100 + / area.hydro.reservoirCapacity, + area.hydro.waterValues, + weekFirstDay); } if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable > 0) diff --git a/src/solver/simulation/timeseries-numbers.cpp b/src/solver/simulation/timeseries-numbers.cpp index 52b1213ada..446a0efa08 100644 --- a/src/solver/simulation/timeseries-numbers.cpp +++ b/src/solver/simulation/timeseries-numbers.cpp @@ -329,8 +329,7 @@ bool checkInterModalConsistencyForArea(const Area& area, { logs.error() << "Inter-modal correlation: time-series numbers of inter-modal modes in area '" - << area.name << "'" - << " are not identical"; + << area.name << "'" << " are not identical"; return false; } diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 696725f846..0702c9e7b9 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -23,12 +23,12 @@ #include #include +#include // For Antares::IO::fileSetContent #include #include #include #include #include -#include // For Antares::IO::fileSetContent #include "antares/study/simulation.h" #define SEP Yuni::IO::Separator @@ -101,14 +101,18 @@ class GeneratorTempData final const T& duration) const; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen, MersenneTwister& rndGenerator): +GeneratorTempData::GeneratorTempData(Data::Study& study, + unsigned nbOfSeriesToGen, + MersenneTwister& rndGenerator): derated(study.parameters.derated), nbOfSeriesToGen_(nbOfSeriesToGen), rndgenerator(rndGenerator) { } -GeneratorTempData::GeneratorTempData(bool derated, unsigned int nbOfSeriesToGen, MersenneTwister& rndGenerator): +GeneratorTempData::GeneratorTempData(bool derated, + unsigned int nbOfSeriesToGen, + MersenneTwister& rndGenerator): derated(derated), nbOfSeriesToGen_(nbOfSeriesToGen), rndgenerator(rndGenerator) @@ -623,14 +627,13 @@ void writeResultsToDisk(const Data::Study& study, writer.addEntryFromBuffer(savePath, buffer); } -void writeResultsToDisk(const Matrix<>& series, - const std::filesystem::path savePath) +void writeResultsToDisk(const Matrix<>& series, const std::filesystem::path savePath) { std::string buffer; series.saveToBuffer(buffer, 0); std::filesystem::path parentDir = savePath.parent_path(); - if (! std::filesystem::exists(parentDir)) + if (!std::filesystem::exists(parentDir)) { std::filesystem::create_directories(parentDir); } @@ -680,21 +683,27 @@ bool generateLinkTimeSeries(std::vector& links, generalParams.random); for (auto& link: links) { - if (! link.hasValidData) + if (!link.hasValidData) { - logs.error() << "Missing data for link " << link.namesPair.first << "/" << link.namesPair.second; + logs.error() << "Missing data for link " << link.namesPair.first << "/" + << link.namesPair.second; return false; } if (link.forceNoGeneration) + { continue; // Skipping the link + } Data::TimeSeriesNumbers fakeTSnumbers; // gp : to quickly get rid of Data::TimeSeries ts(fakeTSnumbers); ts.resize(generalParams.nbLinkTStoGenerate, HOURS_PER_YEAR); // DIRECT - AvailabilityTSGeneratorData tsConfigDataDirect(link, ts, link.modulationCapacityDirect, link.namesPair.second); + AvailabilityTSGeneratorData tsConfigDataDirect(link, + ts, + link.modulationCapacityDirect, + link.namesPair.second); generator.generateTS(tsConfigDataDirect); @@ -703,12 +712,15 @@ bool generateLinkTimeSeries(std::vector& links, writeResultsToDisk(ts.timeSeries, filePath); // INDIRECT - AvailabilityTSGeneratorData tsConfigDataIndirect(link, ts, link.modulationCapacityIndirect, link.namesPair.second); + AvailabilityTSGeneratorData tsConfigDataIndirect(link, + ts, + link.modulationCapacityIndirect, + link.namesPair.second); generator.generateTS(tsConfigDataIndirect); filePath = savePath + SEP + link.namesPair.first + SEP + link.namesPair.second - + "_indirect.txt"; + + "_indirect.txt"; writeResultsToDisk(ts.timeSeries, filePath); } diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 8cddc50679..bfb2901bfa 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -70,7 +70,6 @@ struct LinkTSgenerationParams bool hasValidData = true; }; - class AvailabilityTSGeneratorData { public: @@ -121,7 +120,6 @@ bool generateLinkTimeSeries(std::vector& links, std::vector getAllClustersToGen(const Data::AreaList& areas, bool globalThermalTSgeneration); - /*! ** \brief Destroy all TS Generators */ diff --git a/src/solver/ts-generator/xcast/xcast.cpp b/src/solver/ts-generator/xcast/xcast.cpp index ca0c96087a..56f7234119 100644 --- a/src/solver/ts-generator/xcast/xcast.cpp +++ b/src/solver/ts-generator/xcast/xcast.cpp @@ -593,7 +593,8 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi if (study.parameters.derated) { - study.areas.each([&predicate](Data::Area& area) { predicate.matrix(area).averageTimeseries(); }); + study.areas.each([&predicate](Data::Area& area) + { predicate.matrix(area).averageTimeseries(); }); } if (study.parameters.timeSeriesToArchive & timeSeriesType) diff --git a/src/solver/utils/ortools_utils.cpp b/src/solver/utils/ortools_utils.cpp index 1f2f5e4169..2cc81b80fa 100644 --- a/src/solver/utils/ortools_utils.cpp +++ b/src/solver/utils/ortools_utils.cpp @@ -56,10 +56,9 @@ static void checkSetSolverSpecificParameters(bool status, } } -static void TuneSolverSpecificOptions( - MPSolver* solver, - const std::string& solverName, - const std::string& solverParameters) +static void TuneSolverSpecificOptions(MPSolver* solver, + const std::string& solverName, + const std::string& solverParameters) { if (!solver) { @@ -135,7 +134,6 @@ MPSolver* ProblemSimplexeNommeConverter::Convert() return solver; } - void ProblemSimplexeNommeConverter::CopyMatrix(const MPSolver* solver) const { auto variables = solver->variables(); diff --git a/src/solver/variable/include/antares/solver/variable/economy/all.h b/src/solver/variable/include/antares/solver/variable/economy/all.h index a3c637c43f..b7a62eb6bf 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/all.h +++ b/src/solver/variable/include/antares/solver/variable/economy/all.h @@ -248,8 +248,8 @@ typedef Variable::Join< Variable::Areas, // Variables for each set of areas Variable::Join, - // Variables for each binding constraint - Variable::BindingConstraints>> + // Variables for each binding constraint + Variable::BindingConstraints>> ItemList; /*! diff --git a/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h b/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h index 6d7e02fa3e..8a1f97676f 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h +++ b/src/solver/variable/include/antares/solver/variable/economy/bindingConstraints/bindingConstraintsMarginalCost.h @@ -147,7 +147,6 @@ class BindingConstMarginCost NextType::simulationEnd(); } - void initializeFromStudy(Data::Study& study) { pNbYearsParallel = study.maxNbYearsInParallel; @@ -257,8 +256,8 @@ class BindingConstMarginCost for (int dayInTheWeek = 0; dayInTheWeek < 7; dayInTheWeek++) { pValuesForTheCurrentYear[numSpace].day[dayInTheYear] - -= state.problemeHebdo - ->ResultatsContraintesCouplantes[associatedBC_][dayInTheWeek]; + -= state.problemeHebdo + ->ResultatsContraintesCouplantes[associatedBC_][dayInTheWeek]; dayInTheYear++; } @@ -270,7 +269,7 @@ class BindingConstMarginCost { uint weekInTheYear = state.weekInTheYear; double weeklyValue = -state.problemeHebdo - ->ResultatsContraintesCouplantes[associatedBC_][0]; + ->ResultatsContraintesCouplantes[associatedBC_][0]; pValuesForTheCurrentYear[numSpace].week[weekInTheYear] = weeklyValue; diff --git a/src/solver/variable/include/antares/solver/variable/storage/minmax.h b/src/solver/variable/include/antares/solver/variable/storage/minmax.h index 8e9603fa16..7866d1a271 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/minmax.h +++ b/src/solver/variable/include/antares/solver/variable/storage/minmax.h @@ -84,14 +84,19 @@ struct MinMaxBase: public NextT { case Category::hourly: InternalExportIndices(report, - Memory::RawPointer(minmax.hourly.data()), + Memory::RawPointer( + minmax.hourly.data()), fileLevel); break; case Category::daily: - InternalExportIndices(report, minmax.daily.data(), fileLevel); + InternalExportIndices(report, + minmax.daily.data(), + fileLevel); break; case Category::weekly: - InternalExportIndices(report, minmax.weekly.data(), fileLevel); + InternalExportIndices(report, + minmax.weekly.data(), + fileLevel); break; case Category::monthly: InternalExportIndices(report, minmax.monthly.data(), fileLevel); @@ -107,7 +112,8 @@ struct MinMaxBase: public NextT { case Category::hourly: InternalExportValues(report, - Memory::RawPointer(minmax.hourly.data())); + Memory::RawPointer( + minmax.hourly.data())); break; case Category::daily: InternalExportValues(report, minmax.daily.data()); diff --git a/src/solver/variable/storage/minmax-data.cpp b/src/solver/variable/storage/minmax-data.cpp index 6d25480806..ea59610820 100644 --- a/src/solver/variable/storage/minmax-data.cpp +++ b/src/solver/variable/storage/minmax-data.cpp @@ -29,10 +29,10 @@ constexpr double eps = 1.e-7; static void initArray(bool opInferior, std::vector& array) { - for (auto& data : array) + for (auto& data: array) { data.value = opInferior ? DBL_MAX : -DBL_MAX; // +inf or -inf - data.indice = (uint32_t)(-1); // invalid indice + data.indice = (uint32_t)(-1); // invalid indice } } diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index 1def8eded6..7005057209 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -82,7 +82,7 @@ HydroMaxPowerStudy::HydroMaxPowerStudy() area = addAreaToStudy("Area"); area->thermal.unsuppliedEnergyCost = 1; - setNumberMCyears(1); + setNumberMCyears(1); TimeSeriesConfigurer loadTSconfig(area->load.series.timeSeries); loadTSconfig.setColumnCount(1).fillColumnWith(0, loadInArea); diff --git a/src/tests/inmemory-study/in-memory-study.cpp b/src/tests/inmemory-study/in-memory-study.cpp index 4b4e65c100..30efd246bf 100644 --- a/src/tests/inmemory-study/in-memory-study.cpp +++ b/src/tests/inmemory-study/in-memory-study.cpp @@ -20,9 +20,10 @@ */ #define WIN32_LEAN_AND_MEAN -#include "antares/application/ScenarioBuilderOwner.h" #include "in-memory-study.h" +#include "antares/application/ScenarioBuilderOwner.h" + void initializeStudy(Study* study) { study->parameters.reset(); @@ -223,7 +224,8 @@ void StudyBuilder::setNumberMCyears(unsigned int nbYears) { study->parameters.resetPlaylist(nbYears); study->areas.resizeAllTimeseriesNumbers(nbYears); - study->areas.each([&](Data::Area& area) { area.hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); }); + study->areas.each([&](Data::Area& area) + { area.hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); }); } void StudyBuilder::playOnlyYear(unsigned int year) diff --git a/src/tests/inmemory-study/include/in-memory-study.h b/src/tests/inmemory-study/include/in-memory-study.h index 101b6b47ab..920d28f261 100644 --- a/src/tests/inmemory-study/include/in-memory-study.h +++ b/src/tests/inmemory-study/include/in-memory-study.h @@ -164,14 +164,17 @@ class ScenarioBuilderRule { return rules_->load; } + BindingConstraintsTSNumberData& bcGroup() { return rules_->binding_constraints; } + hydroTSNumberData& hydro() { return rules_->hydro; } + private: Rules::Ptr rules_; }; diff --git a/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp b/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp index e97f4e3524..04d1c7be9f 100644 --- a/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp +++ b/src/tests/src/libs/antares/antlr4-interface/test_antlr_interface.cpp @@ -19,15 +19,17 @@ ** along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE antlr_interface tests -#include -#include -#include "antlr4-runtime.h" #include +#include +#include + #include "ExprLexer.h" #include "ExprParser.h" +#include "antlr4-runtime.h" using namespace antlr4; + BOOST_AUTO_TEST_CASE(test_antlr_interface) { const std::string my_input = "y = b + a*x"; diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp index 7879559fb0..de09d007d1 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp @@ -355,10 +355,12 @@ BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_17__hydro_level_0_123_is_chosen__re AreaName::Vector splitKey = {"hl", "area 1", yearNumber}; my_rule.readLine(splitKey, level); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_1->index), level.to()); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_1->index), + level.to()); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_1->index][yearNumber.to()], level.to()); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_1->index][yearNumber.to()], + level.to()); } BOOST_FIXTURE_TEST_CASE( @@ -370,10 +372,11 @@ BOOST_FIXTURE_TEST_CASE( AreaName::Vector splitKey = {"hl", "area 2", yearNumber}; BOOST_CHECK(my_rule.readLine(splitKey, level)); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_2->index), 1.); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_2->index), + 1.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_2->index][yearNumber.to()], 1.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_2->index][yearNumber.to()], 1.); } BOOST_FIXTURE_TEST_CASE( @@ -385,10 +388,11 @@ BOOST_FIXTURE_TEST_CASE( AreaName::Vector splitKey = {"hl", "area 3", yearNumber}; BOOST_CHECK(my_rule.readLine(splitKey, level)); - BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_3->index), 0.); + BOOST_CHECK_EQUAL(my_rule.hydroInitialLevels.get_value(yearNumber.to(), area_3->index), + 0.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_3->index][yearNumber.to()], 0.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioInitialHydroLevels[area_3->index][yearNumber.to()], 0.); } // ======================== @@ -396,47 +400,47 @@ BOOST_FIXTURE_TEST_CASE( // ======================== BOOST_FIXTURE_TEST_CASE(on_area1_and_on_year_8__hydro_level_0_342_is_chosen__reading_OK, Fixture) { - AreaName yearNumber = "8"; - String level = "0.342"; - AreaName::Vector splitKey = {"hfl", "area 1", yearNumber}; - my_rule.readLine(splitKey, level, false); + AreaName yearNumber = "8"; + String level = "0.342"; + AreaName::Vector splitKey = {"hfl", "area 1", yearNumber}; + my_rule.readLine(splitKey, level, false); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_1->index), - level.to()); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_1->index), + level.to()); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_1->index][yearNumber.to()], - level.to()); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_1->index][yearNumber.to()], + level.to()); } -BOOST_FIXTURE_TEST_CASE(on_area2_and_on_year_1__hydro_level_2_4_is_chosen_level_lowered_to_1__reading_OK, Fixture) +BOOST_FIXTURE_TEST_CASE( + on_area2_and_on_year_1__hydro_level_2_4_is_chosen_level_lowered_to_1__reading_OK, + Fixture) { - AreaName yearNumber = "1"; - String level = "2.4"; - AreaName::Vector splitKey = {"hfl", "area 2", yearNumber}; - BOOST_CHECK(my_rule.readLine(splitKey, level, false)); + AreaName yearNumber = "1"; + String level = "2.4"; + AreaName::Vector splitKey = {"hfl", "area 2", yearNumber}; + BOOST_CHECK(my_rule.readLine(splitKey, level, false)); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_2->index), - 1.); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_2->index), 1.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_2->index][yearNumber.to()], - 1.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_2->index][yearNumber.to()], 1.); } -BOOST_FIXTURE_TEST_CASE(on_area3_and_on_year_3__hydro_level_neg_5_2_is_chosen__level_raised_to_0__reading_OK, Fixture) +BOOST_FIXTURE_TEST_CASE( + on_area3_and_on_year_3__hydro_level_neg_5_2_is_chosen__level_raised_to_0__reading_OK, + Fixture) { - AreaName yearNumber = "3"; - String level = "-5.2"; - AreaName::Vector splitKey = {"hfl", "area 3", yearNumber}; - BOOST_CHECK(my_rule.readLine(splitKey, level, false)); + AreaName yearNumber = "3"; + String level = "-5.2"; + AreaName::Vector splitKey = {"hfl", "area 3", yearNumber}; + BOOST_CHECK(my_rule.readLine(splitKey, level, false)); - BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_3->index), - 0.); + BOOST_CHECK_EQUAL(my_rule.hydroFinalLevels.get_value(yearNumber.to(), area_3->index), 0.); - BOOST_CHECK(my_rule.apply()); - BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_3->index][yearNumber.to()], - 0.); + BOOST_CHECK(my_rule.apply()); + BOOST_CHECK_EQUAL(study->scenarioFinalHydroLevels[area_3->index][yearNumber.to()], 0.); } // ====================== diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp index 13d5a38b48..64813637fc 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp @@ -436,7 +436,9 @@ BOOST_FIXTURE_TEST_CASE( // ======================== // Tests on Hydro final levels // ======================== -BOOST_FIXTURE_TEST_CASE(HYDRO_FINAL_LEVEL__TS_number_for_many_areas_and_years__generated_and_ref_sc_buider_files_are_identical, saveFixture) +BOOST_FIXTURE_TEST_CASE( + HYDRO_FINAL_LEVEL__TS_number_for_many_areas_and_years__generated_and_ref_sc_buider_files_are_identical, + saveFixture) { my_rule->hydroFinalLevels.setTSnumber(area_1->index, 4, 8); my_rule->hydroFinalLevels.setTSnumber(area_2->index, 11, 3); diff --git a/src/tests/src/libs/antares/test_utils.cpp b/src/tests/src/libs/antares/test_utils.cpp index ad7e97d833..5cb05e27c4 100644 --- a/src/tests/src/libs/antares/test_utils.cpp +++ b/src/tests/src/libs/antares/test_utils.cpp @@ -19,14 +19,14 @@ * along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE test utils +#include #include #include -#include - #include -#include + +#include namespace fs = std::filesystem; @@ -99,7 +99,8 @@ BOOST_AUTO_TEST_CASE(yuni_normalize_vs_std_lexically_normal) { Yuni::String yuniNorm; Yuni::IO::Normalize(yuniNorm, path.string()); - BOOST_CHECK_MESSAGE(path.lexically_normal().string() == yuniNorm, std::string("Check failed for ") + path.string()); + BOOST_CHECK_MESSAGE(path.lexically_normal().string() == yuniNorm, + std::string("Check failed for ") + path.string()); }; helper(fs::path("a/./b/..")); helper(fs::path("a/.///b/../")); diff --git a/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp b/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp index ebfbc4bba8..87978fbcaa 100644 --- a/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp +++ b/src/tests/src/libs/antares/yaml-parser/test_yaml_parser.cpp @@ -19,19 +19,22 @@ ** along with Antares_Simulator. If not, see . */ #define BOOST_TEST_MODULE yamlcpp tests -#include -#include -#include "yaml-cpp/yaml.h" -#include #include +#include #include #include +#include +#include + +#include "yaml-cpp/yaml.h" + // our data types struct Vec3 { float x, y, z; }; + struct Power { std::string name; @@ -44,6 +47,7 @@ struct Monster Vec3 position; std::vector powers; }; + namespace YAML { template<> @@ -71,6 +75,7 @@ struct convert return true; } }; + template<> struct convert { @@ -89,6 +94,7 @@ struct convert return true; } }; + template<> struct convert { @@ -108,7 +114,7 @@ struct convert rhs.name = node["name"].as(); rhs.position = node["position"].as(); const YAML::Node& powers = node["powers"]; - for (const auto power : powers) + for (const auto power: powers) { rhs.powers.push_back(power.as()); } diff --git a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp index 5f10a75879..321bd4b3e7 100644 --- a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp +++ b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp @@ -21,10 +21,11 @@ #define WIN32_LEAN_AND_MEAN #define BOOST_TEST_MODULE unfeasible_problem_analyzer +#include + #include #include #include -#include #include "antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h" #include "antares/solver/infeasible-problem-analysis/unfeasible-pb-analyzer.h" diff --git a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp index 70e4b62357..e426d99da4 100644 --- a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp +++ b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp @@ -14,16 +14,16 @@ using namespace Antares::Solver; using namespace Antares::Data; - struct Fixture { Fixture(const Fixture& f) = delete; Fixture(const Fixture&& f) = delete; Fixture& operator=(const Fixture& f) = delete; Fixture& operator=(const Fixture&& f) = delete; + Fixture() { - // Simulation last day must be 365 so that final level checks succeeds + // Simulation last day must be 365 so that final level checks succeeds study->parameters.simulationDays.end = 365; study->parameters.firstMonthInYear = january; uint nbYears = study->parameters.nbYears = 2; @@ -57,7 +57,6 @@ struct Fixture area_1->hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); area_2->hydro.deltaBetweenFinalAndInitialLevels.resize(nbYears); - // Scenario builder for initial and final reservoir levels // ------------------------------------------------------- uint areasCount = study->areas.size(); @@ -97,7 +96,7 @@ struct Fixture // ... Area 2 : Inflows time series area_2->hydro.series->storage.resize(nbInflowTS, 365); area_2->hydro.series->storage.timeSeries.fill(300.); - area_2->hydro.series->storage[0][0] = 300. + 1.; //DAYS_PER_YEAR + area_2->hydro.series->storage[0][0] = 300. + 1.; // DAYS_PER_YEAR area_2->hydro.series->storage[0][DAYS_PER_YEAR - 1] = 300. + 2.; } @@ -179,7 +178,8 @@ BOOST_AUTO_TEST_CASE(final_level_not_set_by_user____check_succeeds_but_final_lev BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); } -BOOST_AUTO_TEST_CASE(initial_level_month_and_simulation_first_month_different___check_fails_and_final_level_not_usable) +BOOST_AUTO_TEST_CASE( + initial_level_month_and_simulation_first_month_different___check_fails_and_final_level_not_usable) { uint year = 0; area_1->hydro.initializeReservoirLevelDate = 3; // initialize reservoir level != January @@ -234,7 +234,8 @@ BOOST_AUTO_TEST_CASE(final_level_out_of_rule_curves___check_fails_and_final_leve BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); } -BOOST_AUTO_TEST_CASE(final_level_unreachable_because_of_too_few_inflows___check_fails_and_final_level_not_usable) +BOOST_AUTO_TEST_CASE( + final_level_unreachable_because_of_too_few_inflows___check_fails_and_final_level_not_usable) { area_1->hydro.reservoirCapacity = 185000; uint year = 0; @@ -258,7 +259,7 @@ BOOST_AUTO_TEST_CASE(final_level_unreachable_because_of_too_few_inflows___check_ BOOST_AUTO_TEST_CASE(check_all_areas_final_levels_when_config_is_ok___all_checks_succeed) { - for (uint year : {0, 1}) + for (uint year: {0, 1}) { CheckFinalReservoirLevelsConfiguration(study->areas, study->parameters, diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 60ad9dd720..b1fabf2ff7 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -133,13 +133,13 @@ LinkPairs extractLinkNamesFromStudy(fs::path studyDir) { LinkPairs to_return; fs::path linksDir = studyDir / "input" / "links"; - for (auto const& item : fs::directory_iterator{linksDir}) + for (const auto& item: fs::directory_iterator{linksDir}) { if (item.is_directory()) { std::string sourceAreaName = item.path().filename().generic_string(); auto targetAreas = extractTargetAreas(item); - for (auto& targetAreaName : targetAreas) + for (auto& targetAreaName: targetAreas) { auto linkPair = std::make_pair(sourceAreaName, targetAreaName); to_return.push_back(linkPair); @@ -152,25 +152,26 @@ LinkPairs extractLinkNamesFromStudy(fs::path studyDir) bool pairs_match(const LinkPair& p1, const LinkPair& p2) { return (p1.first == p2.first && p1.second == p2.second) - || (p1.first == p2.second && p1.second == p2.first); + || (p1.first == p2.second && p1.second == p2.first); } const LinkPair* getMatchingPairInCollection(const LinkPair& pair, const LinkPairs& collection) { - for(const auto& p : collection) + for (const auto& p: collection) { if (pairs_match(pair, p)) + { return &p; + } } return nullptr; } -LinkPairs extractLinkNamesFromCmdLine(const LinkPairs& allLinks, - const std::string linksFromCmdLine) +LinkPairs extractLinkNamesFromCmdLine(const LinkPairs& allLinks, const std::string linksFromCmdLine) { LinkPairs to_return; LinkPairs pairsFromCmdLine = splitStringIntoPairs(linksFromCmdLine, ';', '.'); - for (auto& p : pairsFromCmdLine) + for (auto& p: pairsFromCmdLine) { if (const auto* found_pair = getMatchingPairInCollection(p, allLinks); found_pair) { @@ -198,9 +199,11 @@ bool readLinkGeneralProperty(StudyParamsForLinkTS& params, } if (key == "seed-tsgen-links") { - unsigned int seed {0}; - if (! value.to(seed)) + unsigned int seed{0}; + if (!value.to(seed)) + { return false; + } params.random.reset(seed); return true; } @@ -218,14 +221,16 @@ StudyParamsForLinkTS readGeneralParamsForLinksTS(fs::path studyDir) // Skipping sections useless in the current context Yuni::String sectionName = section->name; if (sectionName != "general" && sectionName != "seeds - Mersenne Twister") + { continue; + } for (const IniFile::Property* p = section->firstProperty; p; p = p->next) { - if (! readLinkGeneralProperty(to_return, p->key, p->value)) + if (!readLinkGeneralProperty(to_return, p->key, p->value)) { - logs.warning() << ini.filename() << ": reading value of '" - << p->key << "' went wrong"; + logs.warning() << ini.filename() << ": reading value of '" << p->key + << "' went wrong"; } } } @@ -236,7 +241,7 @@ std::vector CreateLinkList(const LinkPairs& linksFromCmd { std::vector to_return; to_return.reserve(linksFromCmdLine.size()); - for (const auto& link_pair : linksFromCmdLine) + for (const auto& link_pair: linksFromCmdLine) { LinkTSgenerationParams params; params.namesPair = link_pair; @@ -248,10 +253,12 @@ std::vector CreateLinkList(const LinkPairs& linksFromCmd LinkTSgenerationParams* findLinkInList(const LinkPair& link_to_find, std::vector& linkList) { - for(auto& link : linkList) + for (auto& link: linkList) { if (link.namesPair == link_to_find) + { return &link; + } } return nullptr; } @@ -297,16 +304,15 @@ bool readLinkIniProperty(LinkTSgenerationParams* link, return true; } -void readLinkIniProperties(LinkTSgenerationParams* link, - IniFile::Section* section) +void readLinkIniProperties(LinkTSgenerationParams* link, IniFile::Section* section) { for (const IniFile::Property* p = section->firstProperty; p; p = p->next) { - if (! readLinkIniProperty(link, p->key, p->value)) + if (!readLinkIniProperty(link, p->key, p->value)) { std::string linkName = link->namesPair.first + "." + link->namesPair.second; - logs.warning() << "Link '" << linkName << "' : reading value of '" - << p->key << "' went wrong"; + logs.warning() << "Link '" << linkName << "' : reading value of '" << p->key + << "' went wrong"; link->hasValidData = false; } } @@ -331,7 +337,7 @@ void readSourceAreaIniFile(fs::path pathToIni, void readIniProperties(std::vector& linkList, fs::path toLinksDir) { - for(auto& link : linkList) + for (auto& link: linkList) { std::string sourceAreaName = link.namesPair.first; fs::path pathToIni = toLinksDir / sourceAreaName / "properties.ini"; @@ -339,8 +345,7 @@ void readIniProperties(std::vector& linkList, fs::path t } } -bool readLinkPreproTimeSeries(LinkTSgenerationParams& link, - fs::path sourceAreaDir) +bool readLinkPreproTimeSeries(LinkTSgenerationParams& link, fs::path sourceAreaDir) { bool to_return = true; const auto preproId = link.namesPair.first + "/" + link.namesPair.second; @@ -353,21 +358,19 @@ bool readLinkPreproTimeSeries(LinkTSgenerationParams& link, if (fs::exists(preproFile)) { to_return = link.prepro->data.loadFromCSVFile( - preproFile.string(), - Data::PreproAvailability::preproAvailabilityMax, - DAYS_PER_YEAR) - && link.prepro->validate() - && to_return; + preproFile.string(), + Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && link.prepro->validate() && to_return; } auto modulationFileDirect = preproFileRoot; modulationFileDirect += "_mod_direct.txt"; if (fs::exists(modulationFileDirect)) { - to_return = link.modulationCapacityDirect.loadFromCSVFile( - modulationFileDirect.string(), - 1, - HOURS_PER_YEAR) + to_return = link.modulationCapacityDirect.loadFromCSVFile(modulationFileDirect.string(), + 1, + HOURS_PER_YEAR) && to_return; } @@ -375,10 +378,9 @@ bool readLinkPreproTimeSeries(LinkTSgenerationParams& link, modulationFileIndirect += "_mod_indirect.txt"; if (fs::exists(modulationFileIndirect)) { - to_return = link.modulationCapacityIndirect.loadFromCSVFile( - modulationFileIndirect.string(), - 1, - HOURS_PER_YEAR) + to_return = link.modulationCapacityIndirect.loadFromCSVFile(modulationFileIndirect.string(), + 1, + HOURS_PER_YEAR) && to_return; } // Makes possible a skip of TS generation when time comes @@ -386,17 +388,16 @@ bool readLinkPreproTimeSeries(LinkTSgenerationParams& link, return to_return; } -void readPreproTimeSeries(std::vector& linkList, - fs::path toLinksDir) +void readPreproTimeSeries(std::vector& linkList, fs::path toLinksDir) { - for(auto& link : linkList) + for (auto& link: linkList) { std::string sourceAreaName = link.namesPair.first; fs::path sourceAreaDir = toLinksDir / sourceAreaName; - if (! readLinkPreproTimeSeries(link, sourceAreaDir)) + if (!readLinkPreproTimeSeries(link, sourceAreaDir)) { - logs.warning() << "Could not load all prepro data for link '" - << link.namesPair.first << "." << link.namesPair.second << "'"; + logs.warning() << "Could not load all prepro data for link '" << link.namesPair.first + << "." << link.namesPair.second << "'"; } } } @@ -416,6 +417,7 @@ std::string DateAndTime() Yuni::DateTime::TimestampToString(to_return, "%Y%m%d-%H%M", now); return to_return.to(); } + // ============================================================================ int main(int argc, char* argv[]) @@ -500,10 +502,11 @@ int main(int argc, char* argv[]) // ============ LINKS : Getting data for generating LINKS time-series ===== auto allLinksPairs = extractLinkNamesFromStudy(settings.studyFolder); - auto linksFromCmdLine = extractLinkNamesFromCmdLine(allLinksPairs, - settings.linksListToGen); + auto linksFromCmdLine = extractLinkNamesFromCmdLine(allLinksPairs, settings.linksListToGen); if (settings.allLinks) + { linksFromCmdLine = allLinksPairs; + } StudyParamsForLinkTS generalParams = readGeneralParamsForLinksTS(settings.studyFolder); @@ -525,4 +528,4 @@ int main(int argc, char* argv[]) && ret; return !ret; // return 0 for success -} \ No newline at end of file +} From 52077755c797092d4409333a0fc4a1d5f12d1eb1 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Mon, 1 Jul 2024 13:47:04 +0200 Subject: [PATCH 052/127] install gh from rpm (#2216) --- .github/workflows/centos7.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index 3308dab812..573163d105 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -87,10 +87,9 @@ jobs: - name: Install gh if needed if: ${{ env.IS_RELEASE == 'true' }} run: | - yum -y install dnf - dnf -y install 'dnf-command(config-manager)' - dnf -y config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo - dnf -y install gh + wget https://github.com/cli/cli/releases/download/v2.52.0/gh_2.52.0_linux_amd64.rpm + rpm -i gh_2.52.0_linux_amd64.rpm + gh --version - name: Configure run: | From ff40ec22dbee53aa73883d60fb5ba1cfdd947546 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:25:47 +0200 Subject: [PATCH 053/127] Harmonize time constants (#2203) close #2188 --------- Co-authored-by: Florian OMNES --- src/libs/antares/date/date.cpp | 29 ++-- .../include/antares/antares/constants.h | 5 +- src/libs/antares/study/area/scratchpad.cpp | 3 +- src/solver/hydro/management/daily.cpp | 30 ++-- src/solver/hydro/management/monthly.cpp | 36 ++--- .../antares/solver/simulation/solver.hxx | 1 - src/solver/ts-generator/hydro.cpp | 12 +- src/solver/variable/CMakeLists.txt | 3 +- .../antares/solver/variable/categories.h | 59 +------- .../antares/solver/variable/constants.h | 134 ------------------ .../solver/variable/economy/STSbyGroup.h | 2 +- .../economy/STStorageCashFlowByCluster.h | 2 +- .../economy/STStorageInjectionByCluster.h | 2 +- .../economy/STStorageLevelsByCluster.h | 2 +- .../economy/STStorageWithdrawalByCluster.h | 2 +- .../economy/links/congestionProbability.h | 8 +- .../economy/productionByDispatchablePlant.h | 14 +- .../economy/productionByRenewablePlant.h | 2 +- .../include/antares/solver/variable/info.h | 30 ++-- .../include/antares/solver/variable/print.h | 102 +++++++++++-- .../include/antares/solver/variable/state.h | 22 ++- .../antares/solver/variable/storage/average.h | 16 +-- .../solver/variable/storage/averagedata.h | 8 +- .../solver/variable/storage/intermediate.h | 6 +- .../solver/variable/storage/intermediate.hxx | 14 +- .../solver/variable/storage/minmax-data.h | 8 +- .../antares/solver/variable/storage/minmax.h | 38 ++--- .../antares/solver/variable/storage/raw.h | 14 +- .../antares/solver/variable/storage/rawdata.h | 6 +- .../solver/variable/storage/stdDeviation.h | 43 +++--- .../antares/solver/variable/variable.h | 1 - src/solver/variable/state.cpp | 23 ++- src/solver/variable/storage/averagedata.cpp | 18 +-- src/solver/variable/storage/intermediate.cpp | 32 ++--- src/solver/variable/storage/rawdata.cpp | 18 +-- .../variable/surveyresults/surveyresults.cpp | 11 +- 36 files changed, 330 insertions(+), 426 deletions(-) delete mode 100644 src/solver/variable/include/antares/solver/variable/constants.h diff --git a/src/libs/antares/date/date.cpp b/src/libs/antares/date/date.cpp index 1d309201a2..acec182242 100644 --- a/src/libs/antares/date/date.cpp +++ b/src/libs/antares/date/date.cpp @@ -21,6 +21,8 @@ #include +#include + #include #include #include @@ -32,7 +34,7 @@ using namespace Yuni; namespace Antares::Date { -static const uint StandardDaysPerMonths[12] = { +static const uint StandardDaysPerMonths[MONTHS_PER_YEAR] = { 31, // january 28, // february 31, // march @@ -137,12 +139,13 @@ bool StringToMonth(MonthName& out, AnyString text) return false; } text.trim(); - CString<12, false> t = text; - t.toLower(); + std::string t = text; + boost::algorithm::to_lower(t); + /* t.toLower(); */ if (t.size() == 3) { - for (uint m = 0; m != 12; ++m) + for (uint m = 0; m != MONTHS_PER_YEAR; ++m) { if (monthShortLowerNames[m] == t) { @@ -153,7 +156,7 @@ bool StringToMonth(MonthName& out, AnyString text) } else { - for (uint m = 0; m != 12; ++m) + for (uint m = 0; m != MONTHS_PER_YEAR; ++m) { if (monthNamesLower[m] == t) { @@ -168,22 +171,22 @@ bool StringToMonth(MonthName& out, AnyString text) const char* MonthToString(int m, int offset) { - return monthNames[(m - offset) % 12]; + return monthNames[(m - offset) % MONTHS_PER_YEAR]; } const char* MonthToLowerString(int m, int offset) { - return monthNamesLower[(m - offset) % 12]; + return monthNamesLower[(m - offset) % MONTHS_PER_YEAR]; } const char* MonthToShortString(int m, int offset) { - return monthShortNames[(m - offset) % 12]; + return monthShortNames[(m - offset) % MONTHS_PER_YEAR]; } const char* MonthToUpperShortString(int m, int offset) { - return monthShortUpperNames[(m - offset) % 12]; + return monthShortUpperNames[(m - offset) % MONTHS_PER_YEAR]; } const char* WeekdayToString(int m) @@ -424,7 +427,7 @@ bool Calendar::saveToCSVFile(const AnyString& filename) const line.clear() << "hour begin\thour end\tdays\tday uear begin\tday year end\tfirst weekday"; report.months.push_back(line); - for (uint m = 0; m != 12; ++m) + for (uint m = 0; m != MONTHS_PER_YEAR; ++m) { auto& month = months[m]; line.clear(); @@ -494,10 +497,10 @@ void Calendar::reset() (void)::memset(months, '\0', sizeof(months)); // Reset months relationship - for (uint m = 0; m != 12 + 1; ++m) + for (uint m = 0; m != MONTHS_PER_YEAR + 1; ++m) { - uint realmonth = (m + (uint)settings_.firstMonth) % 12; - if (m < 12) + uint realmonth = (m + (uint)settings_.firstMonth) % MONTHS_PER_YEAR; + if (m < MONTHS_PER_YEAR) { mapping.months[realmonth] = m; } diff --git a/src/libs/antares/include/antares/antares/constants.h b/src/libs/antares/include/antares/antares/constants.h index d2bb24bacd..c29e81c1ef 100644 --- a/src/libs/antares/include/antares/antares/constants.h +++ b/src/libs/antares/include/antares/antares/constants.h @@ -51,12 +51,15 @@ #include const unsigned int HOURS_PER_DAY = 24; + +const unsigned int MONTHS_PER_YEAR = 12; +const unsigned int WEEKS_PER_YEAR = 53; const unsigned int DAYS_PER_YEAR = 365; const unsigned int HOURS_PER_YEAR = 8760; namespace Antares::Constants { -extern const std::array daysPerMonth; +extern const std::array daysPerMonth; extern const unsigned int nbHoursInAWeek; } // namespace Antares::Constants diff --git a/src/libs/antares/study/area/scratchpad.cpp b/src/libs/antares/study/area/scratchpad.cpp index a08d6b01c3..d0a1637a1d 100644 --- a/src/libs/antares/study/area/scratchpad.cpp +++ b/src/libs/antares/study/area/scratchpad.cpp @@ -66,7 +66,6 @@ AreaScratchpad::AreaScratchpad(const StudyRuntimeInfos& rinfos, Area& area): { // alias to the simulation mode auto mode = rinfos.mode; - uint nbMonthsPerYear = 12; for (uint i = 0; i != 168; ++i) { @@ -168,7 +167,7 @@ AreaScratchpad::AreaScratchpad(const StudyRuntimeInfos& rinfos, Area& area): auto& colPowerOverWater = m[PreproHydro::powerOverWater]; auto& colMaxEnergy = m[PreproHydro::maximumEnergy]; - for (uint month = 0; month < nbMonthsPerYear; ++month) + for (uint month = 0; month < MONTHS_PER_YEAR; ++month) { valueCol += colMaxEnergy[month] * (1. - colPowerOverWater[month]); } diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index 64072a5097..254ab2b1b2 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -86,11 +86,11 @@ struct DebugData std::array OVF{0}; std::array DEV{0}; std::array VIO{0}; - std::array deviationMax{0}; - std::array violationMax{0}; - std::array WASTE{0}; - std::array CoutTotal{0}; - std::array previousMonthWaste{0}; + std::array deviationMax{0}; + std::array violationMax{0}; + std::array WASTE{0}; + std::array CoutTotal{0}; + std::array previousMonthWaste{0}; Solver::IResultWriter& pWriter; const Antares::Data::AreaDependantHydroManagementData& data; @@ -163,9 +163,9 @@ struct DebugData << ".txt"; buffer << "\tNiveau init : " << hydro_specific.monthly[initReservoirLvlMonth].MOL << "\n"; - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { - uint realmonth = (initReservoirLvlMonth + month) % 12; + uint realmonth = (initReservoirLvlMonth + month) % MONTHS_PER_YEAR; uint simulationMonth = calendar.mapping.months[realmonth]; auto daysPerMonth = calendar.months[simulationMonth].days; @@ -272,7 +272,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( hydro_specific); } - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { auto daysPerMonth = calendar_.months[month].days; assert(daysPerMonth <= maxOPP); @@ -298,7 +298,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( || (area.hydro.useHeuristicTarget && !area.hydro.followLoadModulations)) { dayYear = 0; - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { auto daysPerMonth = calendar_.months[month].days; for (uint day = 0; day != daysPerMonth; ++day) @@ -313,7 +313,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( else { dayYear = 0; - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { uint realmonth = calendar_.months[month].realmonth; auto daysPerMonth = calendar_.months[month].days; @@ -371,7 +371,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations( if (debugData) { dayYear = 0; - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { auto daysPerMonth = calendar_.months[month].days; @@ -386,9 +386,9 @@ inline void HydroManagement::prepareDailyOptimalGenerations( if (not area.hydro.reservoirManagement) { - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { - uint realmonth = (initReservoirLvlMonth + month) % 12; + uint realmonth = (initReservoirLvlMonth + month) % MONTHS_PER_YEAR; uint simulationMonth = calendar_.mapping.months[realmonth]; auto daysPerMonth = calendar_.months[simulationMonth].days; @@ -453,9 +453,9 @@ inline void HydroManagement::prepareDailyOptimalGenerations( Hydro_problem_costs h2o2_optim_costs(parameters_); - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { - uint realmonth = (initReservoirLvlMonth + month) % 12; + uint realmonth = (initReservoirLvlMonth + month) % MONTHS_PER_YEAR; uint simulationMonth = calendar_.mapping.months[realmonth]; auto daysPerMonth = calendar_.months[simulationMonth].days; diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index 684ac4db16..04f2c7b107 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -59,9 +59,9 @@ static void CheckHydroAllocationProblem(Data::Area& area, { logs.warning() << area.id << ": lvi = " << lvi; logs.warning() << area.id << ": cost = " << problem.CoutDepassementVolume; - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { - uint realmonth = (initLevelMonth + month) % 12; + uint realmonth = (initLevelMonth + month) % MONTHS_PER_YEAR; logs.warning() << "month: " << ((realmonth < 10) ? "0" : "") << realmonth << ", turb.max: " << problem.TurbineMax[realmonth] << ", turb.cible: " << problem.TurbineCible[realmonth] @@ -72,9 +72,9 @@ static void CheckHydroAllocationProblem(Data::Area& area, logs.info(); problem.Volume[initLevelMonth] = lvi; - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { - uint realmonth = (initLevelMonth + month) % 12; + uint realmonth = (initLevelMonth + month) % MONTHS_PER_YEAR; logs.warning() << "month: " << ((realmonth < 10) ? "0" : "") << realmonth << ", turbine: " << problem.Turbine[realmonth] << ", volume: " << problem.Volume[realmonth]; @@ -89,14 +89,14 @@ double HydroManagement::prepareMonthlyTargetGenerations( { double total = 0; - for (uint realmonth = 0; realmonth != 12; ++realmonth) + for (uint realmonth = 0; realmonth != MONTHS_PER_YEAR; ++realmonth) { total += data.inflows[realmonth]; } if (not area.hydro.followLoadModulations) { - for (uint realmonth = 0; realmonth != 12; ++realmonth) + for (uint realmonth = 0; realmonth != MONTHS_PER_YEAR; ++realmonth) { hydro_specific.monthly[realmonth].MTG = data.inflows[realmonth]; } @@ -106,7 +106,7 @@ double HydroManagement::prepareMonthlyTargetGenerations( double monthlyMaxDemand = -std::numeric_limits::infinity(); - for (uint realmonth = 0; realmonth != 12; ++realmonth) + for (uint realmonth = 0; realmonth != MONTHS_PER_YEAR; ++realmonth) { if (hydro_specific.monthly[realmonth].MLE > monthlyMaxDemand) { @@ -117,7 +117,7 @@ double HydroManagement::prepareMonthlyTargetGenerations( if (!Utils::isZero(monthlyMaxDemand)) { double coeff = 0.; - for (uint realmonth = 0; realmonth != 12; ++realmonth) + for (uint realmonth = 0; realmonth != MONTHS_PER_YEAR; ++realmonth) { assert(hydro_specific.monthly[realmonth].MLE / monthlyMaxDemand >= 0.); coeff += std::pow(hydro_specific.monthly[realmonth].MLE / monthlyMaxDemand, @@ -129,7 +129,7 @@ double HydroManagement::prepareMonthlyTargetGenerations( coeff = total / coeff; } - for (uint realmonth = 0; realmonth != 12; ++realmonth) + for (uint realmonth = 0; realmonth != MONTHS_PER_YEAR; ++realmonth) { assert(hydro_specific.monthly[realmonth].MLE / monthlyMaxDemand >= 0.); hydro_specific.monthly[realmonth].MTG = coeff @@ -142,7 +142,7 @@ double HydroManagement::prepareMonthlyTargetGenerations( { double coeff = total / 12.; - for (uint realmonth = 0; realmonth != 12; ++realmonth) + for (uint realmonth = 0; realmonth != MONTHS_PER_YEAR; ++realmonth) { hydro_specific.monthly[realmonth].MTG = coeff; } @@ -187,9 +187,9 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ problem.CoutViolMaxDuVolumeMin = 1e5; problem.VolumeInitial = lvi; - for (unsigned month = 0; month != 12; ++month) + for (unsigned month = 0; month != MONTHS_PER_YEAR; ++month) { - uint realmonth = (initReservoirLvlMonth + month) % 12; + uint realmonth = (initReservoirLvlMonth + month) % MONTHS_PER_YEAR; uint simulationMonth = calendar_.mapping.months[realmonth]; uint firstDay = calendar_.months[simulationMonth].daysYear.first; @@ -212,9 +212,9 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ CheckHydroAllocationProblem(area, problem, initReservoirLvlMonth, lvi); } - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { - uint realmonth = (initReservoirLvlMonth + month) % 12; + uint realmonth = (initReservoirLvlMonth + month) % MONTHS_PER_YEAR; hydro_specific.monthly[realmonth].MOG = problem.Turbine[month] * area.hydro.reservoirCapacity; @@ -248,7 +248,7 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ { auto& reservoirLevel = area.hydro.reservoirLevel[Data::PartHydro::average]; - for (uint realmonth = 0; realmonth != 12; ++realmonth) + for (uint realmonth = 0; realmonth != MONTHS_PER_YEAR; ++realmonth) { hydro_specific.monthly[realmonth].MOG = data.inflows[realmonth]; hydro_specific.monthly[realmonth].MOL = reservoirLevel[realmonth]; @@ -256,7 +256,7 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ } #ifndef NDEBUG - for (uint realmonth = 0; realmonth != 12; ++realmonth) + for (uint realmonth = 0; realmonth != MONTHS_PER_YEAR; ++realmonth) { assert(!std::isnan(hydro_specific.monthly[realmonth].MOG) && "nan value detected for MOG"); @@ -292,9 +292,9 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ buffer << '\t' << "\tInflows" << '\t' << "\tTarget Gen." << "\tTurbined" << "\tLevels" << '\t' << "\tLvl min" << '\t' << "\tLvl max\n"; - for (uint month = 0; month != 12; ++month) + for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { - uint realmonth = (initReservoirLvlMonth + month) % 12; + uint realmonth = (initReservoirLvlMonth + month) % MONTHS_PER_YEAR; uint simulationMonth = calendar_.mapping.months[realmonth]; diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index cd4ddfc0a9..21e0aeb7a1 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -36,7 +36,6 @@ #include "antares/solver/simulation/opt_time_writer.h" #include "antares/solver/simulation/timeseries-numbers.h" #include "antares/solver/ts-generator/generator.h" -#include "antares/solver/variable/constants.h" #include "antares/solver/variable/print.h" namespace Antares::Solver::Simulation diff --git a/src/solver/ts-generator/hydro.cpp b/src/solver/ts-generator/hydro.cpp index 29d0a29f42..2d31f08b22 100644 --- a/src/solver/ts-generator/hydro.cpp +++ b/src/solver/ts-generator/hydro.cpp @@ -66,7 +66,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu auto& studyRTI = *(study.runtime); auto& calendar = study.calendar; - uint DIM = 12 * study.areas.size(); + uint DIM = MONTHS_PER_YEAR * study.areas.size(); uint DEM = DIM / 2; Matrix CHSKY; @@ -95,7 +95,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu for (uint i = 0; i < DIM; i++) { - uint areaIndexI = i / 12; + uint areaIndexI = i / MONTHS_PER_YEAR; auto* prepro = study.areas.byIndex[areaIndexI]->hydro.prepro; auto& corre = CORRE[i]; @@ -104,10 +104,10 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu for (uint j = 0; j < DIM; j++) { - uint areaIndexJ = j / 12; + uint areaIndexJ = j / MONTHS_PER_YEAR; auto* preproJ = study.areas.byIndex[areaIndexJ]->hydro.prepro; - x = std::abs(((int)(i % 12) - (int)(j % 12)) / 2.); + x = std::abs(((int)(i % MONTHS_PER_YEAR) - (int)(j % MONTHS_PER_YEAR)) / 2.); corre[j] = annualCorrAreaI[areaIndexJ] * pow(prepro->intermonthlyCorrelation * preproJ->intermonthlyCorrelation, x); @@ -167,7 +167,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu } for (uint i = 0; i < DIM; ++i) { - auto& area = *(study.areas.byIndex[i / 12]); + auto& area = *(study.areas.byIndex[i / MONTHS_PER_YEAR]); auto& prepro = *area.hydro.prepro; auto& series = *area.hydro.series; auto ror = series.ror[l]; @@ -178,7 +178,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu auto& colMaxEnergy = prepro.data[Data::PreproHydro::maximumEnergy]; auto& colPOW = prepro.data[Data::PreproHydro::powerOverWater]; - uint month = i % 12; + uint month = i % MONTHS_PER_YEAR; uint realmonth = calendar.months[month].realmonth; assert(l < series.ror.timeSeries.width); diff --git a/src/solver/variable/CMakeLists.txt b/src/solver/variable/CMakeLists.txt index 58009ba7b4..11ed4b5c9d 100644 --- a/src/solver/variable/CMakeLists.txt +++ b/src/solver/variable/CMakeLists.txt @@ -16,7 +16,6 @@ set(SRC_VARIABLE include/antares/solver/variable/setofareas.hxx include/antares/solver/variable/bindConstraints.h include/antares/solver/variable/bindConstraints.hxx - include/antares/solver/variable/constants.h include/antares/solver/variable/categories.h include/antares/solver/variable/surveyresults.h include/antares/solver/variable/surveyresults/reportbuilder.hxx @@ -183,4 +182,4 @@ target_link_libraries(antares-solver-variable-info install(DIRECTORY include/antares DESTINATION "include" -) \ No newline at end of file +) diff --git a/src/solver/variable/include/antares/solver/variable/categories.h b/src/solver/variable/include/antares/solver/variable/categories.h index d14b457e76..3c2df86b22 100644 --- a/src/solver/variable/include/antares/solver/variable/categories.h +++ b/src/solver/variable/include/antares/solver/variable/categories.h @@ -21,15 +21,9 @@ #ifndef __SOLVER_VARIABLE_CATEGORIES_H__ #define __SOLVER_VARIABLE_CATEGORIES_H__ -#include "constants.h" +#include -namespace Antares -{ -namespace Solver -{ -namespace Variable -{ -namespace Category +namespace Antares::Solver::Variable::Category { namespace DataLevel { @@ -266,53 +260,6 @@ inline void PrecisionLevelToStream(StreamT& out, int precisionLevel) } } -template -struct MaxRowCount -{ - enum - { - value = 0 - }; -}; - -template<> -struct MaxRowCount -{ - enum - { - value = maxHoursInAYear - }; -}; - -template<> -struct MaxRowCount -{ - enum - { - value = maxDaysInAYear - }; -}; - -template<> -struct MaxRowCount -{ - enum - { - value = maxWeeksInAYear - }; -}; - -template<> -struct MaxRowCount -{ - enum - { - value = maxMonths - }; -}; -} // namespace Category -} // namespace Variable -} // namespace Solver -} // namespace Antares +} // namespace Antares::Solver::Variable::Category #endif // __SOLVER_VARIABLE_CATEGORIES_H__ diff --git a/src/solver/variable/include/antares/solver/variable/constants.h b/src/solver/variable/include/antares/solver/variable/constants.h deleted file mode 100644 index cea6298346..0000000000 --- a/src/solver/variable/include/antares/solver/variable/constants.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ -#ifndef __SOLVER_VARIABLE_CONSTANT_H__ -#define __SOLVER_VARIABLE_CONSTANT_H__ - -namespace Antares -{ -namespace Solver -{ -namespace Variable -{ -constexpr unsigned int maxHoursInAYear = 8785; -constexpr unsigned int maxDaysInAYear = 7 * 53 + 1; // 366, -constexpr unsigned int maxWeeksInAYear = 53; -constexpr unsigned int maxHoursInADay = 24; -constexpr unsigned int maxMonths = 12; -constexpr unsigned int maxDaysInAWeek = 7; -constexpr unsigned int maxHoursInAWeek = 24 * 7; // 168 - -template -struct PrecisionToPrintfFormat -{ - static const char* Value() - { - return "%.6f"; - } -}; - -template<> -struct PrecisionToPrintfFormat<0> -{ - static const char* Value() - { - return "%.0f"; - } -}; - -template<> -struct PrecisionToPrintfFormat<1> -{ - static const char* Value() - { - return "%.1f"; - } -}; - -template<> -struct PrecisionToPrintfFormat<2> -{ - static const char* Value() - { - return "%.2f"; - } -}; - -template<> -struct PrecisionToPrintfFormat<3> -{ - static const char* Value() - { - return "%.3f"; - } -}; - -template<> -struct PrecisionToPrintfFormat<4> -{ - static const char* Value() - { - return "%.4f"; - } -}; - -template<> -struct PrecisionToPrintfFormat<5> -{ - static const char* Value() - { - return "%.5f"; - } -}; - -template -static inline void AssignPrecisionToPrintfFormat(StringT& out, uint precision) -{ - switch (precision) - { - case 0: - out.assign("%.0f", 4); - break; - case 1: - out.assign("%.1f", 4); - break; - case 2: - out.assign("%.2f", 4); - break; - case 3: - out.assign("%.3f", 4); - break; - case 4: - out.assign("%.4f", 4); - break; - case 5: - out.assign("%.5f", 4); - break; - default: - out.assign("%.6f", 4); - break; - } -} - -} // namespace Variable -} // namespace Solver -} // namespace Antares - -#endif // __SOLVER_VARIABLE_CONSTANT_H__ diff --git a/src/solver/variable/include/antares/solver/variable/economy/STSbyGroup.h b/src/solver/variable/include/antares/solver/variable/economy/STSbyGroup.h index 70adaea52a..4e3ad6ee7c 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/STSbyGroup.h +++ b/src/solver/variable/include/antares/solver/variable/economy/STSbyGroup.h @@ -341,7 +341,7 @@ class STSbyGroup: public Variable::IVariable, NextT, VCardSTSb { uint64_t r = (sizeof(IntermediateValues) * nbColumns_ + IntermediateValues::MemoryUsage()) * pNbYearsParallel; - r += sizeof(double) * nbColumns_ * maxHoursInAYear * pNbYearsParallel; + r += sizeof(double) * nbColumns_ * HOURS_PER_YEAR * pNbYearsParallel; r += AncestorType::memoryUsage(); return r; } diff --git a/src/solver/variable/include/antares/solver/variable/economy/STStorageCashFlowByCluster.h b/src/solver/variable/include/antares/solver/variable/economy/STStorageCashFlowByCluster.h index db6beb4c95..eb2eaa48b9 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/STStorageCashFlowByCluster.h +++ b/src/solver/variable/include/antares/solver/variable/economy/STStorageCashFlowByCluster.h @@ -263,7 +263,7 @@ class STstorageCashFlowByCluster: public Variable::IVariableareaWideIndex] .hour[i]; state.thermalClusterPMinOfTheClusterForYear[i] += pminOfTheClusterForYear - [numSpace][(state.thermalCluster->areaWideIndex * maxHoursInAYear) + i]; + [numSpace][(state.thermalCluster->areaWideIndex * HOURS_PER_YEAR) + i]; } // Next variable @@ -322,8 +322,8 @@ class ProductionByDispatchablePlant pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].hour[state.hourInTheYear] += thermal[area->index].thermalClustersProductions[cluster->areaWideIndex]; - pminOfTheClusterForYear[numSpace][(cluster->areaWideIndex * maxHoursInAYear) - + state.hourInTheYear] + pminOfTheClusterForYear[numSpace] + [(cluster->areaWideIndex * HOURS_PER_YEAR) + state.hourInTheYear] = thermal[area->index].PMinOfClusters[cluster->areaWideIndex]; } @@ -348,7 +348,7 @@ class ProductionByDispatchablePlant { uint64_t r = (sizeof(IntermediateValues) * pSize + IntermediateValues::MemoryUsage()) * pNbYearsParallel; - r += sizeof(double) * pSize * maxHoursInAYear * pNbYearsParallel; + r += sizeof(double) * pSize * HOURS_PER_YEAR * pNbYearsParallel; r += AncestorType::memoryUsage(); return r; } diff --git a/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h index 8da6244e49..82ce7b3dcf 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h @@ -312,7 +312,7 @@ class ProductionByRenewablePlant: public Variable::IVariable::ReturnType array = intermediateValues[i].hour; - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { array[y] *= v; } @@ -88,7 +88,7 @@ struct VariableAccessor for (uint i = 0; i != ColumnCountT; ++i) { Antares::Memory::Stored::ReturnType array = intermediateValues[i].hour; - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { array[y] = std::abs(array[y]) > 0. ? 1. : 0.; } @@ -101,7 +101,7 @@ struct VariableAccessor for (uint i = 0; i != ColumnCountT; ++i) { Antares::Memory::Stored::ReturnType array = intermediateValues[i].hour; - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { array[y] = std::abs(array[y]) > 0. ? 100. : 0.; } @@ -247,7 +247,7 @@ struct VariableAccessor = var.retrieveRawHourlyValuesForCurrentYear(i, numSpace); assert(src != NULL); - for (uint h = 0; h != maxHoursInAYear; ++h) + for (uint h = 0; h != HOURS_PER_YEAR; ++h) { out[i].hour[h] += src[h]; } @@ -263,7 +263,7 @@ struct VariableAccessor = var.retrieveRawHourlyValuesForCurrentYear(i, numSpace); assert(src != NULL); - for (uint h = 0; h != maxHoursInAYear; ++h) + for (uint h = 0; h != HOURS_PER_YEAR; ++h) { if (out[i].hour[h] < src[h]) { @@ -289,7 +289,7 @@ struct VariableAccessor for (typename Type::const_iterator i = intermediateValues.begin(); i != end; ++i) { array = (*i).hour; - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { array[y] *= v; } @@ -304,7 +304,7 @@ struct VariableAccessor for (typename Type::const_iterator i = intermediateValues.begin(); i != end; ++i) { array = (*i).hour; - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { array[y] = std::abs(array[y]) > 0. ? 1. : 0.; } @@ -319,7 +319,7 @@ struct VariableAccessor for (typename Type::const_iterator i = intermediateValues.begin(); i != end; ++i) { array = (*i).hour; - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { array[y] = std::abs(array[y]) > 0. ? 100. : 0.; } @@ -516,7 +516,7 @@ struct VariableAccessor = var.retrieveRawHourlyValuesForCurrentYear(i, numSpace); assert(src != NULL); - for (uint h = 0; h != maxHoursInAYear; ++h) + for (uint h = 0; h != HOURS_PER_YEAR; ++h) { out[i].hour[h] += src[h]; } @@ -532,7 +532,7 @@ struct VariableAccessor = var.retrieveRawHourlyValuesForCurrentYear(i, numSpace); assert(src != NULL); - for (uint h = 0; h != maxHoursInAYear; ++h) + for (uint h = 0; h != HOURS_PER_YEAR; ++h) { if (out[i].hour[h] < src[h]) { @@ -553,7 +553,7 @@ struct VariableAccessor static void MultiplyHourlyResultsBy(U& intermediateValues, const double v) { assert(!std::isnan(v)); - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { intermediateValues.hour[y] *= v; } @@ -562,7 +562,7 @@ struct VariableAccessor template static void SetTo1IfPositive(U& intermediateValues) { - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { intermediateValues.hour[y] = std::abs(intermediateValues.hour[y]) > 0. ? 1. : 0.; } @@ -571,7 +571,7 @@ struct VariableAccessor template static void Or(U& intermediateValues) { - for (uint y = 0; y != maxHoursInAYear; ++y) + for (uint y = 0; y != HOURS_PER_YEAR; ++y) { intermediateValues.hour[y] = std::abs(intermediateValues.hour[y]) > 0. ? 100. : 0.; } @@ -683,7 +683,7 @@ struct VariableAccessor = var.retrieveRawHourlyValuesForCurrentYear(-1, numSpace); assert(src != NULL); - for (uint h = 0; h != maxHoursInAYear; ++h) + for (uint h = 0; h != HOURS_PER_YEAR; ++h) { out.hour[h] += src[h]; } @@ -696,7 +696,7 @@ struct VariableAccessor = var.retrieveRawHourlyValuesForCurrentYear(-1, numSpace); assert(src != NULL); - for (uint h = 0; h != maxHoursInAYear; ++h) + for (uint h = 0; h != HOURS_PER_YEAR; ++h) { if (out.hour[h] < src[h]) { diff --git a/src/solver/variable/include/antares/solver/variable/print.h b/src/solver/variable/include/antares/solver/variable/print.h index 9f398ab86b..5ac4b0617a 100644 --- a/src/solver/variable/include/antares/solver/variable/print.h +++ b/src/solver/variable/include/antares/solver/variable/print.h @@ -23,11 +23,7 @@ #include -namespace Antares -{ -namespace Solver -{ -namespace Variable +namespace Antares::Solver::Variable { class PrintInfosStdCout final { @@ -86,8 +82,98 @@ class PrintInfosStdCout final Yuni::String pBuffer; }; -} // namespace Variable -} // namespace Solver -} // namespace Antares +template +struct PrecisionToPrintfFormat +{ + static const char* Value() + { + return "%.6f"; + } +}; + +template<> +struct PrecisionToPrintfFormat<0> +{ + static const char* Value() + { + return "%.0f"; + } +}; + +template<> +struct PrecisionToPrintfFormat<1> +{ + static const char* Value() + { + return "%.1f"; + } +}; + +template<> +struct PrecisionToPrintfFormat<2> +{ + static const char* Value() + { + return "%.2f"; + } +}; + +template<> +struct PrecisionToPrintfFormat<3> +{ + static const char* Value() + { + return "%.3f"; + } +}; + +template<> +struct PrecisionToPrintfFormat<4> +{ + static const char* Value() + { + return "%.4f"; + } +}; + +template<> +struct PrecisionToPrintfFormat<5> +{ + static const char* Value() + { + return "%.5f"; + } +}; + +template +static inline void AssignPrecisionToPrintfFormat(StringT& out, uint precision) +{ + switch (precision) + { + case 0: + out.assign("%.0f", 4); + break; + case 1: + out.assign("%.1f", 4); + break; + case 2: + out.assign("%.2f", 4); + break; + case 3: + out.assign("%.3f", 4); + break; + case 4: + out.assign("%.4f", 4); + break; + case 5: + out.assign("%.5f", 4); + break; + default: + out.assign("%.6f", 4); + break; + } +} + +} // namespace Antares::Solver::Variable #endif // __SOLVER_VARIABLE_PRINT_H__ diff --git a/src/solver/variable/include/antares/solver/variable/state.h b/src/solver/variable/include/antares/solver/variable/state.h index 597b692d9e..eb3edda98c 100644 --- a/src/solver/variable/include/antares/solver/variable/state.h +++ b/src/solver/variable/include/antares/solver/variable/state.h @@ -32,8 +32,6 @@ #include "antares/solver/simulation/sim_structure_donnees.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" -#include "constants.h" - namespace Antares::Solver::Variable { class ThermalState @@ -115,14 +113,14 @@ class State void yearEndBuildThermalClusterCalculateStartupCosts( const uint& maxDurationON, - const std::array& ON_min, - const std::array& ON_opt, + const std::array& ON_min, + const std::array& ON_opt, const Data::ThermalCluster* currentCluster); - std::array computeEconomicallyOptimalNbClustersONforEachHour( + std::array computeEconomicallyOptimalNbClustersONforEachHour( const uint& maxDurationON, - const std::array& ON_min, - const std::array& ON_max) const; + const std::array& ON_min, + const std::array& ON_max) const; /*! ** \brief Smooth the thermal units run after resolutions @@ -182,17 +180,17 @@ class State VALEURS_DE_NTC_ET_RESISTANCES ntc; //! Thermal production for the current thermal cluster for the whole year - double thermalClusterProductionForYear[Variable::maxHoursInAYear]; + double thermalClusterProductionForYear[HOURS_PER_YEAR]; //! Number of unit dispatched for all clusters for the whole year for ucHeruistic (fast) or //! ucMILP (accurate) - uint thermalClusterDispatchedUnitsCountForYear[Variable::maxHoursInAYear]; + uint thermalClusterDispatchedUnitsCountForYear[HOURS_PER_YEAR]; //! Thermal operating cost for the current thermal cluster for the whole year - double thermalClusterOperatingCostForYear[Variable::maxHoursInAYear]; + double thermalClusterOperatingCostForYear[HOURS_PER_YEAR]; //! Thermal NP Cost for the current thermal cluster for the whole year - double thermalClusterNonProportionalCostForYear[Variable::maxHoursInAYear]; + double thermalClusterNonProportionalCostForYear[HOURS_PER_YEAR]; //! Minimum power of the cluster for the whole year - double thermalClusterPMinOfTheClusterForYear[Variable::maxHoursInAYear]; + double thermalClusterPMinOfTheClusterForYear[HOURS_PER_YEAR]; double renewableClusterProduction; diff --git a/src/solver/variable/include/antares/solver/variable/storage/average.h b/src/solver/variable/include/antares/solver/variable/storage/average.h index 0597d121b8..380915e284 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/average.h +++ b/src/solver/variable/include/antares/solver/variable/storage/average.h @@ -100,20 +100,20 @@ struct Average: public NextT switch (precision) { case Category::hourly: - InternalExportValues(report, - Memory::RawPointer( - avgdata.hourly)); + InternalExportValues(report, + Memory::RawPointer( + avgdata.hourly)); break; case Category::daily: - InternalExportValues(report, - avgdata.daily); + InternalExportValues(report, avgdata.daily); break; case Category::weekly: - InternalExportValues(report, - avgdata.weekly); + InternalExportValues(report, + avgdata.weekly); break; case Category::monthly: - InternalExportValues(report, avgdata.monthly); + InternalExportValues(report, + avgdata.monthly); break; case Category::annual: InternalExportValues<1, VCardT, Category::annual>(report, avgdata.year); diff --git a/src/solver/variable/include/antares/solver/variable/storage/averagedata.h b/src/solver/variable/include/antares/solver/variable/storage/averagedata.h index 22de3ff8c8..0ed11ae239 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/averagedata.h +++ b/src/solver/variable/include/antares/solver/variable/storage/averagedata.h @@ -54,13 +54,13 @@ class AverageData uint64_t dynamicMemoryUsage() const { - return sizeof(double) * maxHoursInAYear + sizeof(double) * nbYearsCapacity; + return sizeof(double) * HOURS_PER_YEAR + sizeof(double) * nbYearsCapacity; } public: - double monthly[maxMonths]; - double weekly[maxWeeksInAYear]; - double daily[maxDaysInAYear]; + double monthly[MONTHS_PER_YEAR]; + double weekly[WEEKS_PER_YEAR]; + double daily[DAYS_PER_YEAR]; Antares::Memory::Stored::Type hourly; double* year; unsigned int nbYearsCapacity; diff --git a/src/solver/variable/include/antares/solver/variable/storage/intermediate.h b/src/solver/variable/include/antares/solver/variable/storage/intermediate.h index 44f54918ad..e7c1757c62 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/intermediate.h +++ b/src/solver/variable/include/antares/solver/variable/storage/intermediate.h @@ -133,11 +133,11 @@ class IntermediateValues final Antares::Data::StudyRuntimeInfos* pRuntimeInfo; //! Values for each month - Type month[maxMonths]; + Type month[MONTHS_PER_YEAR]; //! Values for each week - Type week[maxWeeksInAYear]; + Type week[WEEKS_PER_YEAR]; //! Values for each day in the year - Type day[maxDaysInAYear]; + Type day[DAYS_PER_YEAR]; //! Values for each hour in the year mutable Antares::Memory::Stored::Type hour; //! Year diff --git a/src/solver/variable/include/antares/solver/variable/storage/intermediate.hxx b/src/solver/variable/include/antares/solver/variable/storage/intermediate.hxx index 132b2caba5..9dd74a235a 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/intermediate.hxx +++ b/src/solver/variable/include/antares/solver/variable/storage/intermediate.hxx @@ -21,6 +21,8 @@ #ifndef __SOLVER_VARIABLE_STORAGE_INTERMEDIATE_HXX__ #define __SOLVER_VARIABLE_STORAGE_INTERMEDIATE_HXX__ +#include + namespace Antares { namespace Solver @@ -34,7 +36,7 @@ inline IntermediateValues::~IntermediateValues() inline void IntermediateValues::reset() { - Antares::Memory::Zero(maxHoursInAYear, hour); + Antares::Memory::Zero(HOURS_PER_YEAR, hour); memset(month, 0, sizeof(month)); memset(week, 0, sizeof(week)); memset(day, 0, sizeof(day)); @@ -53,7 +55,7 @@ inline const IntermediateValues::Type& IntermediateValues::operator[]( inline uint64_t IntermediateValues::MemoryUsage() { - return +sizeof(Type) * maxHoursInAYear; + return +sizeof(Type) * HOURS_PER_YEAR; } template @@ -66,16 +68,16 @@ inline void IntermediateValues::buildAnnualSurveyReport(SurveyResults& report, switch (precision) { case Category::hourly: - internalExportAnnualValues(report, hour, false); + internalExportAnnualValues(report, hour, false); break; case Category::daily: - internalExportAnnualValues(report, day, false); + internalExportAnnualValues(report, day, false); break; case Category::weekly: - internalExportAnnualValues(report, week, false); + internalExportAnnualValues(report, week, false); break; case Category::monthly: - internalExportAnnualValues(report, month, false); + internalExportAnnualValues(report, month, false); break; case Category::annual: internalExportAnnualValues<1, VCardT>(report, &year, true); diff --git a/src/solver/variable/include/antares/solver/variable/storage/minmax-data.h b/src/solver/variable/include/antares/solver/variable/storage/minmax-data.h index 156f53fec2..27bc3e89b4 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/minmax-data.h +++ b/src/solver/variable/include/antares/solver/variable/storage/minmax-data.h @@ -46,10 +46,10 @@ class MinMaxData void mergeSup(uint year, const IntermediateValues& rhs); std::vector annual{1}; - std::vector monthly{maxMonths}; - std::vector weekly{maxWeeksInAYear}; - std::vector daily{maxDaysInAYear}; - std::vector hourly{maxHoursInAYear}; + std::vector monthly{MONTHS_PER_YEAR}; + std::vector weekly{WEEKS_PER_YEAR}; + std::vector daily{DAYS_PER_YEAR}; + std::vector hourly{HOURS_PER_YEAR}; }; // class MinMaxData diff --git a/src/solver/variable/include/antares/solver/variable/storage/minmax.h b/src/solver/variable/include/antares/solver/variable/storage/minmax.h index 7866d1a271..6095863374 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/minmax.h +++ b/src/solver/variable/include/antares/solver/variable/storage/minmax.h @@ -83,23 +83,25 @@ struct MinMaxBase: public NextT switch (precision) { case Category::hourly: - InternalExportIndices(report, - Memory::RawPointer( - minmax.hourly.data()), - fileLevel); + InternalExportIndices(report, + Memory::RawPointer( + minmax.hourly.data()), + fileLevel); break; case Category::daily: - InternalExportIndices(report, - minmax.daily.data(), - fileLevel); + InternalExportIndices(report, + minmax.daily.data(), + fileLevel); break; case Category::weekly: - InternalExportIndices(report, - minmax.weekly.data(), - fileLevel); + InternalExportIndices(report, + minmax.weekly.data(), + fileLevel); break; case Category::monthly: - InternalExportIndices(report, minmax.monthly.data(), fileLevel); + InternalExportIndices(report, + minmax.monthly.data(), + fileLevel); break; case Category::annual: InternalExportIndices<1, VCardT>(report, minmax.annual.data(), fileLevel); @@ -111,18 +113,18 @@ struct MinMaxBase: public NextT switch (precision) { case Category::hourly: - InternalExportValues(report, - Memory::RawPointer( - minmax.hourly.data())); + InternalExportValues(report, + Memory::RawPointer( + minmax.hourly.data())); break; case Category::daily: - InternalExportValues(report, minmax.daily.data()); + InternalExportValues(report, minmax.daily.data()); break; case Category::weekly: - InternalExportValues(report, minmax.weekly.data()); + InternalExportValues(report, minmax.weekly.data()); break; case Category::monthly: - InternalExportValues(report, minmax.monthly.data()); + InternalExportValues(report, minmax.monthly.data()); break; case Category::annual: InternalExportValues<1, VCardT>(report, minmax.annual.data()); @@ -143,7 +145,7 @@ struct MinMaxBase: public NextT uint64_t memoryUsage() const { - return sizeof(double) * maxHoursInAYear + NextType::memoryUsage(); + return sizeof(double) * HOURS_PER_YEAR + NextType::memoryUsage(); } template class DecoratorT> diff --git a/src/solver/variable/include/antares/solver/variable/storage/raw.h b/src/solver/variable/include/antares/solver/variable/storage/raw.h index be1c3d9699..e71356953f 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/raw.h +++ b/src/solver/variable/include/antares/solver/variable/storage/raw.h @@ -104,20 +104,20 @@ struct Raw: public NextT switch (precision) { case Category::hourly: - InternalExportValues( + InternalExportValues( report, ::Antares::Memory::RawPointer(rawdata.hourly)); break; case Category::daily: - InternalExportValues(report, - rawdata.daily); + InternalExportValues(report, rawdata.daily); break; case Category::weekly: - InternalExportValues(report, - rawdata.weekly); + InternalExportValues(report, + rawdata.weekly); break; case Category::monthly: - InternalExportValues(report, rawdata.monthly); + InternalExportValues(report, + rawdata.monthly); break; case Category::annual: InternalExportValues(report, rawdata.year); @@ -161,7 +161,7 @@ struct Raw: public NextT uint64_t memoryUsage() const { - return +sizeof(double) * maxHoursInAYear + NextType::memoryUsage(); + return +sizeof(double) * HOURS_PER_YEAR + NextType::memoryUsage(); } template class DecoratorT> diff --git a/src/solver/variable/include/antares/solver/variable/storage/rawdata.h b/src/solver/variable/include/antares/solver/variable/storage/rawdata.h index c559dd57dc..6a2c118c05 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/rawdata.h +++ b/src/solver/variable/include/antares/solver/variable/storage/rawdata.h @@ -56,9 +56,9 @@ class RawData void merge(unsigned int year, const IntermediateValues& rhs); public: - double monthly[maxMonths]; - double weekly[maxWeeksInAYear]; - double daily[maxDaysInAYear]; + double monthly[MONTHS_PER_YEAR]; + double weekly[WEEKS_PER_YEAR]; + double daily[DAYS_PER_YEAR]; Antares::Memory::Stored::Type hourly; double* year; mutable double allYears; diff --git a/src/solver/variable/include/antares/solver/variable/storage/stdDeviation.h b/src/solver/variable/include/antares/solver/variable/storage/stdDeviation.h index a80ac39fdc..44159d9cba 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/stdDeviation.h +++ b/src/solver/variable/include/antares/solver/variable/storage/stdDeviation.h @@ -77,7 +77,7 @@ struct StdDeviation: public NextT protected: void initializeFromStudy(Antares::Data::Study& study) { - Antares::Memory::Allocate(stdDeviationHourly, maxHoursInAYear); + Antares::Memory::Allocate(stdDeviationHourly, HOURS_PER_YEAR); // Next NextType::initializeFromStudy(study); @@ -88,10 +88,10 @@ struct StdDeviation: public NextT void reset() { // Reset - (void)::memset(stdDeviationMonthly, 0, sizeof(double) * maxMonths); - (void)::memset(stdDeviationWeekly, 0, sizeof(double) * maxWeeksInAYear); - (void)::memset(stdDeviationDaily, 0, sizeof(double) * maxDaysInAYear); - Antares::Memory::Zero(maxHoursInAYear, stdDeviationHourly); + (void)::memset(stdDeviationMonthly, 0, sizeof(double) * MONTHS_PER_YEAR); + (void)::memset(stdDeviationWeekly, 0, sizeof(double) * WEEKS_PER_YEAR); + (void)::memset(stdDeviationDaily, 0, sizeof(double) * DAYS_PER_YEAR); + Antares::Memory::Zero(HOURS_PER_YEAR, stdDeviationHourly); stdDeviationYear = 0.; // Next NextType::reset(); @@ -104,22 +104,22 @@ struct StdDeviation: public NextT unsigned int i; // StdDeviation value for each hour throughout all years - for (i = 0; i != maxHoursInAYear; ++i) + for (i = 0; i != HOURS_PER_YEAR; ++i) { stdDeviationHourly[i] += rhs.hour[i] * rhs.hour[i] * pRatio; } // StdDeviation value for each day throughout all years - for (i = 0; i != maxDaysInAYear; ++i) + for (i = 0; i != DAYS_PER_YEAR; ++i) { stdDeviationDaily[i] += rhs.day[i] * rhs.day[i] * pRatio; } // StdDeviation value for each week throughout all years - for (i = 0; i != maxWeeksInAYear; ++i) + for (i = 0; i != WEEKS_PER_YEAR; ++i) { stdDeviationWeekly[i] += rhs.week[i] * rhs.week[i] * pRatio; } // StdDeviation value for each month throughout all years - for (i = 0; i != maxMonths; ++i) + for (i = 0; i != MONTHS_PER_YEAR; ++i) { stdDeviationMonthly[i] += rhs.month[i] * rhs.month[i] * pRatio; } @@ -142,26 +142,27 @@ struct StdDeviation: public NextT switch (precision) { case Category::hourly: - InternalExportValues( + InternalExportValues( report, results, Memory::RawPointer(stdDeviationHourly)); break; case Category::daily: - InternalExportValues(report, - results, - stdDeviationDaily); + InternalExportValues(report, + results, + stdDeviationDaily); break; case Category::weekly: - InternalExportValues( + InternalExportValues( report, results, stdDeviationWeekly); break; case Category::monthly: - InternalExportValues(report, - results, - stdDeviationMonthly); + InternalExportValues( + report, + results, + stdDeviationMonthly); break; case Category::annual: InternalExportValues(report, @@ -180,7 +181,7 @@ struct StdDeviation: public NextT uint64_t memoryUsage() const { - return sizeof(double) * maxHoursInAYear + NextType::memoryUsage(); + return sizeof(double) * HOURS_PER_YEAR + NextType::memoryUsage(); } template class DecoratorT> @@ -194,9 +195,9 @@ struct StdDeviation: public NextT } public: - double stdDeviationMonthly[maxMonths]; - double stdDeviationWeekly[maxWeeksInAYear]; - double stdDeviationDaily[maxDaysInAYear]; + double stdDeviationMonthly[MONTHS_PER_YEAR]; + double stdDeviationWeekly[WEEKS_PER_YEAR]; + double stdDeviationDaily[DAYS_PER_YEAR]; Antares::Memory::Stored::Type stdDeviationHourly; double stdDeviationYear; diff --git a/src/solver/variable/include/antares/solver/variable/variable.h b/src/solver/variable/include/antares/solver/variable/variable.h index 536af9107f..279ba9da3d 100644 --- a/src/solver/variable/include/antares/solver/variable/variable.h +++ b/src/solver/variable/include/antares/solver/variable/variable.h @@ -30,7 +30,6 @@ #include #include "categories.h" -#include "constants.h" #include "container.h" #include "endoflist.h" #include "info.h" diff --git a/src/solver/variable/state.cpp b/src/solver/variable/state.cpp index 9318e49f21..ca8d5b2677 100644 --- a/src/solver/variable/state.cpp +++ b/src/solver/variable/state.cpp @@ -234,20 +234,20 @@ void State::yearEndBuildFromThermalClusterIndex(const uint clusterAreaWideIndex) uint endHourForCurrentYear = startHourForCurrentYear + study.runtime->rangeLimits.hour[Data::rangeCount]; - assert(endHourForCurrentYear <= Variable::maxHoursInAYear); + assert(endHourForCurrentYear <= HOURS_PER_YEAR); // Nombre minimal de groupes en fonctionnement à l'heure h (determiné par Peff et Pnom) - std::array ON_min; + std::array ON_min; // Nombre maximal de groupes en fonctionnement à l'heure h (determine par Peff et Pmin) - std::array ON_max; + std::array ON_max; // Nombre de groupes économiquement optimal en fonctionnement à l'heure h - std::array ON_opt{}; + std::array ON_opt{}; // Get cluster properties Data::ThermalCluster* currentCluster = area->thermal.list.enabledClusterAt(clusterAreaWideIndex) .get(); - assert(endHourForCurrentYear <= Variable::maxHoursInAYear); + assert(endHourForCurrentYear <= HOURS_PER_YEAR); assert(endHourForCurrentYear <= currentCluster->series.timeSeries.height); assert(currentCluster); @@ -373,8 +373,8 @@ void State::yearEndBuildFromThermalClusterIndex(const uint clusterAreaWideIndex) void State::yearEndBuildThermalClusterCalculateStartupCosts( const uint& maxDurationON, - const std::array& ON_min, - const std::array& ON_opt, + const std::array& ON_min, + const std::array& ON_opt, const Data::ThermalCluster* currentCluster) { uint startHourForCurrentYear = study.runtime->rangeLimits.hour[Data::rangeBegin]; @@ -422,18 +422,17 @@ void State::yearEndBuildThermalClusterCalculateStartupCosts( } } -std::array -State::computeEconomicallyOptimalNbClustersONforEachHour( +std::array State::computeEconomicallyOptimalNbClustersONforEachHour( const uint& maxDurationON, - const std::array& ON_min, - const std::array& ON_max) const + const std::array& ON_min, + const std::array& ON_max) const { uint startHourForCurrentYear = study.runtime->rangeLimits.hour[Data::rangeBegin]; uint endHourForCurrentYear = startHourForCurrentYear + study.runtime->rangeLimits.hour[Data::rangeCount]; // Nombre de groupes économiquement optimal en fonctionnement à l'heure h - std::array ON_opt; + std::array ON_opt; uint nivmax; // valeur maximale de ON_opt[h] , progressivement réactualisée à la baisse uint nivmin; // valeur minimale de ON_opt[h] , progressivement réactualisée à la hausse diff --git a/src/solver/variable/storage/averagedata.cpp b/src/solver/variable/storage/averagedata.cpp index aceaf26dcc..4a88945bb6 100644 --- a/src/solver/variable/storage/averagedata.cpp +++ b/src/solver/variable/storage/averagedata.cpp @@ -45,16 +45,16 @@ AverageData::~AverageData() void AverageData::reset() { - Antares::Memory::Zero(maxHoursInAYear, hourly); - (void)::memset(monthly, 0, sizeof(double) * maxMonths); - (void)::memset(weekly, 0, sizeof(double) * maxWeeksInAYear); - (void)::memset(daily, 0, sizeof(double) * maxDaysInAYear); + Antares::Memory::Zero(HOURS_PER_YEAR, hourly); + (void)::memset(monthly, 0, sizeof(double) * MONTHS_PER_YEAR); + (void)::memset(weekly, 0, sizeof(double) * WEEKS_PER_YEAR); + (void)::memset(daily, 0, sizeof(double) * DAYS_PER_YEAR); (void)::memset(year, 0, sizeof(double) * nbYearsCapacity); } void AverageData::initializeFromStudy(Data::Study& study) { - Antares::Memory::Allocate(hourly, maxHoursInAYear); + Antares::Memory::Allocate(hourly, HOURS_PER_YEAR); nbYearsCapacity = study.runtime->rangeLimits.year[Data::rangeEnd] + 1; year = new double[nbYearsCapacity]; @@ -70,22 +70,22 @@ void AverageData::merge(unsigned int y, const IntermediateValues& rhs) double ratio = (double)yearsWeight[y] / (double)yearsWeightSum; // Average value for each hour throughout all years - for (i = 0; i != maxHoursInAYear; ++i) + for (i = 0; i != HOURS_PER_YEAR; ++i) { hourly[i] += rhs.hour[i] * ratio; } // Average value for each day throughout all years - for (i = 0; i != maxDaysInAYear; ++i) + for (i = 0; i != DAYS_PER_YEAR; ++i) { daily[i] += rhs.day[i] * ratio; } // Average value for each week throughout all years - for (i = 0; i != maxWeeksInAYear; ++i) + for (i = 0; i != WEEKS_PER_YEAR; ++i) { weekly[i] += rhs.week[i] * ratio; } // Average value for each month throughout all years - for (i = 0; i != maxMonths; ++i) + for (i = 0; i != MONTHS_PER_YEAR; ++i) { monthly[i] += rhs.month[i] * ratio; } diff --git a/src/solver/variable/storage/intermediate.cpp b/src/solver/variable/storage/intermediate.cpp index 5fb15cc2f4..4799085aaf 100644 --- a/src/solver/variable/storage/intermediate.cpp +++ b/src/solver/variable/storage/intermediate.cpp @@ -35,11 +35,11 @@ IntermediateValues::IntermediateValues(): calendar(nullptr), year(0.) { - Antares::Memory::Allocate(hour, maxHoursInAYear); - Antares::Memory::Zero(maxHoursInAYear, hour); - (void)::memset(month, 0, sizeof(Type) * maxMonths); - (void)::memset(week, 0, sizeof(Type) * maxWeeksInAYear); - (void)::memset(day, 0, sizeof(Type) * maxDaysInAYear); + Antares::Memory::Allocate(hour, HOURS_PER_YEAR); + Antares::Memory::Zero(HOURS_PER_YEAR, hour); + (void)::memset(month, 0, sizeof(Type) * MONTHS_PER_YEAR); + (void)::memset(week, 0, sizeof(Type) * WEEKS_PER_YEAR); + (void)::memset(day, 0, sizeof(Type) * DAYS_PER_YEAR); } void IntermediateValues::initializeFromStudy(Data::Study& study) @@ -87,9 +87,9 @@ void IntermediateValues::computeStatisticsForTheCurrentYear() { double d = 0.; // One day - for (j = 0; j != maxHoursInADay; ++j) + for (j = 0; j != HOURS_PER_DAY; ++j) { - assert(indx < maxHoursInAYear); + assert(indx < HOURS_PER_YEAR); d += hour[indx]; ++indx; } @@ -98,7 +98,7 @@ void IntermediateValues::computeStatisticsForTheCurrentYear() } // weeks - for (i = 0; i != maxWeeksInAYear; ++i) + for (i = 0; i != WEEKS_PER_YEAR; ++i) { week[i] = 0.; } @@ -142,9 +142,9 @@ void IntermediateValues::computeStatisticsOrForTheCurrentYear() { day[i] = 0.; // One day - for (j = 0; j != maxHoursInADay; ++j) + for (j = 0; j != HOURS_PER_DAY; ++j) { - assert(indx < maxHoursInAYear); + assert(indx < HOURS_PER_YEAR); if (hour[indx] > 0.) { day[i] = 100.; @@ -154,7 +154,7 @@ void IntermediateValues::computeStatisticsOrForTheCurrentYear() } // weeks - for (i = 0; i != maxWeeksInAYear; ++i) + for (i = 0; i != WEEKS_PER_YEAR; ++i) { week[i] = 0.; } @@ -220,19 +220,19 @@ void IntermediateValues::computeDailyAveragesForCurrentYear() { // Compute sum of hourly values on the current day of year day_sum = 0.; - for (uint h = 0; h != maxHoursInADay; ++h) + for (uint h = 0; h != HOURS_PER_DAY; ++h) { day_sum += hour[indx]; ++indx; } - day[d] = day_sum / maxHoursInADay; + day[d] = day_sum / HOURS_PER_DAY; } } void IntermediateValues::computeWeeklyAveragesForCurrentYear() { // Re-initialization (a previous MC year could have left non-nil values) - for (int w = 0; w != maxWeeksInAYear; ++w) + for (int w = 0; w != WEEKS_PER_YEAR; ++w) { week[w] = 0.; } @@ -303,7 +303,7 @@ void IntermediateValues::computeProbabilitiesForTheCurrentYear() { d = 0.; // One day - for (j = 0; j != maxHoursInADay; ++j) + for (j = 0; j != HOURS_PER_DAY; ++j) { if (hour[indx] > 0.) { @@ -324,7 +324,7 @@ void IntermediateValues::computeProbabilitiesForTheCurrentYear() } // weeks - for (i = 0; i != maxWeeksInAYear; ++i) + for (i = 0; i != WEEKS_PER_YEAR; ++i) { week[i] = 0.; } diff --git a/src/solver/variable/storage/rawdata.cpp b/src/solver/variable/storage/rawdata.cpp index 117d117bb2..4baf8531bd 100644 --- a/src/solver/variable/storage/rawdata.cpp +++ b/src/solver/variable/storage/rawdata.cpp @@ -42,7 +42,7 @@ RawData::~RawData() void RawData::initializeFromStudy(const Data::Study& study) { - Antares::Memory::Allocate(hourly, maxHoursInAYear); + Antares::Memory::Allocate(hourly, HOURS_PER_YEAR); nbYearsCapacity = study.runtime->rangeLimits.year[Data::rangeEnd] + 1; year = new double[nbYearsCapacity]; } @@ -50,10 +50,10 @@ void RawData::initializeFromStudy(const Data::Study& study) void RawData::reset() { // Reset - Antares::Memory::Zero(maxHoursInAYear, hourly); - (void)::memset(monthly, 0, sizeof(double) * maxMonths); - (void)::memset(weekly, 0, sizeof(double) * maxWeeksInAYear); - (void)::memset(daily, 0, sizeof(double) * maxDaysInAYear); + Antares::Memory::Zero(HOURS_PER_YEAR, hourly); + (void)::memset(monthly, 0, sizeof(double) * MONTHS_PER_YEAR); + (void)::memset(weekly, 0, sizeof(double) * WEEKS_PER_YEAR); + (void)::memset(daily, 0, sizeof(double) * DAYS_PER_YEAR); (void)::memset(year, 0, sizeof(double) * nbYearsCapacity); } @@ -61,22 +61,22 @@ void RawData::merge(unsigned int y, const IntermediateValues& rhs) { unsigned int i; // StdDeviation value for each hour throughout all years - for (i = 0; i != maxHoursInAYear; ++i) + for (i = 0; i != HOURS_PER_YEAR; ++i) { hourly[i] += rhs.hour[i]; } // StdDeviation value for each day throughout all years - for (i = 0; i != maxDaysInAYear; ++i) + for (i = 0; i != DAYS_PER_YEAR; ++i) { daily[i] += rhs.day[i]; } // StdDeviation value for each week throughout all years - for (i = 0; i != maxWeeksInAYear; ++i) + for (i = 0; i != WEEKS_PER_YEAR; ++i) { weekly[i] += rhs.week[i]; } // StdDeviation value for each month throughout all years - for (i = 0; i != maxMonths; ++i) + for (i = 0; i != MONTHS_PER_YEAR; ++i) { monthly[i] += rhs.month[i]; } diff --git a/src/solver/variable/surveyresults/surveyresults.cpp b/src/solver/variable/surveyresults/surveyresults.cpp index 0402fb6c15..bb763a1b80 100644 --- a/src/solver/variable/surveyresults/surveyresults.cpp +++ b/src/solver/variable/surveyresults/surveyresults.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -533,8 +534,8 @@ SurveyResults::SurveyResults(const Data::Study& s, const String& o, IResultWrite values = new ValueType[maxVariables]; for (uint i = 0; i != maxVariables; ++i) { - values[i] = new double[maxHoursInAYear]; - memset(values[i], 0, sizeof(double) * maxHoursInAYear); + values[i] = new double[HOURS_PER_YEAR]; + memset(values[i], 0, sizeof(double) * HOURS_PER_YEAR); } // captions @@ -638,7 +639,7 @@ void SurveyResults::exportDigestAllYears(std::string& buffer) for (auto j = data.rowCaptions.begin(); j != end; ++j, ++y) { // asserts - assert(y < maxHoursInAYear); + assert(y < HOURS_PER_YEAR); buffer.append("\t").append(j->c_str()); @@ -646,7 +647,7 @@ void SurveyResults::exportDigestAllYears(std::string& buffer) for (uint i = 0; i != data.columnIndex; ++i) { assert(i < maxVariables && "i greater can not be greater than maxVariables"); - assert(y < maxHoursInAYear && "y can not be greater than maxHoursInAYear"); + assert(y < HOURS_PER_YEAR && "y can not be greater than HOURS_PER_YEAR"); if (digestNonApplicableStatus[y][i]) { @@ -791,7 +792,7 @@ void SurveyResults::saveToFile(int dataLevel, int fileLevel, int precisionLevel) for (uint y = heightBegin; y < heightEnd; ++y) { // Asserts - assert(y < maxHoursInAYear); + assert(y < HOURS_PER_YEAR); // Index writeDateToFileDescriptor(y + 1, precisionLevel); From 7145e40a4b6b5b93d1045c1a2524eadfa5832fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 1 Jul 2024 17:26:30 +0200 Subject: [PATCH 054/127] Fix a few newly-introduced code smells (#2218) Add `const` qualifiers, fix lambda captures. --- .../antares/solver/hydro/management/management.h | 4 ++-- src/solver/hydro/management/PrepareInflows.cpp | 5 ++--- src/solver/hydro/management/management.cpp | 2 +- src/solver/hydro/management/monthly.cpp | 2 +- src/solver/ts-generator/availability.cpp | 10 +++++----- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/solver/hydro/include/antares/solver/hydro/management/management.h b/src/solver/hydro/include/antares/solver/hydro/management/management.h index a8576248b4..8f4cf12d01 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -85,9 +85,9 @@ class HydroManagement final const Antares::Data::Area::ScratchMap& scratchmap, HydroSpecificMap& hydro_specific_map); //! Prepare the effective demand for each area - void prepareEffectiveDemand(uint year, HydroSpecificMap& hydro_specific_map); + void prepareEffectiveDemand(uint year, HydroSpecificMap& hydro_specific_map) const; //! Monthly Optimal generations - void prepareMonthlyOptimalGenerations(double* random_reservoir_level, + void prepareMonthlyOptimalGenerations(const double* random_reservoir_level, uint y, HydroSpecificMap& hydro_specific_map); diff --git a/src/solver/hydro/management/PrepareInflows.cpp b/src/solver/hydro/management/PrepareInflows.cpp index c13d11a64b..01eb38efaf 100644 --- a/src/solver/hydro/management/PrepareInflows.cpp +++ b/src/solver/hydro/management/PrepareInflows.cpp @@ -19,8 +19,7 @@ void PrepareInflows::Run(uint year) void PrepareInflows::LoadInflows(uint year) { areas_.each( - // un-const because now data is a member of area [&](const Data::Area& area) - [&](Data::Area& area) + [this, year](Data::Area& area) { const auto& srcinflows = area.hydro.series->storage.getColumn(year); @@ -69,7 +68,7 @@ void PrepareInflows::LoadInflows(uint year) void PrepareInflows::ChangeInflowsToAccommodateFinalLevels(uint year) { areas_.each( - [this, &year](Data::Area& area) + [&year](Data::Area& area) { auto& data = area.hydro.managementData[year]; diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index e4aeecde1e..0ad4d4a357 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -196,7 +196,7 @@ void HydroManagement::prepareNetDemand(uint year, }); } -void HydroManagement::prepareEffectiveDemand(uint year, HydroSpecificMap& hydro_specific_map) +void HydroManagement::prepareEffectiveDemand(uint year, HydroSpecificMap& hydro_specific_map) const { areas_.each( [this, &year, &hydro_specific_map](Data::Area& area) diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index 04f2c7b107..8afcd0e26f 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -151,7 +151,7 @@ double HydroManagement::prepareMonthlyTargetGenerations( return total; } -void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_level, +void HydroManagement::prepareMonthlyOptimalGenerations(const double* random_reservoir_level, uint y, HydroSpecificMap& hydro_specific_map) { diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 0702c9e7b9..efb5991093 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -612,10 +612,10 @@ std::vector getAllClustersToGen(const Data::AreaList& are return clusters; } -void writeResultsToDisk(const Data::Study& study, - Solver::IResultWriter& writer, - const Matrix<>& series, - const std::string& savePath) +static void writeResultsToDisk(const Data::Study& study, + Solver::IResultWriter& writer, + const Matrix<>& series, + const std::string& savePath) { if (study.parameters.noOutput) { @@ -627,7 +627,7 @@ void writeResultsToDisk(const Data::Study& study, writer.addEntryFromBuffer(savePath, buffer); } -void writeResultsToDisk(const Matrix<>& series, const std::filesystem::path savePath) +static void writeResultsToDisk(const Matrix<>& series, const std::filesystem::path& savePath) { std::string buffer; series.saveToBuffer(buffer, 0); From 5bdf7882439572c636bbe3db40ae22996576984a Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:20:15 +0200 Subject: [PATCH 055/127] Collect hydro validation errors (#2204) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit collect *n* hydro validation errors (10 per area ) before exiting --------- Co-authored-by: Florian Omnès --- src/libs/antares/study/CMakeLists.txt | 2 - src/solver/hydro/CMakeLists.txt | 6 +- .../hydro/management/HydroErrorsCollector.h | 63 +++++++++ .../hydro/management/HydroInputsChecker.h | 19 +-- .../hydro/management}/finalLevelValidator.h | 25 +++- .../hydro-final-reservoir-level-functions.h | 41 ------ .../hydro/management/HydroErrorsCollector.cpp | 45 +++++++ .../hydro/management/HydroInputsChecker.cpp | 122 ++++++++++++------ .../hydro/management}/finalLevelValidator.cpp | 58 +++++---- .../hydro-final-reservoir-level-functions.cpp | 73 ----------- .../antares/solver/simulation/solver.hxx | 3 + ...-hydro-final-reservoir-level-functions.cpp | 38 +++--- 12 files changed, 276 insertions(+), 219 deletions(-) create mode 100644 src/solver/hydro/include/antares/solver/hydro/management/HydroErrorsCollector.h rename src/{libs/antares/study/include/antares/study/parts/hydro => solver/hydro/include/antares/solver/hydro/management}/finalLevelValidator.h (81%) delete mode 100644 src/solver/hydro/include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h create mode 100644 src/solver/hydro/management/HydroErrorsCollector.cpp rename src/{libs/antares/study/parts/hydro => solver/hydro/management}/finalLevelValidator.cpp (72%) delete mode 100644 src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index 65ad5398a6..3ec77caaed 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -122,8 +122,6 @@ set(SRC_STUDY_PART_HYDRO include/antares/study/parts/hydro/allocation.h include/antares/study/parts/hydro/allocation.hxx parts/hydro/allocation.cpp - include/antares/study/parts/hydro/finalLevelValidator.h - parts/hydro/finalLevelValidator.cpp include/antares/study/parts/hydro/hydromaxtimeseriesreader.h parts/hydro/hydromaxtimeseriesreader.cpp ) diff --git a/src/solver/hydro/CMakeLists.txt b/src/solver/hydro/CMakeLists.txt index 657c52e17a..3ba25e80d4 100644 --- a/src/solver/hydro/CMakeLists.txt +++ b/src/solver/hydro/CMakeLists.txt @@ -58,8 +58,10 @@ set(SRC_MANAGEMENT management/MinGenerationScaling.cpp include/antares/solver/hydro/management/HydroInputsChecker.h management/HydroInputsChecker.cpp - include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h - management/hydro-final-reservoir-level-functions.cpp + include/antares/solver/hydro/management/HydroErrorsCollector.h + management/HydroErrorsCollector.cpp + include/antares/solver/hydro/management/finalLevelValidator.h + management/finalLevelValidator.cpp ) diff --git a/src/solver/hydro/include/antares/solver/hydro/management/HydroErrorsCollector.h b/src/solver/hydro/include/antares/solver/hydro/management/HydroErrorsCollector.h new file mode 100644 index 0000000000..d6054f12b6 --- /dev/null +++ b/src/solver/hydro/include/antares/solver/hydro/management/HydroErrorsCollector.h @@ -0,0 +1,63 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ + +#pragma once +#include +#include +#include +#include + +namespace Antares +{ + +class HydroErrorsCollector +{ +public: + class AreaReference + { + public: + AreaReference(HydroErrorsCollector* collector, const std::string& name); + template + AreaReference& operator<<(const T& msg); + + private: + std::string& areaSingleErrorMessage_; + }; + + AreaReference operator()(const std::string& name); + HydroErrorsCollector() = default; + void CheckForErrors() const; + +private: + std::map> areasErrorMap_; + std::string& CurrentMessage(const std::string& name); +}; + +template +HydroErrorsCollector::AreaReference& HydroErrorsCollector::AreaReference::operator<<(const T& msg) +{ + std::ostringstream strfy; + strfy << msg; + areaSingleErrorMessage_ += strfy.str(); + return *this; +} + +} // namespace Antares diff --git a/src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h b/src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h index 0308779170..af9049a97e 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/HydroInputsChecker.h @@ -21,6 +21,7 @@ #pragma once #include #include "antares/date/date.h" +#include "antares/solver/hydro/management/HydroErrorsCollector.h" #include "antares/solver/hydro/management/MinGenerationScaling.h" #include "antares/solver/hydro/management/PrepareInflows.h" #include "antares/study/study.h" @@ -33,31 +34,31 @@ class HydroInputsChecker public: explicit HydroInputsChecker(Antares::Data::Study& study); void Execute(uint year); + void CheckForErrors() const; + void CheckFinalReservoirLevelsConfiguration(uint year); private: Data::AreaList& areas_; const Data::Parameters& parameters_; const Date::Calendar& calendar_; - Data::SimulationMode simulationMode_; - const uint firstYear_; - const uint endYear_; PrepareInflows prepareInflows_; MinGenerationScaling minGenerationScaling_; const Data::TimeSeries::TS& scenarioInitialHydroLevels_; const Data::TimeSeries::TS& scenarioFinalHydroLevels_; + HydroErrorsCollector errorCollector_; //! return false if checkGenerationPowerConsistency or checkMinGeneration returns false - bool checkMonthlyMinGeneration(uint year, const Data::Area& area) const; + bool checkMonthlyMinGeneration(uint year, const Data::Area& area); //! check Yearly minimum generation is lower than available inflows - bool checkYearlyMinGeneration(uint year, const Data::Area& area) const; + bool checkYearlyMinGeneration(uint year, const Data::Area& area); //! check Weekly minimum generation is lower than available inflows - bool checkWeeklyMinGeneration(uint year, const Data::Area& area) const; + bool checkWeeklyMinGeneration(uint year, const Data::Area& area); //! check Hourly minimum generation is lower than available inflows - bool checkGenerationPowerConsistency(uint year) const; + bool checkGenerationPowerConsistency(uint year); //! return false if checkGenerationPowerConsistency or checkMinGeneration returns false - bool checksOnGenerationPowerBounds(uint year) const; + bool checksOnGenerationPowerBounds(uint year); //! check minimum generation is lower than available inflows - bool checkMinGeneration(uint year) const; + bool checkMinGeneration(uint year); }; } // namespace Antares diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/finalLevelValidator.h b/src/solver/hydro/include/antares/solver/hydro/management/finalLevelValidator.h similarity index 81% rename from src/libs/antares/study/include/antares/study/parts/hydro/finalLevelValidator.h rename to src/solver/hydro/include/antares/solver/hydro/management/finalLevelValidator.h index 518e29d40b..ecbcd8ed31 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/finalLevelValidator.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/finalLevelValidator.h @@ -26,23 +26,30 @@ */ #pragma once +#include "antares/solver/hydro/management/HydroErrorsCollector.h" #include "antares/study/parts/hydro/container.h" -namespace Antares::Data +namespace Antares +{ +namespace Data { class PartHydro; +} +namespace Solver +{ class FinalLevelValidator { public: - FinalLevelValidator(PartHydro& hydro, + FinalLevelValidator(Antares::Data::PartHydro& hydro, unsigned int areaIndex, - const AreaName areaName, + const Antares::Data::AreaName areaName, double initialLevel, double finalLevel, const unsigned int year, const unsigned int lastSimulationDay, - const unsigned int firstMonthOfSimulation); + const unsigned int firstMonthOfSimulation, + HydroErrorsCollector& errorCollector); bool check(); bool finalLevelFineForUse(); @@ -62,12 +69,16 @@ class FinalLevelValidator unsigned int firstMonthOfSimulation_ = 0; // Data from area - PartHydro& hydro_; + Antares::Data::PartHydro& hydro_; unsigned int areaIndex_; - const AreaName areaName_; + const Antares::Data::AreaName areaName_; double initialLevel_; double finalLevel_; bool finalLevelFineForUse_ = false; + + // area input errors + HydroErrorsCollector& errorCollector_; }; -} // namespace Antares::Data +} // namespace Solver +} // namespace Antares diff --git a/src/solver/hydro/include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h b/src/solver/hydro/include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h deleted file mode 100644 index 9ded556947..0000000000 --- a/src/solver/hydro/include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -** Copyright 2007-2023 RTE -** Authors: RTE-international / Redstork / Antares_Simulator Team -** -** This file is part of Antares_Simulator. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** There are special exceptions to the terms and conditions of the -** license as they are applied to this software. View the full text of -** the exceptions in file COPYING.txt in the directory of this software -** distribution -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with Antares_Simulator. If not, see . -** -** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions -*/ -#ifndef __SOLVER_SIMULATION_HYDRO_FINAL_RESERVOIR_PRE_CHECKS_H__ -#define __SOLVER_SIMULATION_HYDRO_FINAL_RESERVOIR_PRE_CHECKS_H__ - -#include "antares/study/study.h" - -namespace Antares::Solver -{ -void CheckFinalReservoirLevelsConfiguration(Data::AreaList& areas, - const Data::Parameters& parameters, - const Data::TimeSeries::TS& scenarioInitialHydroLevels, - const Data::TimeSeries::TS& scenarioFinalHydroLevels, - uint year); -} // namespace Antares::Solver - -#endif // __SOLVER_SIMULATION_HYDRO_FINAL_RESERVOIR_PRE_CHECKS_H__ diff --git a/src/solver/hydro/management/HydroErrorsCollector.cpp b/src/solver/hydro/management/HydroErrorsCollector.cpp new file mode 100644 index 0000000000..729726e14e --- /dev/null +++ b/src/solver/hydro/management/HydroErrorsCollector.cpp @@ -0,0 +1,45 @@ +#include "antares/solver/hydro/management/HydroErrorsCollector.h" + +#include +#include + +#include + +#include "antares/antares/fatal-error.h" + +namespace Antares +{ + +void HydroErrorsCollector::CheckForErrors() const +{ + if (!areasErrorMap_.empty()) + { + for (const auto& [key, values]: areasErrorMap_) + { + for (const auto& value: values | std::views::take(10)) + { + logs.error() << "In Area " << key << ": " << value << " "; + } + } + + throw FatalError("Hydro validation has failed !"); + } +} + +HydroErrorsCollector::AreaReference::AreaReference(HydroErrorsCollector* collector, + const std::string& name): + areaSingleErrorMessage_(collector->CurrentMessage(name)) +{ +} + +HydroErrorsCollector::AreaReference HydroErrorsCollector::operator()(const std::string& name) +{ + return AreaReference(this, name); +} + +std::string& HydroErrorsCollector::CurrentMessage(const std::string& name) +{ + auto& msgs = areasErrorMap_[name]; + return *msgs.insert(msgs.end(), ""); +} +} // namespace Antares diff --git a/src/solver/hydro/management/HydroInputsChecker.cpp b/src/solver/hydro/management/HydroInputsChecker.cpp index c249cdabe3..d9956e94a2 100644 --- a/src/solver/hydro/management/HydroInputsChecker.cpp +++ b/src/solver/hydro/management/HydroInputsChecker.cpp @@ -23,8 +23,7 @@ #include #include -#include "antares/antares/fatal-error.h" -#include "antares/solver/hydro/management/hydro-final-reservoir-level-functions.h" +#include "antares/solver/hydro/management/finalLevelValidator.h" #include "antares/solver/hydro/monthly/h2o_m_donnees_annuelles.h" #include "antares/solver/hydro/monthly/h2o_m_fonctions.h" #include "antares/solver/simulation/common-eco-adq.h" @@ -36,9 +35,6 @@ HydroInputsChecker::HydroInputsChecker(Antares::Data::Study& study): areas_(study.areas), parameters_(study.parameters), calendar_(study.calendar), - simulationMode_(study.runtime->mode), - firstYear_(0), - endYear_(1 + study.runtime->rangeLimits.year[Data::rangeEnd]), prepareInflows_(study.areas, study.calendar), minGenerationScaling_(study.areas, study.calendar), scenarioInitialHydroLevels_(study.scenarioInitialHydroLevels), @@ -50,27 +46,22 @@ void HydroInputsChecker::Execute(uint year) { prepareInflows_.Run(year); minGenerationScaling_.Run(year); - if (!checksOnGenerationPowerBounds(year)) { - throw FatalError("hydro inputs checks: invalid minimum generation"); + logs.error() << "hydro inputs checks: invalid minimum generation in year " << year; } if (parameters_.useCustomScenario) { - CheckFinalReservoirLevelsConfiguration(areas_, - parameters_, - scenarioInitialHydroLevels_, - scenarioFinalHydroLevels_, - year); + CheckFinalReservoirLevelsConfiguration(year); } } -bool HydroInputsChecker::checksOnGenerationPowerBounds(uint year) const +bool HydroInputsChecker::checksOnGenerationPowerBounds(uint year) { return checkMinGeneration(year) && checkGenerationPowerConsistency(year); } -bool HydroInputsChecker::checkMinGeneration(uint year) const +bool HydroInputsChecker::checkMinGeneration(uint year) { bool ret = true; areas_.each( @@ -103,11 +94,12 @@ bool HydroInputsChecker::checkMinGeneration(uint year) const return ret; } -bool HydroInputsChecker::checkWeeklyMinGeneration(uint year, const Data::Area& area) const +bool HydroInputsChecker::checkWeeklyMinGeneration(uint year, const Data::Area& area) { const auto& srcinflows = area.hydro.series->storage.getColumn(year); const auto& srcmingen = area.hydro.series->mingen.getColumn(year); // Weekly minimum generation <= Weekly inflows for each week + bool ret = true; for (uint week = 0; week < calendar_.maxWeeksInYear - 1; ++week) { double totalWeekMingen = 0.0; @@ -127,57 +119,60 @@ bool HydroInputsChecker::checkWeeklyMinGeneration(uint year, const Data::Area& a } if (totalWeekMingen > totalWeekInflows) { - logs.error() << "In Area " << area.name << " the minimum generation of " - << totalWeekMingen << " MW in week " << week + 1 << " of TS-" - << area.hydro.series->mingen.getSeriesIndex(year) + 1 - << " is incompatible with the inflows of " << totalWeekInflows << " MW."; - return false; + errorCollector_(area.name) + << " the minimum generation of " << totalWeekMingen << " MW in week " << week + 1 + << " of TS-" << area.hydro.series->mingen.getSeriesIndex(year) + 1 + << " is incompatible with the inflows of " << totalWeekInflows << " MW."; + ret = false; } } - return true; + return ret; } -bool HydroInputsChecker::checkYearlyMinGeneration(uint year, const Data::Area& area) const +bool HydroInputsChecker::checkYearlyMinGeneration(uint year, const Data::Area& area) { const auto& data = area.hydro.managementData.at(year); + bool ret = true; if (data.totalYearMingen > data.totalYearInflows) { // Yearly minimum generation <= Yearly inflows - logs.error() << "In Area " << area.name << " the minimum generation of " - << data.totalYearMingen << " MW of TS-" - << area.hydro.series->mingen.getSeriesIndex(year) + 1 - << " is incompatible with the inflows of " << data.totalYearInflows << " MW."; - return false; + errorCollector_(area.name) + << " the minimum generation of " << data.totalYearMingen << " MW of TS-" + << area.hydro.series->mingen.getSeriesIndex(year) + 1 + << " is incompatible with the inflows of " << data.totalYearInflows << " MW."; + ret = false; } - return true; + return ret; } -bool HydroInputsChecker::checkMonthlyMinGeneration(uint year, const Data::Area& area) const +bool HydroInputsChecker::checkMonthlyMinGeneration(uint year, const Data::Area& area) { const auto& data = area.hydro.managementData.at(year); + bool ret = true; for (uint month = 0; month != 12; ++month) { uint realmonth = calendar_.months[month].realmonth; // Monthly minimum generation <= Monthly inflows for each month if (data.totalMonthMingen[realmonth] > data.totalMonthInflows[realmonth]) { - logs.error() << "In Area " << area.name << " the minimum generation of " - << data.totalMonthMingen[realmonth] << " MW in month " << month + 1 - << " of TS-" << area.hydro.series->mingen.getSeriesIndex(year) + 1 - << " is incompatible with the inflows of " - << data.totalMonthInflows[realmonth] << " MW."; - return false; + errorCollector_(area.name) + << " the minimum generation of " << data.totalMonthMingen[realmonth] + << " MW in month " << month + 1 << " of TS-" + << area.hydro.series->mingen.getSeriesIndex(year) + 1 + << " is incompatible with the inflows of " << data.totalMonthInflows[realmonth] + << " MW."; + ret = false; } } - return true; + return ret; } -bool HydroInputsChecker::checkGenerationPowerConsistency(uint year) const +bool HydroInputsChecker::checkGenerationPowerConsistency(uint year) { bool ret = true; areas_.each( - [&ret, &year](const Data::Area& area) + [this, &ret, &year](const Data::Area& area) { const auto& srcmingen = area.hydro.series->mingen.getColumn(year); const auto& srcmaxgen = area.hydro.series->maxHourlyGenPower.getColumn(year); @@ -192,11 +187,11 @@ bool HydroInputsChecker::checkGenerationPowerConsistency(uint year) const if (max < min) { - logs.error() << "In area: " << area.name << " [hourly] minimum generation of " - << min << " MW in timestep " << h + 1 << " of TS-" << tsIndexMin + 1 - << " is incompatible with the maximum generation of " << max - << " MW in timestep " << h + 1 << " of TS-" << tsIndexMax + 1 - << " MW."; + errorCollector_(area.name) + << "In area: " << area.name << " [hourly] minimum generation of " << min + << " MW in timestep " << h + 1 << " of TS-" << tsIndexMin + 1 + << " is incompatible with the maximum generation of " << max + << " MW in timestep " << h + 1 << " of TS-" << tsIndexMax + 1 << " MW."; ret = false; return; } @@ -205,4 +200,45 @@ bool HydroInputsChecker::checkGenerationPowerConsistency(uint year) const return ret; } + +void HydroInputsChecker::CheckFinalReservoirLevelsConfiguration(uint year) +{ + if (!parameters_.yearsFilter.at(year)) + { + return; + } + + areas_.each( + [this, year](Data::Area& area) + { + double initialLevel = scenarioInitialHydroLevels_.entry[area.index][year]; + double finalLevel = scenarioFinalHydroLevels_.entry[area.index][year]; + + Antares::Solver::FinalLevelValidator validator(area.hydro, + area.index, + area.name, + initialLevel, + finalLevel, + year, + parameters_.simulationDays.end, + parameters_.firstMonthInYear, + errorCollector_); + if (!validator.check()) + { + errorCollector_(area.name) + << "hydro final level : infeasibility for area " << area.name + << " please check the corresponding final level data (scenario-builder)"; + } + if (validator.finalLevelFineForUse()) + { + area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; + } + }); +} // End function CheckFinalReservoirLevelsConfiguration + +void HydroInputsChecker::CheckForErrors() const +{ + errorCollector_.CheckForErrors(); +} + } // namespace Antares diff --git a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp b/src/solver/hydro/management/finalLevelValidator.cpp similarity index 72% rename from src/libs/antares/study/parts/hydro/finalLevelValidator.cpp rename to src/solver/hydro/management/finalLevelValidator.cpp index c0834441a1..8986f4b233 100644 --- a/src/libs/antares/study/parts/hydro/finalLevelValidator.cpp +++ b/src/solver/hydro/management/finalLevelValidator.cpp @@ -25,27 +25,30 @@ ** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions */ -#include "antares/study/parts/hydro/finalLevelValidator.h" +#include "antares/solver/hydro/management/finalLevelValidator.h" -namespace Antares::Data +namespace Antares::Solver { -FinalLevelValidator::FinalLevelValidator(PartHydro& hydro, - unsigned int areaIndex, - const AreaName areaName, // gp : to std::string - double initialLevel, - double finalLevel, - const unsigned int year, - const unsigned int lastSimulationDay, - const unsigned int firstMonthOfSimulation): - year_(year), - lastSimulationDay_(lastSimulationDay), - firstMonthOfSimulation_(firstMonthOfSimulation), +FinalLevelValidator::FinalLevelValidator( + Antares::Data::PartHydro& hydro, + unsigned int areaIndex, + const Antares::Data::AreaName areaName, // gp : to std::string + double initialLevel, + double finalLevel, + const unsigned int year, + const unsigned int lastSimulationDay, + const unsigned int firstMonthOfSimulation, + HydroErrorsCollector& errorCollector): hydro_(hydro), - areaIndex_(areaIndex), areaName_(areaName), + areaIndex_(areaIndex), initialLevel_(initialLevel), - finalLevel_(finalLevel) + finalLevel_(finalLevel), + year_(year), + lastSimulationDay_(lastSimulationDay), + firstMonthOfSimulation_(firstMonthOfSimulation), + errorCollector_(errorCollector) { } @@ -112,9 +115,10 @@ bool FinalLevelValidator::hydroAllocationStartMatchesSimulation() const return true; } - logs.error() << "Year " << year_ + 1 << ", area '" << areaName_ - << "' : " << "Hydro allocation must start on the 1st simulation month and " - << "simulation last a whole year"; + errorCollector_(areaName_) << "Year " << year_ + 1 << ": " + << "Hydro allocation must start on the 1st simulation month and " + << "simulation last a whole year"; + return false; } @@ -125,10 +129,10 @@ bool FinalLevelValidator::isFinalLevelReachable() const if ((finalLevel_ - initialLevel_) * reservoirCapacity > totalYearInflows) { - logs.error() << "Year: " << year_ + 1 << ". Area: " << areaName_ - << ". Incompatible total inflows: " << totalYearInflows - << " with initial: " << initialLevel_ << " and final: " << finalLevel_ - << " reservoir levels."; + errorCollector_(areaName_) + << "Year: " << year_ + 1 << " Incompatible total inflows: " << totalYearInflows + << " with initial: " << initialLevel_ << " and final: " << finalLevel_ + << " reservoir levels."; return false; } return true; @@ -154,10 +158,10 @@ bool FinalLevelValidator::isBetweenRuleCurves() const if (finalLevel_ < lowLevelLastDay || finalLevel_ > highLevelLastDay) { - logs.error() << "Year: " << year_ + 1 << ". Area: " << areaName_ - << ". Specifed final reservoir level: " << finalLevel_ - << " is incompatible with reservoir level rule curve [" << lowLevelLastDay - << " , " << highLevelLastDay << "]"; + errorCollector_(areaName_) + << "Year: " << year_ + 1 << " Specifed final reservoir level: " << finalLevel_ + << " is incompatible with reservoir level rule curve [" << lowLevelLastDay << " , " + << highLevelLastDay << "]"; return false; } return true; @@ -168,4 +172,4 @@ bool FinalLevelValidator::finalLevelFineForUse() return finalLevelFineForUse_; } -} // namespace Antares::Data +} // namespace Antares::Solver diff --git a/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp b/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp deleted file mode 100644 index 6e9a53ce95..0000000000 --- a/src/solver/hydro/management/hydro-final-reservoir-level-functions.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* -** Copyright 2007-2023 RTE -** Authors: RTE-international / Redstork / Antares_Simulator Team -** -** This file is part of Antares_Simulator. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** There are special exceptions to the terms and conditions of the -** license as they are applied to this software. View the full text of -** the exceptions in file COPYING.txt in the directory of this software -** distribution -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with Antares_Simulator. If not, see . -** -** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions -*/ - -#include "antares/solver/hydro/management/hydro-final-reservoir-level-functions.h" - -#include -#include "antares/study/parts/hydro/finalLevelValidator.h" - -namespace Antares::Solver -{ - -void CheckFinalReservoirLevelsConfiguration(Data::AreaList& areas, - const Data::Parameters& parameters, - const Data::TimeSeries::TS& scenarioInitialHydroLevels, - const Data::TimeSeries::TS& scenarioFinalHydroLevels, - uint year) -{ - if (!parameters.yearsFilter.at(year)) - { - return; - } - - areas.each( - [&areas, ¶meters, &scenarioInitialHydroLevels, &scenarioFinalHydroLevels, year]( - Data::Area& area) - { - double initialLevel = scenarioInitialHydroLevels.entry[area.index][year]; - double finalLevel = scenarioFinalHydroLevels.entry[area.index][year]; - - Data::FinalLevelValidator validator(area.hydro, - area.index, - area.name, - initialLevel, - finalLevel, - year, - parameters.simulationDays.end, - parameters.firstMonthInYear); - if (!validator.check()) - { - throw FatalError("hydro final level : infeasibility"); - } - if (validator.finalLevelFineForUse()) - { - area.hydro.deltaBetweenFinalAndInitialLevels[year] = finalLevel - initialLevel; - } - }); -} // End function CheckFinalReservoirLevelsConfiguration - -} // namespace Antares::Solver diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 21e0aeb7a1..be838f59bd 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -972,6 +972,7 @@ void ISimulation::loopThroughYears(uint firstYear, hydroInputsChecker.Execute(year); } } + hydroInputsChecker.CheckForErrors(); logs.info() << " Starting the simulation"; @@ -996,6 +997,8 @@ void ISimulation::loopThroughYears(uint firstYear, { // for each year not handled earlier hydroInputsChecker.Execute(y); + hydroInputsChecker.CheckForErrors(); + bool performCalculations = batch.isYearPerformed[y]; unsigned int numSpace = 999999; if (performCalculations) diff --git a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp index e426d99da4..9eeeaf9618 100644 --- a/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp +++ b/src/tests/src/solver/simulation/test-hydro-final-reservoir-level-functions.cpp @@ -7,9 +7,10 @@ #include #include +#include "antares/solver/hydro/management/HydroErrorsCollector.h" +#include "antares/solver/hydro/management/finalLevelValidator.h" -#include "include/antares/solver/hydro/management/hydro-final-reservoir-level-functions.h" -#include "include/antares/study/parts/hydro/finalLevelValidator.h" +#include "include/antares/solver/hydro/management/HydroInputsChecker.h" using namespace Antares::Solver; using namespace Antares::Data; @@ -105,6 +106,7 @@ struct Fixture Study::Ptr study = std::make_shared(); Area* area_1; Area* area_2; + HydroErrorsCollector hydro_errors_collector; }; BOOST_FIXTURE_TEST_SUITE(final_level_validator, Fixture) @@ -119,7 +121,8 @@ BOOST_AUTO_TEST_CASE(all_parameters_good___check_succeeds_and_final_level_is_usa study->scenarioFinalHydroLevels[area_1->index][year], year, study->parameters.simulationDays.end, - study->parameters.firstMonthInYear); + study->parameters.firstMonthInYear, + hydro_errors_collector); BOOST_CHECK_EQUAL(validator.check(), true); BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), true); @@ -136,7 +139,8 @@ BOOST_AUTO_TEST_CASE(no_reservoir_management___check_succeeds_but_final_level_no study->scenarioFinalHydroLevels[area_1->index][year], year, study->parameters.simulationDays.end, - study->parameters.firstMonthInYear); + study->parameters.firstMonthInYear, + hydro_errors_collector); BOOST_CHECK_EQUAL(validator.check(), true); BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); @@ -154,7 +158,8 @@ BOOST_AUTO_TEST_CASE(use_water_value_is_true___check_succeeds_but_final_level_no study->scenarioFinalHydroLevels[area_1->index][year], year, study->parameters.simulationDays.end, - study->parameters.firstMonthInYear); + study->parameters.firstMonthInYear, + hydro_errors_collector); BOOST_CHECK_EQUAL(validator.check(), true); BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); @@ -172,7 +177,8 @@ BOOST_AUTO_TEST_CASE(final_level_not_set_by_user____check_succeeds_but_final_lev study->scenarioFinalHydroLevels[area_1->index][year], year, study->parameters.simulationDays.end, - study->parameters.firstMonthInYear); + study->parameters.firstMonthInYear, + hydro_errors_collector); BOOST_CHECK_EQUAL(validator.check(), true); BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); @@ -191,7 +197,8 @@ BOOST_AUTO_TEST_CASE( study->scenarioFinalHydroLevels[area_1->index][year], year, study->parameters.simulationDays.end, - study->parameters.firstMonthInYear); + study->parameters.firstMonthInYear, + hydro_errors_collector); BOOST_CHECK_EQUAL(validator.check(), false); BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); @@ -209,7 +216,8 @@ BOOST_AUTO_TEST_CASE(simulation_does_last_a_whole_year___check_fails_and_final_l study->scenarioFinalHydroLevels[area_1->index][year], year, study->parameters.simulationDays.end, - study->parameters.firstMonthInYear); + study->parameters.firstMonthInYear, + hydro_errors_collector); BOOST_CHECK_EQUAL(validator.check(), false); BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); @@ -228,7 +236,8 @@ BOOST_AUTO_TEST_CASE(final_level_out_of_rule_curves___check_fails_and_final_leve study->scenarioFinalHydroLevels[area_1->index][year], year, study->parameters.simulationDays.end, - study->parameters.firstMonthInYear); + study->parameters.firstMonthInYear, + hydro_errors_collector); BOOST_CHECK_EQUAL(validator.check(), false); BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); @@ -251,7 +260,8 @@ BOOST_AUTO_TEST_CASE( study->scenarioFinalHydroLevels[area_1->index][year], year, study->parameters.simulationDays.end, - study->parameters.firstMonthInYear); + study->parameters.firstMonthInYear, + hydro_errors_collector); BOOST_CHECK_EQUAL(validator.check(), false); BOOST_CHECK_EQUAL(validator.finalLevelFineForUse(), false); @@ -259,13 +269,11 @@ BOOST_AUTO_TEST_CASE( BOOST_AUTO_TEST_CASE(check_all_areas_final_levels_when_config_is_ok___all_checks_succeed) { + HydroInputsChecker hydro_input_checker(*study); + for (uint year: {0, 1}) { - CheckFinalReservoirLevelsConfiguration(study->areas, - study->parameters, - study->scenarioInitialHydroLevels, - study->scenarioFinalHydroLevels, - year); + hydro_input_checker.CheckFinalReservoirLevelsConfiguration(year); } // CheckFinalReservoirLevelsConfiguration(*study, 0); // CheckFinalReservoirLevelsConfiguration(*study, 1); From df49f62e1b378db077ed68ad4bac65360402b625 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Tue, 2 Jul 2024 20:10:51 +0200 Subject: [PATCH 056/127] Remove actions dependencies using node js 16 (#2215) > Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: notiz-dev/github-action-json-property@release. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/. --------- Co-authored-by: Florian OMNES --- .github/workflows/oracle8.yml | 6 ++-- .github/workflows/ubuntu.yml | 44 ++++++++++++++------------- .github/workflows/windows-vcpkg.yml | 47 ++++++++++++++++------------- 3 files changed, 53 insertions(+), 44 deletions(-) diff --git a/.github/workflows/oracle8.yml b/.github/workflows/oracle8.yml index 92b65a9a72..01f040c5ac 100644 --- a/.github/workflows/oracle8.yml +++ b/.github/workflows/oracle8.yml @@ -142,13 +142,15 @@ jobs: cpack -G TGZ - name: Installer TGZ push - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: + name: targz path: _build/*.tar.gz - name: Installer RPM push - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: + name: rpm path: _build/*.rpm - name: Publish assets diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 88fc65ceac..15d8e1ba7a 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -132,13 +132,15 @@ jobs: cd _build ctest -C Release --output-on-failure - # simtest - name: Read simtest version - id: simtest-version - uses: notiz-dev/github-action-json-property@release - with: - path: 'simtest.json' - prop_path: 'version' + run: | + echo 'SIMTEST_JSON<> $GITHUB_ENV + cat ./simtest.json >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV + + - name: Export simtest version + run: | + echo "SIMTEST=${{ fromJson(env.SIMTEST_JSON).version }}" >> $GITHUB_ENV - name: Init submodule run: | @@ -148,7 +150,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-named-mps os: ${{ env.os }} variant: "named-mps" @@ -176,7 +178,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v830 os: ${{ env.os }} @@ -184,7 +186,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-milp variant: "milp-cbc" os: ${{ env.os }} @@ -193,7 +195,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v860 os: ${{ env.os }} @@ -201,7 +203,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v870 os: ${{ env.os }} @@ -209,7 +211,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v910 os: ${{ env.os }} @@ -217,7 +219,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: short-tests os: ${{ env.os }} @@ -225,7 +227,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-mps os: ${{ env.os }} @@ -233,7 +235,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: adequacy-patch-CSR os: ${{ env.os }} @@ -241,7 +243,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-parallel os: ${{ env.os }} variant: "parallel" @@ -250,7 +252,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: ts-generator os: ${{ env.os }} variant: "tsgenerator" @@ -259,7 +261,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: medium-tests os: ${{ env.os }} @@ -267,7 +269,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-1 os: ${{ env.os }} @@ -275,7 +277,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-2 os: ${{ env.os }} @@ -283,7 +285,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-3 os: ${{ env.os }} diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index 59e931e6a8..53062edba7 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -136,19 +136,24 @@ jobs: shell: bash run: | cmake --build _build --config Release -j$(nproc) - # simtest + - name: Read simtest version - id: simtest-version - uses: notiz-dev/github-action-json-property@release - with: - path: 'simtest.json' - prop_path: 'version' + shell: bash + run: | + echo 'SIMTEST_JSON<> $GITHUB_ENV + cat ./simtest.json >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV + + - name: Export simtest version + shell: bash + run: | + echo "SIMTEST=${{ fromJson(env.SIMTEST_JSON).version }}" >> $GITHUB_ENV - name: Run named mps tests if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-named-mps os: ${{ env.test-platform }} variant: "named-mps" @@ -176,7 +181,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: adequacy-patch-CSR os: ${{ env.test-platform }} @@ -184,7 +189,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v830 os: ${{ env.test-platform }} @@ -192,7 +197,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-milp variant: "milp-cbc" os: ${{ env.test-platform }} @@ -201,7 +206,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v860 os: ${{ env.test-platform }} @@ -209,7 +214,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v870 os: ${{ env.test-platform }} @@ -217,7 +222,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v910 os: ${{ env.test-platform }} @@ -225,7 +230,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: short-tests os: ${{ env.test-platform }} @@ -233,7 +238,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-mps os: ${{ env.test-platform }} @@ -241,7 +246,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: valid-parallel os: ${{ env.test-platform }} variant: "parallel" @@ -250,7 +255,7 @@ jobs: if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: ts-generator os: ${{ env.test-platform }} variant: "tsgenerator" @@ -259,7 +264,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: medium-tests os: ${{ env.test-platform }} @@ -267,7 +272,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-1 os: ${{ env.test-platform }} @@ -275,7 +280,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-2 os: ${{ env.test-platform }} @@ -283,7 +288,7 @@ jobs: if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: - simtest-tag: ${{steps.simtest-version.outputs.prop}} + simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-3 os: ${{ env.test-platform }} From 977b48e4a60d67bf7b8f64d4e2ff8425ed859924 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Wed, 3 Jul 2024 09:40:21 +0200 Subject: [PATCH 057/127] Move TS number print (#2228) Purpose : moving the code that prints the TS numbers on disk : due to recent changes it was moved after the loop through MC years. So, we have to wait until simulation ends to know which TS numbers where drawn. So we move that code back. --- .../simulation/include/antares/solver/simulation/solver.hxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index be838f59bd..2c0ae3bb1a 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -312,6 +312,9 @@ void ISimulation::run() } else { + // Export ts-numbers into output + TimeSeriesNumbers::StoreTimeSeriesNumbersIntoOuput(study, pResultWriter); + if (not ImplementationType::simulationBegin()) { return; @@ -349,9 +352,6 @@ void ISimulation::run() ImplementationType::variables.simulationEnd(); - // Export ts-numbers into output - TimeSeriesNumbers::StoreTimeSeriesNumbersIntoOuput(study, pResultWriter); - // Spatial clusters // Notifying all variables to perform the final spatial clusters. // This must be done only when all variables have finished to compute their From a2f92013f8499ee702c1d454e6e83fe83b3ca6b2 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Wed, 3 Jul 2024 10:53:49 +0200 Subject: [PATCH 058/127] Infeability analyzer : renaming (#2225) Purpose : as the title says This PR is attached to ticket [ticket ANT-1825](https://gopro-tickets.rte-france.com/browse/ANT-1825). Some improvements were made or tried by taking care of the ticket. The result is this PR. --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- .../constraint.cpp | 44 +++++++++---------- .../infeasible-problem-analysis/constraint.h | 8 ++-- .../infeasible-problem-analysis/report.h | 8 ++-- .../infeasible-problem-analysis/report.cpp | 32 +++++++------- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 0e95848ad9..c9aacb06aa 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -33,37 +33,37 @@ const std::string kUnknown = ""; namespace Antares::Optimization { Constraint::Constraint(const std::string& input, const double slackValue): - mInput(input), - mSlackValue(slackValue) + name_(input), + slackValue_(slackValue) { } -std::size_t Constraint::extractItems() +std::size_t Constraint::extractComponentsFromName() { - const auto beg = mInput.begin(); - const auto end = mInput.end(); + const auto beg = name_.begin(); + const auto end = name_.end(); std::size_t newPos = 0; const std::size_t sepSize = 2; - const std::size_t inputSize = mInput.size(); + const std::size_t inputSize = name_.size(); for (std::size_t pos = 0; pos < inputSize; pos = newPos + sepSize) { - newPos = mInput.find("::", pos); + newPos = name_.find("::", pos); if (newPos == std::string::npos) { - mItems.emplace_back(beg + pos, end); + nameComponents_.emplace_back(beg + pos, end); break; } if (newPos > pos) { - mItems.emplace_back(beg + pos, beg + newPos); + nameComponents_.emplace_back(beg + pos, beg + newPos); } } - return mItems.size(); + return nameComponents_.size(); } double Constraint::getSlackValue() const { - return mSlackValue; + return slackValue_; } class StringIsNotWellFormated: public std::runtime_error @@ -117,7 +117,7 @@ std::string Constraint::getAreaName() const { return ""; } - return StringBetweenAngleBrackets(mItems.at(1)); + return StringBetweenAngleBrackets(nameComponents_.at(1)); } std::string Constraint::getTimeStepInYear() const @@ -129,7 +129,7 @@ std::string Constraint::getTimeStepInYear() const case ConstraintType::fictitious_load: case ConstraintType::hydro_reservoir_level: case ConstraintType::short_term_storage_level: - return StringBetweenAngleBrackets(mItems.at(mItems.size() - 2)); + return StringBetweenAngleBrackets(nameComponents_.at(nameComponents_.size() - 2)); default: return kUnknown; } @@ -137,28 +137,28 @@ std::string Constraint::getTimeStepInYear() const ConstraintType Constraint::getType() const { - assert(mItems.size() > 1); - if (mItems.at(1) == "hourly") + assert(nameComponents_.size() > 1); + if (nameComponents_.at(1) == "hourly") { return ConstraintType::binding_constraint_hourly; } - if (mItems.at(1) == "daily") + if (nameComponents_.at(1) == "daily") { return ConstraintType::binding_constraint_daily; } - if (mItems.at(1) == "weekly") + if (nameComponents_.at(1) == "weekly") { return ConstraintType::binding_constraint_weekly; } - if (mItems.at(0) == "FictiveLoads") + if (nameComponents_.at(0) == "FictiveLoads") { return ConstraintType::fictitious_load; } - if (mItems.at(0) == "AreaHydroLevel") + if (nameComponents_.at(0) == "AreaHydroLevel") { return ConstraintType::hydro_reservoir_level; } - if (mItems.at(0) == "Level") + if (nameComponents_.at(0) == "Level") { return ConstraintType::short_term_storage_level; } @@ -172,7 +172,7 @@ std::string Constraint::getBindingConstraintName() const case ConstraintType::binding_constraint_hourly: case ConstraintType::binding_constraint_daily: case ConstraintType::binding_constraint_weekly: - return mItems.at(0); + return nameComponents_.at(0); default: return kUnknown; } @@ -182,7 +182,7 @@ std::string Constraint::getSTSName() const { if (getType() == ConstraintType::short_term_storage_level) { - return StringBetweenAngleBrackets(mItems.at(2)); + return StringBetweenAngleBrackets(nameComponents_.at(2)); } else { diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h index aba82e7f21..c5443f951c 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h @@ -47,14 +47,14 @@ class Constraint double getSlackValue() const; // Extract items, check consistency - std::size_t extractItems(); + std::size_t extractComponentsFromName(); std::string prettyPrint() const; ConstraintType getType() const; private: - std::string mInput; - std::vector mItems; - double mSlackValue; + std::string name_; + std::vector nameComponents_; + double slackValue_; // Get specific items std::string getAreaName() const; diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h index 6ebb919fb1..334e09c979 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h @@ -46,11 +46,11 @@ class InfeasibleProblemReport const std::vector& slackVariables); void sortConstraints(); void trimConstraints(); - void extractItems(); + void sortConstraintsByType(); void logSuspiciousConstraints(); - std::vector mConstraints; - std::map mTypes; - const unsigned int nbVariables = 10; + std::vector constraints_; + std::map nbConstraintsByType_; + const unsigned int nbMaxVariables = 10; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index 28e72109bf..bc493ff6bd 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -52,62 +52,62 @@ void InfeasibleProblemReport::turnSlackVarsIntoConstraints( { for (const MPVariable* slack: slackVariables) { - mConstraints.emplace_back(slack->name(), slack->solution_value()); + constraints_.emplace_back(slack->name(), slack->solution_value()); } } void InfeasibleProblemReport::sortConstraints() { - std::sort(std::begin(mConstraints), std::end(mConstraints), ::compareSlackSolutions); + std::sort(std::begin(constraints_), std::end(constraints_), ::compareSlackSolutions); } void InfeasibleProblemReport::trimConstraints() { - if (nbVariables <= mConstraints.size()) + if (nbMaxVariables <= constraints_.size()) { - mConstraints.resize(nbVariables); + constraints_.resize(nbMaxVariables); } } -void InfeasibleProblemReport::extractItems() +void InfeasibleProblemReport::sortConstraintsByType() { - for (auto& c: mConstraints) + for (auto& c: constraints_) { - if (c.extractItems() == 0) + if (c.extractComponentsFromName() == 0) { return; } - mTypes[c.getType()]++; + nbConstraintsByType_[c.getType()]++; } } void InfeasibleProblemReport::logSuspiciousConstraints() { Antares::logs.error() << "The following constraints are suspicious (first = most suspicious)"; - for (const auto& c: mConstraints) + for (const auto& c: constraints_) { Antares::logs.error() << c.prettyPrint(); } Antares::logs.error() << "Possible causes of infeasibility:"; - if (mTypes[ConstraintType::hydro_reservoir_level] > 0) + if (nbConstraintsByType_[ConstraintType::hydro_reservoir_level] > 0) { Antares::logs.error() << "* Hydro reservoir impossible to manage with cumulative options " "\"hard bounds without heuristic\""; } - if (mTypes[ConstraintType::fictitious_load] > 0) + if (nbConstraintsByType_[ConstraintType::fictitious_load] > 0) { Antares::logs.error() << "* Last resort shedding status,"; } - if (mTypes[ConstraintType::short_term_storage_level] > 0) + if (nbConstraintsByType_[ConstraintType::short_term_storage_level] > 0) { Antares::logs.error() << "* Short-term storage reservoir level impossible to manage. Please check inflows, " "lower & upper curves and initial level (if prescribed),"; } - const unsigned int bcCount = mTypes[ConstraintType::binding_constraint_hourly] - + mTypes[ConstraintType::binding_constraint_daily] - + mTypes[ConstraintType::binding_constraint_weekly]; + const unsigned int bcCount = nbConstraintsByType_[ConstraintType::binding_constraint_hourly] + + nbConstraintsByType_[ConstraintType::binding_constraint_daily] + + nbConstraintsByType_[ConstraintType::binding_constraint_weekly]; if (bcCount > 0) { Antares::logs.error() << "* Binding constraints,"; @@ -118,7 +118,7 @@ void InfeasibleProblemReport::logSuspiciousConstraints() void InfeasibleProblemReport::prettyPrint() { - extractItems(); + sortConstraintsByType(); logSuspiciousConstraints(); } From a7172ad92ce6ad8d3e3b9b0127eb12ffbf051ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jason=20Mar=C3=A9chal?= <45510813+JasonMarechal25@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:22:53 +0200 Subject: [PATCH 059/127] Always run clang-format on PR (#2230) --- .github/workflows/clang-format.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 9e00892851..f8fc659cbc 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,12 +1,7 @@ name: Check cpp formatting on: - push: - branches: - - develop - - feature/* - - features/* - - fix/* + pull_request: jobs: build: From fb6d65f6c9b408799f23cbb4244a5b57bb525ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 3 Jul 2024 16:54:43 +0200 Subject: [PATCH 060/127] Add changelog for minor versions (#2229) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - v8.8.6 - v8.6.8 --------- Co-authored-by: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Co-authored-by: Jason Maréchal <45510813+JasonMarechal25@users.noreply.github.com> --- docs/developer-guide/CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/developer-guide/CHANGELOG.md b/docs/developer-guide/CHANGELOG.md index d6606547da..7309cad241 100644 --- a/docs/developer-guide/CHANGELOG.md +++ b/docs/developer-guide/CHANGELOG.md @@ -83,6 +83,11 @@ toc_depth: 2 * Fix invalid index causing segfault in `test-study` test (#1902) ## Branch 8.8.x (end of support 12/2025) +### 8.8.6 (07/2024) +#### Bugfix +- Fix missing synthesis results for links (#2115) +#### Dependencies +- Update vcpkg (fix Boost) ### 8.8.5 (05/2024) #### Bugfix @@ -318,6 +323,12 @@ toc_depth: 2 * Array, logs jit and correlation in makefile (#1410) ## Branch 8.6.x (end of support 06/2025) +### 8.6.8 (07/2024) +#### Bugfix +- [UI] Remove propery storagecycle for short term storage added when saving a study (#2037) +#### Dependencies +- Update vcpkg (fix Boost) + ### 8.6.7 (05/2024) #### Bugfixes * Fix formula use in output var Profit by plant [ANT-1719] (https://github.com/AntaresSimulatorTeam/Antares_Simulator/pull/2097) From ecccb29f0cd959b3d3e98c99794992ce9219a87f Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:55:04 +0200 Subject: [PATCH 061/127] Infeasibility analyzer : small simplifications (#2226) Purpose : as the title says This PR is attached to ticket [ticket ANT-1825](https://gopro-tickets.rte-france.com/browse/ANT-1825). Some improvements were made or tried by taking care of the ticket. The result is this PR. --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- .../constraint.cpp | 22 ++++--------------- .../infeasible-problem-analysis/report.cpp | 6 ++--- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index c9aacb06aa..b43dc7dd95 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -25,6 +25,9 @@ #include #include +#include +#include + namespace { const std::string kUnknown = ""; @@ -40,24 +43,7 @@ Constraint::Constraint(const std::string& input, const double slackValue): std::size_t Constraint::extractComponentsFromName() { - const auto beg = name_.begin(); - const auto end = name_.end(); - std::size_t newPos = 0; - const std::size_t sepSize = 2; - const std::size_t inputSize = name_.size(); - for (std::size_t pos = 0; pos < inputSize; pos = newPos + sepSize) - { - newPos = name_.find("::", pos); - if (newPos == std::string::npos) - { - nameComponents_.emplace_back(beg + pos, end); - break; - } - if (newPos > pos) - { - nameComponents_.emplace_back(beg + pos, beg + newPos); - } - } + boost::algorithm::split_regex(nameComponents_, name_, boost::regex("::")); return nameComponents_.size(); } diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index bc493ff6bd..0964c251ab 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -63,10 +63,8 @@ void InfeasibleProblemReport::sortConstraints() void InfeasibleProblemReport::trimConstraints() { - if (nbMaxVariables <= constraints_.size()) - { - constraints_.resize(nbMaxVariables); - } + unsigned int nbConstraints = constraints_.size(); + constraints_.resize(std::min(nbMaxVariables, nbConstraints)); } void InfeasibleProblemReport::sortConstraintsByType() From f0a80bf94dce2164364cddcb922cae6dea7a6143 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:14:21 +0200 Subject: [PATCH 062/127] Fix compile, add boost header in CMakelists (#2233) --- src/solver/infeasible-problem-analysis/CMakeLists.txt | 1 + src/solver/infeasible-problem-analysis/constraint.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/infeasible-problem-analysis/CMakeLists.txt b/src/solver/infeasible-problem-analysis/CMakeLists.txt index 720842fd6a..424235facc 100644 --- a/src/solver/infeasible-problem-analysis/CMakeLists.txt +++ b/src/solver/infeasible-problem-analysis/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(infeasible_problem_analysis ${SRC_INFEASIBLE_PROBLEM_ANALYSIS}) target_link_libraries(infeasible_problem_analysis PRIVATE ortools::ortools + Boost::headers Antares::logs ) target_include_directories(infeasible_problem_analysis diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index b43dc7dd95..1f04e50cd3 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -26,7 +26,6 @@ #include #include -#include namespace { From e9d7c450b5b3c289f5ae6209fc2ee8e2686a3fa8 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 8 Jul 2024 09:59:16 +0200 Subject: [PATCH 063/127] STS: Withdrawal efficiency [ANT-1862] (#2223) Add a efficiencywithdrawal property to short term storage This mimics the already existing efficiency for injection --- docs/user-guide/04-migration-guides.md | 3 + docs/user-guide/solver/02-inputs.md | 1 + .../parts/short-term-storage/properties.h | 9 ++- .../parts/short-term-storage/properties.cpp | 32 +++++++-- .../constraints/ShortTermStorageLevel.cpp | 4 +- .../opt_gestion_des_couts_cas_lineaire.cpp | 4 +- .../sim_structure_probleme_economique.h | 3 +- .../simulation/sim_calcul_economique.cpp | 3 +- .../end-to-end/simple_study/simple-study.cpp | 67 ++++++++++++++++--- .../short-term-storage-input-output.cpp | 2 + 10 files changed, 103 insertions(+), 25 deletions(-) diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index c423bc5346..729818c28f 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -19,6 +19,9 @@ with XXX in - number of TS to generate => generaldata.ini/General/nbtimeserieslinks (unsigned int, default value 1) +### Input +#### Short term storage: efficiency for withdrawal +In input/st-storage/area/list.ini add property: `efficiencywithdrawal` [double] in range 0-1 ## v9.1.0 ### Input diff --git a/docs/user-guide/solver/02-inputs.md b/docs/user-guide/solver/02-inputs.md index 287be4b797..8f497e8b34 100644 --- a/docs/user-guide/solver/02-inputs.md +++ b/docs/user-guide/solver/02-inputs.md @@ -286,6 +286,7 @@ The user may pick any area appearing in the area list and is then given access t - Injection (MW): the maximum injection power for the storage - withdrawal refers to the flow from the power system to the storage - Stock (MWh): the capacity of the storage in MWh - Efficiency (%): the energy efficiency of the storage, i.e. the ratio for a given volume between the energy taken from the system to be injected into the storage and the energy returned to the system during its withdrawal. This efficiency factor is applied when injecting energy into the storage. + - Efficiency Withdrawal (%): Same behavior as the previous efficiency, this factor is applied when withdrawing energy from the storage. - Initial level (%): the imposed initial filling rate of the storage at the beginning of each optimisation period. - Initial level optimal: if the parameter is activated, the "Initial level" parameter is ignored and the initial storage level is optimized by Antares for each optimization period to minimize its objective function. _Note: setting this parameter to "True" implies that there is no guarantee that the initial storage level of week N is the same as the final storage level of week N-1. However, the final level of week N is always equal to the initial level of the same week N plus/minus the injections/withdrawals occuring at the last hour of week N._ diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/properties.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/properties.h index 11b4808e0d..ac1d37e791 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/properties.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/properties.h @@ -41,12 +41,17 @@ class Properties std::optional withdrawalNominalCapacity; /// Not optional Reservoir capacity in MWh, >= 0 std::optional reservoirCapacity; + /// Initial level, <= 1 double initialLevel = initiallevelDefault; /// Bool to optimise or not initial level bool initialLevelOptim = false; - /// Efficiency factor between 0 and 1 - double efficiencyFactor = 1; + + /// Efficiency factor for injection between 0 and 1 + double injectionEfficiency = 1; + /// Efficiency factor for withdrawal between 0 and 1 + double withdrawalEfficiency = 1; + // Used to sort outputs std::string groupName = "OTHER1"; /// cluster name diff --git a/src/libs/antares/study/parts/short-term-storage/properties.cpp b/src/libs/antares/study/parts/short-term-storage/properties.cpp index 546717588e..b4592105fe 100644 --- a/src/libs/antares/study/parts/short-term-storage/properties.cpp +++ b/src/libs/antares/study/parts/short-term-storage/properties.cpp @@ -61,7 +61,12 @@ bool Properties::loadKey(const IniFile::Property* p) if (p->key == "efficiency") { - return p->value.to(this->efficiencyFactor); + return p->value.to(this->injectionEfficiency); + } + + if (p->key == "efficiencywithdrawal") + { + return p->value.to(this->withdrawalEfficiency); } if (p->key == "name") @@ -105,7 +110,8 @@ void Properties::save(IniFile& ini) const s->add("injectionnominalcapacity", this->injectionNominalCapacity); s->add("withdrawalnominalcapacity", this->withdrawalNominalCapacity); - s->add("efficiency", this->efficiencyFactor); + s->add("efficiency", this->injectionEfficiency); + s->add("efficiencyWithdrawal", this->withdrawalEfficiency); s->add("initialleveloptim", this->initialLevelOptim); s->add("enabled", this->enabled); } @@ -157,16 +163,30 @@ bool Properties::validate() return false; } - if (efficiencyFactor < 0) + if (injectionEfficiency < 0) { logs.warning() << "Property efficiency must be >= 0 " << "for short term storage " << name; - efficiencyFactor = 0; + injectionEfficiency = 0; } - if (efficiencyFactor > 1) + if (injectionEfficiency > 1) { logs.warning() << "Property efficiency must be <= 1 " << "for short term storage " << name; - efficiencyFactor = 1; + injectionEfficiency = 1; + } + + if (withdrawalEfficiency < 0) + { + logs.warning() << "Property efficiencyWithdrawal must be >= 0 " << "for short term storage " + << name; + withdrawalEfficiency = 0; + } + + if (withdrawalEfficiency > 1) + { + logs.warning() << "Property efficiencyWithdrawal must be <= 1 " << "for short term storage " + << name; + withdrawalEfficiency = 1; } if (initialLevel < 0) diff --git a/src/solver/optimisation/constraints/ShortTermStorageLevel.cpp b/src/solver/optimisation/constraints/ShortTermStorageLevel.cpp index 0faa565a8a..00a70e8dd9 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageLevel.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageLevel.cpp @@ -42,8 +42,8 @@ void ShortTermStorageLevel::add(int pdt, int pays) -1.0, -1, builder.data.NombreDePasDeTempsPourUneOptimisation) - .ShortTermStorageInjection(index, -1.0 * storage.efficiency) - .ShortTermStorageWithdrawal(index, 1.0) + .ShortTermStorageInjection(index, -storage.injectionEfficiency) + .ShortTermStorageWithdrawal(index, storage.withdrawalEfficiency) .equalTo() .build(); } diff --git a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp index c2d1859106..857561f616 100644 --- a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp @@ -61,7 +61,7 @@ static void shortTermStorageCost( pdtJour); varInjection >= 0) { - linearCost[varInjection] = cost; + linearCost[varInjection] = storage.withdrawalEfficiency * cost; } if (const int varWithdrawal = variableManager.ShortTermStorageWithdrawal( @@ -69,7 +69,7 @@ static void shortTermStorageCost( pdtJour); varWithdrawal >= 0) { - linearCost[varWithdrawal] = storage.efficiency * cost; + linearCost[varWithdrawal] = storage.injectionEfficiency * cost; } } } diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h index 66400ed678..7805218061 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h @@ -169,7 +169,8 @@ struct PROPERTIES double reservoirCapacity; double injectionNominalCapacity; double withdrawalNominalCapacity; - double efficiency; + double injectionEfficiency; + double withdrawalEfficiency; double initialLevel; bool initialLevelOptim; diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 7fb3336599..f9f47eb65a 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -53,7 +53,8 @@ static void importShortTermStorages( // Properties toInsert.reservoirCapacity = st.properties.reservoirCapacity.value(); - toInsert.efficiency = st.properties.efficiencyFactor; + toInsert.injectionEfficiency = st.properties.injectionEfficiency; + toInsert.withdrawalEfficiency = st.properties.withdrawalEfficiency; toInsert.injectionNominalCapacity = st.properties.injectionNominalCapacity.value(); toInsert.withdrawalNominalCapacity = st.properties.withdrawalNominalCapacity.value(); toInsert.initialLevel = st.properties.initialLevel; diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index 7005057209..2664dc97d0 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -308,7 +308,8 @@ BOOST_FIXTURE_TEST_CASE(STS_initial_level_is_also_weekly_final_level, StudyFixtu props.injectionNominalCapacity = 10; props.withdrawalNominalCapacity = 10; props.reservoirCapacity = 100; - props.efficiencyFactor = .9; + props.injectionEfficiency = .9; + props.withdrawalEfficiency = .8; props.initialLevel = .443; props.groupName = std::string("Some STS group"); // Default values for series @@ -317,17 +318,16 @@ BOOST_FIXTURE_TEST_CASE(STS_initial_level_is_also_weekly_final_level, StudyFixtu storages.push_back(sts); // Fatal gen at h=1 + auto& windTS = area->wind.series.timeSeries; + TimeSeriesConfigurer(windTS).setColumnCount(1).fillColumnWith(0, 0.); + windTS[0][1] = 100; + + // Fatal load at h=2-10 + auto& loadTS = area->load.series.timeSeries; + TimeSeriesConfigurer(loadTS).setColumnCount(1).fillColumnWith(0, 0.); + for (int i = 2; i < 10; i++) { - auto& windTS = area->wind.series.timeSeries; - TimeSeriesConfigurer(windTS).setColumnCount(1).fillColumnWith(0, 0.); - windTS[0][1] = 100; - } - - // Fatal load at h=2 - { - auto& loadTS = area->load.series.timeSeries; - TimeSeriesConfigurer(loadTS).setColumnCount(1).fillColumnWith(0, 0.); - loadTS[0][2] = 100; + loadTS[0][i] = 100; } // Usual values, avoid spillage & unsupplied energy @@ -343,6 +343,51 @@ BOOST_FIXTURE_TEST_CASE(STS_initial_level_is_also_weekly_final_level, StudyFixtu == props.initialLevel * props.reservoirCapacity.value(), tt::tolerance(0.001)); } + +BOOST_FIXTURE_TEST_CASE(STS_efficiency_for_injection_and_withdrawal, StudyFixture) +{ + using namespace Antares::Data::ShortTermStorage; + setNumberMCyears(1); + auto& storages = area->shortTermStorage.storagesByIndex; + STStorageCluster sts; + auto& props = sts.properties; + props.name = "my-sts"; + props.injectionNominalCapacity = 10; + props.withdrawalNominalCapacity = 10; + props.reservoirCapacity = 100; + props.injectionEfficiency = .6; + props.withdrawalEfficiency = .8; + props.initialLevel = .5; + props.groupName = std::string("Some STS group"); + // Default values for series + sts.series->fillDefaultSeriesIfEmpty(); + + storages.push_back(sts); + + // Fatal gen at h=1 + auto& windTS = area->wind.series.timeSeries; + TimeSeriesConfigurer(windTS).setColumnCount(1).fillColumnWith(0, 0.); + windTS[0][1] = 100; + + // Fatal load at h=2 + auto& loadTS = area->load.series.timeSeries; + TimeSeriesConfigurer(loadTS).setColumnCount(1).fillColumnWith(0, 0.); + loadTS[0][2] = 100; + + // Usual values, avoid spillage & unsupplied energy + area->thermal.unsuppliedEnergyCost = 1.e3; + area->thermal.spilledEnergyCost = 1.; + + simulation->create(); + simulation->run(); + + unsigned int groupNb = 0; // Used to reach the first group of STS results + OutputRetriever output(simulation->rawSimu()); + + BOOST_CHECK_EQUAL(output.levelForSTSgroup(area, groupNb).hour(1), 56); // injection + BOOST_CHECK_EQUAL(output.levelForSTSgroup(area, groupNb).hour(2), 48); // withdrawal +} + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(HYDRO_MAX_POWER) diff --git a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp index 83965049e6..99152e42d0 100644 --- a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp +++ b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp @@ -115,6 +115,7 @@ void createIniFile(bool enabled) outfile << "withdrawalnominalcapacity = 900.000000" << std::endl; outfile << "reservoircapacity = 31200.000000" << std::endl; outfile << "efficiency = 0.75" << std::endl; + outfile << "efficiencywithdrawal = 0.9" << std::endl; outfile << "initiallevel = 0.50000" << std::endl; outfile << "enabled = " << (enabled ? "true" : "false") << std::endl; outfile.close(); @@ -134,6 +135,7 @@ void createIniFileWrongValue() outfile << "withdrawalnominalcapacity = -900.000000" << std::endl; outfile << "reservoircapacity = -31200.000000" << std::endl; outfile << "efficiency = 4" << std::endl; + outfile << "efficiencywithdrawal = -2" << std::endl; outfile << "initiallevel = -0.50000" << std::endl; outfile.close(); From 07420475b526ada849ebc1f33ea20071460daa89 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Mon, 8 Jul 2024 10:30:44 +0200 Subject: [PATCH 064/127] Infeasibility analyzer : HydroPower constraint (#2227) [ANT-1825] Add constraint that can possibily lead to infeasibilities. HydroPower is the constraint on the sum of generated hydro energy over the week for a given area. The provided RHS in some cases makes the problem infeasible. --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- src/solver/infeasible-problem-analysis/constraint.cpp | 7 +++++++ .../constraint-slack-analysis.h | 3 ++- .../solver/infeasible-problem-analysis/constraint.h | 1 + src/solver/infeasible-problem-analysis/report.cpp | 4 ++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 1f04e50cd3..8d9491695e 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -26,6 +26,7 @@ #include #include +#include namespace { @@ -143,6 +144,10 @@ ConstraintType Constraint::getType() const { return ConstraintType::hydro_reservoir_level; } + if (nameComponents_.at(0) == "HydroPower") + { + return ConstraintType::hydro_production_weekly; + } if (nameComponents_.at(0) == "Level") { return ConstraintType::short_term_storage_level; @@ -194,6 +199,8 @@ std::string Constraint::prettyPrint() const case ConstraintType::hydro_reservoir_level: return "Hydro reservoir constraint at area '" + getAreaName() + "' at hour " + getTimeStepInYear(); + case ConstraintType::hydro_production_weekly: + return "Hydro weekly production at area '" + getAreaName() + "'"; case ConstraintType::short_term_storage_level: return "Short-term-storage reservoir constraint at area '" + getAreaName() + "' in STS '" + getSTSName() + "' at hour " + getTimeStepInYear(); diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h index a298b6b026..bb56228b2f 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h @@ -57,7 +57,8 @@ class ConstraintSlackAnalysis: public UnfeasibilityAnalysis std::vector slackVariables_; const std::string constraint_name_pattern = "^AreaHydroLevel::|::hourly::|::daily::|::weekly::|" - "^FictiveLoads::|^Level::"; + "^FictiveLoads::|^Level::|" + "^HydroPower::"; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h index c5443f951c..92bab3c87b 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h @@ -32,6 +32,7 @@ enum class ConstraintType binding_constraint_weekly, fictitious_load, hydro_reservoir_level, + hydro_production_weekly, short_term_storage_level, none }; diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index 0964c251ab..2022bfbfd6 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -92,6 +92,10 @@ void InfeasibleProblemReport::logSuspiciousConstraints() Antares::logs.error() << "* Hydro reservoir impossible to manage with cumulative options " "\"hard bounds without heuristic\""; } + if (nbConstraintsByType_[ConstraintType::hydro_production_weekly] > 0) + { + Antares::logs.error() << "* impossible to generate exactly the weekly hydro target"; + } if (nbConstraintsByType_[ConstraintType::fictitious_load] > 0) { Antares::logs.error() << "* Last resort shedding status,"; From 1c90304c74caf8771f19e789305556d8dc59645a Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 8 Jul 2024 11:35:07 +0200 Subject: [PATCH 065/127] Compilation warnings (#2237) close #2236 --- src/solver/hydro/management/finalLevelValidator.cpp | 8 ++++---- src/solver/optimisation/HebdoProblemToLpsTranslator.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/solver/hydro/management/finalLevelValidator.cpp b/src/solver/hydro/management/finalLevelValidator.cpp index 8986f4b233..343a086416 100644 --- a/src/solver/hydro/management/finalLevelValidator.cpp +++ b/src/solver/hydro/management/finalLevelValidator.cpp @@ -40,14 +40,14 @@ FinalLevelValidator::FinalLevelValidator( const unsigned int lastSimulationDay, const unsigned int firstMonthOfSimulation, HydroErrorsCollector& errorCollector): + year_(year), + lastSimulationDay_(lastSimulationDay), + firstMonthOfSimulation_(firstMonthOfSimulation), hydro_(hydro), - areaName_(areaName), areaIndex_(areaIndex), + areaName_(areaName), initialLevel_(initialLevel), finalLevel_(finalLevel), - year_(year), - lastSimulationDay_(lastSimulationDay), - firstMonthOfSimulation_(firstMonthOfSimulation), errorCollector_(errorCollector) { } diff --git a/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp b/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp index d4c6e4b6b0..9c67012c70 100644 --- a/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp +++ b/src/solver/optimisation/HebdoProblemToLpsTranslator.cpp @@ -85,13 +85,13 @@ ConstantDataFromAntares HebdoProblemToLpsTranslator::commonProblemData( throw WeeklyProblemTranslationException("ConstraintesCount must be strictly positive"); } - if (problem->NombreDeContraintes > problem->IndicesDebutDeLigne.size()) + if (problem->NombreDeContraintes > (int)problem->IndicesDebutDeLigne.size()) { throw WeeklyProblemTranslationException( "ConstraintesCount exceed IndicesDebutDeLigne size"); } - if (problem->NombreDeContraintes > problem->NombreDeTermesDesLignes.size()) + if (problem->NombreDeContraintes > (int)problem->NombreDeTermesDesLignes.size()) { throw WeeklyProblemTranslationException( "ConstraintesCount exceed NombreDeTermesDesLignes size"); From d2b4eb9f5d73020c5a7598949fe354caa1f92574 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:06:48 +0200 Subject: [PATCH 066/127] Version 9.2 (#2240) --- src/CMakeLists.txt | 2 +- src/libs/antares/study/version.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0148e31899..9c45b8e32b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.14) # FetchContent_MakeAvailable # Version set(ANTARES_VERSION_HI 9) -set(ANTARES_VERSION_LO 1) +set(ANTARES_VERSION_LO 2) set(ANTARES_VERSION_REVISION 0) diff --git a/src/libs/antares/study/version.cpp b/src/libs/antares/study/version.cpp index 5459ed5d63..8fad2748fd 100644 --- a/src/libs/antares/study/version.cpp +++ b/src/libs/antares/study/version.cpp @@ -43,7 +43,8 @@ constexpr auto supportedVersions = std::to_array({ StudyVersion(8, 7), StudyVersion(8, 8), StudyVersion(9, 0), - StudyVersion(9, 1) + StudyVersion(9, 1), + StudyVersion(9, 2) // Add new versions here }); From 071121d002f972668ea43c6112f5c55aa0d0448d Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Tue, 9 Jul 2024 12:02:56 +0200 Subject: [PATCH 067/127] Fix sonarcloud job (#2246) --- .github/workflows/sonarcloud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 4587c17919..8dbf991635 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,10 +1,10 @@ name: SonarCloud on: + pull_request: push: branches: - develop - pull_request: jobs: sonarcloud: From 252a1076a143ce091b4c5b8d220457dfca20e781 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:33:36 +0200 Subject: [PATCH 068/127] Adequacy Patch regression [ANT-1845] (#2235) --- src/solver/optimisation/post_process_commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/optimisation/post_process_commands.cpp b/src/solver/optimisation/post_process_commands.cpp index 1b170ae353..3ced34ba4a 100644 --- a/src/solver/optimisation/post_process_commands.cpp +++ b/src/solver/optimisation/post_process_commands.cpp @@ -272,7 +272,7 @@ double CurtailmentSharingPostProcessCmd::calculateDensNewAndTotalLmrViolation() // write down densNew values for all the hours problemeHebdo_->ResultatsHoraires[Area].ValeursHorairesDENS[hour] = std::max( 0.0, - densNew - dtgMrg); + densNew); ; // copy spilled Energy values into spilled Energy values after CSR problemeHebdo_->ResultatsHoraires[Area].ValeursHorairesSpilledEnergyAfterCSR[hour] From f4eb47dc8fdecd1c08bd8de567e6aa6debe2eaa1 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:04:10 +0200 Subject: [PATCH 069/127] 9.2 rc 1 (#2247) --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9c45b8e32b..78adeffde1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,7 @@ set(ANTARES_VERSION_REVISION 0) # Beta release set(ANTARES_BETA 0) -set(ANTARES_RC 0) +set(ANTARES_RC 1) set(ANTARES_VERSION_YEAR 2024) From 27e140d4865c3b5c67c249b08df910c7fa577a60 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Tue, 9 Jul 2024 15:05:59 +0200 Subject: [PATCH 070/127] Keep using node js 16 on centos CI (#2248) --- .github/workflows/centos7.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index 573163d105..5ba13ec5c6 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -23,6 +23,7 @@ env: IS_RELEASE: ${{ github.event_name == 'workflow_dispatch' }} IS_PUSH: ${{ github.event_name == 'push' }} REF: ${{ inputs.target_branch =='' && github.ref_name || inputs.target_branch}} + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true jobs: From 3fc885a02a31d2a12ddfac9dd70d0685ea07a920 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Tue, 9 Jul 2024 15:40:17 +0200 Subject: [PATCH 071/127] Infeasibility more cleaning (#2231) We're on the road to make **infeasibility analyzer** more changeable, more precisely when adding a constraint type to the list of constraints to be detected in case of infeasibity. This PR is a step towards this purpose. It contains some heterogeneous simplifications and renaming. In order to ease the review, some comments were added in this PR. --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- .../constraint.cpp | 116 +++++------------- .../infeasible-problem-analysis/constraint.h | 18 ++- .../infeasible-problem-analysis/report.h | 3 +- .../infeasible-problem-analysis/report.cpp | 20 +-- .../test-unfeasible-problem-analyzer.cpp | 6 +- 5 files changed, 54 insertions(+), 109 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 8d9491695e..2c4fd6d085 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -35,16 +36,15 @@ const std::string kUnknown = ""; namespace Antares::Optimization { -Constraint::Constraint(const std::string& input, const double slackValue): - name_(input), +Constraint::Constraint(const std::string& name, const double slackValue): + name_(name), slackValue_(slackValue) { } -std::size_t Constraint::extractComponentsFromName() +void Constraint::extractComponentsFromName() { boost::algorithm::split_regex(nameComponents_, name_, boost::regex("::")); - return nameComponents_.size(); } double Constraint::getSlackValue() const @@ -61,67 +61,36 @@ class StringIsNotWellFormated: public std::runtime_error } }; -std::string StringBetweenAngleBrackets(const std::string& str) +std::string StringBetweenAngleBrackets(const std::string& constraintName) { - const auto& begin = str.begin(); - const auto& end = str.end(); + std::vector split_name; + boost::split(split_name, constraintName, boost::is_any_of("<>")); - auto left = std::find(begin, end, '<'); - - if (left == end) - { - std::ostringstream stream; - stream << std::string("Error the string: ") << std::quoted(str) - << " does not contains the left angle bracket " << std::quoted("<"); - throw StringIsNotWellFormated(stream.str()); - } - - auto right = std::find(begin, end, '>'); - if (right == end) + std::string err_msg = "Error: "; + if (split_name.size() < 3) { - std::ostringstream stream; - stream << std::string("Error the string: ") << std::quoted(str) - << " does not contains the right angle bracket " << std::quoted(">"); - throw StringIsNotWellFormated(stream.str()); + err_msg += "constraint name '" + constraintName + "' misses '<' and/or '>' bracket"; + throw StringIsNotWellFormated(err_msg); } - - if (std::distance(left, right) <= 1) + if (split_name[1].empty()) { - std::ostringstream stream; - stream << std::string("Error the string: ") << std::quoted(str) << " must be of format " - << std::quoted("**"); - throw StringIsNotWellFormated(stream.str()); + err_msg += "constraint name '" + constraintName + "' must be of format '**'"; + throw StringIsNotWellFormated(err_msg); } - return std::string(left + 1, right); + return split_name[1]; } -std::string Constraint::getAreaName() const +std::string Constraint::areaName() const { - if ((getType() == ConstraintType::binding_constraint_hourly) - || (getType() == ConstraintType::binding_constraint_daily) - || (getType() == ConstraintType::binding_constraint_weekly)) - { - return ""; - } return StringBetweenAngleBrackets(nameComponents_.at(1)); } -std::string Constraint::getTimeStepInYear() const +std::string Constraint::timeStep() const { - switch (getType()) - { - case ConstraintType::binding_constraint_hourly: - case ConstraintType::binding_constraint_daily: - case ConstraintType::fictitious_load: - case ConstraintType::hydro_reservoir_level: - case ConstraintType::short_term_storage_level: - return StringBetweenAngleBrackets(nameComponents_.at(nameComponents_.size() - 2)); - default: - return kUnknown; - } + return StringBetweenAngleBrackets(nameComponents_.at(nameComponents_.size() - 2)); } -ConstraintType Constraint::getType() const +ConstraintType Constraint::type() const { assert(nameComponents_.size() > 1); if (nameComponents_.at(1) == "hourly") @@ -155,56 +124,35 @@ ConstraintType Constraint::getType() const return ConstraintType::none; } -std::string Constraint::getBindingConstraintName() const +std::string Constraint::shortName() const { - switch (getType()) - { - case ConstraintType::binding_constraint_hourly: - case ConstraintType::binding_constraint_daily: - case ConstraintType::binding_constraint_weekly: - return nameComponents_.at(0); - default: - return kUnknown; - } + return nameComponents_.at(0); } -std::string Constraint::getSTSName() const +std::string Constraint::STSname() const { - if (getType() == ConstraintType::short_term_storage_level) - { - return StringBetweenAngleBrackets(nameComponents_.at(2)); - } - else - { - return kUnknown; - } + return StringBetweenAngleBrackets(nameComponents_.at(2)); } std::string Constraint::prettyPrint() const { - switch (getType()) + switch (type()) { case ConstraintType::binding_constraint_hourly: - return "Hourly binding constraint '" + getBindingConstraintName() + "' at hour " - + getTimeStepInYear(); + return "Hourly binding constraint '" + shortName() + "' at hour " + timeStep(); case ConstraintType::binding_constraint_daily: - return "Daily binding constraint '" + getBindingConstraintName() + "' at day " - + getTimeStepInYear(); + return "Daily binding constraint '" + shortName() + "' at day " + timeStep(); case ConstraintType::binding_constraint_weekly: - return "Weekly binding constraint '" + getBindingConstraintName(); - + return "Weekly binding constraint '" + shortName(); case ConstraintType::fictitious_load: - return "Last resort shedding status at area '" + getAreaName() + "' at hour " - + getTimeStepInYear(); + return "Last resort shedding status at area '" + areaName() + "' at hour " + timeStep(); case ConstraintType::hydro_reservoir_level: - return "Hydro reservoir constraint at area '" + getAreaName() + "' at hour " - + getTimeStepInYear(); + return "Hydro reservoir constraint at area '" + areaName() + "' at hour " + timeStep(); case ConstraintType::hydro_production_weekly: - return "Hydro weekly production at area '" + getAreaName() + "'"; + return "Hydro weekly production at area '" + areaName() + "'"; case ConstraintType::short_term_storage_level: - return "Short-term-storage reservoir constraint at area '" + getAreaName() + "' in STS '" - + getSTSName() + "' at hour " + getTimeStepInYear(); - + return "Short-term-storage reservoir constraint at area '" + areaName() + "' in STS '" + + STSname() + "' at hour " + timeStep(); default: return kUnknown; } diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h index 92bab3c87b..52fb799692 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h @@ -40,27 +40,23 @@ enum class ConstraintType class Constraint { public: - // Construct object Constraint() = default; - Constraint(const std::string& input, const double slackValue); + Constraint(const std::string& name, const double slackValue); - // Raw members double getSlackValue() const; - // Extract items, check consistency - std::size_t extractComponentsFromName(); + void extractComponentsFromName(); std::string prettyPrint() const; - ConstraintType getType() const; + ConstraintType type() const; private: std::string name_; std::vector nameComponents_; double slackValue_; - // Get specific items - std::string getAreaName() const; - std::string getSTSName() const; - std::string getTimeStepInYear() const; - std::string getBindingConstraintName() const; + std::string areaName() const; + std::string STSname() const; + std::string timeStep() const; + std::string shortName() const; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h index 334e09c979..898f4df359 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h @@ -44,10 +44,11 @@ class InfeasibleProblemReport private: void turnSlackVarsIntoConstraints( const std::vector& slackVariables); - void sortConstraints(); + void sortConstraintsBySlackValue(); void trimConstraints(); void sortConstraintsByType(); void logSuspiciousConstraints(); + void logInfeasibilityCauses(); std::vector constraints_; std::map nbConstraintsByType_; diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index 2022bfbfd6..5154cffa0e 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -43,8 +43,9 @@ InfeasibleProblemReport::InfeasibleProblemReport( const std::vector& slackVariables) { turnSlackVarsIntoConstraints(slackVariables); - sortConstraints(); + sortConstraintsBySlackValue(); trimConstraints(); + sortConstraintsByType(); } void InfeasibleProblemReport::turnSlackVarsIntoConstraints( @@ -56,7 +57,7 @@ void InfeasibleProblemReport::turnSlackVarsIntoConstraints( } } -void InfeasibleProblemReport::sortConstraints() +void InfeasibleProblemReport::sortConstraintsBySlackValue() { std::sort(std::begin(constraints_), std::end(constraints_), ::compareSlackSolutions); } @@ -71,11 +72,8 @@ void InfeasibleProblemReport::sortConstraintsByType() { for (auto& c: constraints_) { - if (c.extractComponentsFromName() == 0) - { - return; - } - nbConstraintsByType_[c.getType()]++; + c.extractComponentsFromName(); + nbConstraintsByType_[c.type()]++; } } @@ -86,6 +84,10 @@ void InfeasibleProblemReport::logSuspiciousConstraints() { Antares::logs.error() << c.prettyPrint(); } +} + +void InfeasibleProblemReport::logInfeasibilityCauses() +{ Antares::logs.error() << "Possible causes of infeasibility:"; if (nbConstraintsByType_[ConstraintType::hydro_reservoir_level] > 0) { @@ -114,14 +116,12 @@ void InfeasibleProblemReport::logSuspiciousConstraints() { Antares::logs.error() << "* Binding constraints,"; } - - Antares::logs.error() << "* Negative hurdle costs on lines with infinite capacity (rare)."; } void InfeasibleProblemReport::prettyPrint() { - sortConstraintsByType(); logSuspiciousConstraints(); + logInfeasibilityCauses(); } } // namespace Antares::Optimization diff --git a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp index 321bd4b3e7..8d960f7381 100644 --- a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp +++ b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp @@ -171,9 +171,9 @@ std::unique_ptr createUnfeasibleProblem(const std::string& constraintN } static const std::string validConstraintNames[] = { - "BC::hourly::hour<36>", - "BC::daily::day<67>", - "BC::weekly::week<12>", + "BC-name-1::hourly::hour<36>", + "BC-name-2::daily::day<67>", + "BC-name-3::weekly::week<12>", "FictiveLoads::hour<25>", "AreaHydroLevel::hour<8>", }; From 7f850a0a6a87e7184b2b13ee5734cf8c016b1131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 9 Jul 2024 16:34:10 +0200 Subject: [PATCH 072/127] Document clang-format (#2243) Add version number to avoid confusion. --- .github/workflows/clang-format.yml | 4 ++-- docs/developer-guide/continuous-integration.md | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index f8fc659cbc..8232f319c7 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,4 +1,4 @@ -name: Check cpp formatting +name: Check cpp formatting using clang 18.1.3 on: pull_request: @@ -23,7 +23,7 @@ jobs: run: | DIFF=`git status --porcelain` if [[ $DIFF ]]; then - echo "The following files are not well formatted" + echo "The following files are not well formatted, please make sure to use clang-format 18.1.3" echo "$DIFF" exit 1 else diff --git a/docs/developer-guide/continuous-integration.md b/docs/developer-guide/continuous-integration.md index 6414c531a6..0f5a47fff3 100644 --- a/docs/developer-guide/continuous-integration.md +++ b/docs/developer-guide/continuous-integration.md @@ -26,8 +26,9 @@ Here is a description of workflows with their associated status. | `download-extract-precompiled-libraries-zip/action.yml` | Download and extract .zip precompiled libraries from antares-deps repository | | | `install-cmake-328/action.yml` | Installs cmake 3.28 using devtoolset 10 | | | `run-tests/action.yml` | Runs tests on the simulator using reference study batches [here](https://github.com/AntaresSimulatorTeam/SimTest) | | - +| `clang-format.yml` | Check formatting using clang-format 18.1.3 through bash script src/format-code.sh[^2] | | [^1]: all branch names must start with `feature/`, `features/`, `fix/`, `release/`, `doc/`, `issue-`, or `dependabot/`; otherwise the workflows are not run +[^2]: please note that this job must succeed in order to merge PRs [ubuntu_ci_svg]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/workflows/Ubuntu%20CI%20(push%20and/or%20release)/badge.svg [ubuntu_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions?query=workflow%3A"Ubuntu%20CI%20(push%20and/or%20release)" From c80109f4cf470029cd261718fb11bcd4722bb094 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:14:45 +0200 Subject: [PATCH 073/127] Link TS generation : splitting into multiple files (#2171) This PR aims at moving some code about link TS generation, from **main** program to new source files. It follows PR #2155 To be done : - [x] move headers (*.h) to the right place - [x] update this branch with its base branch (@flomnes made a change on base branch) We may also take advantage of this PR to : - [ ] Thermal TS generation : - [ ] avoid loading the **whole study** when **no** thermal TS generation is required (this is currently the case) - [ ] move implementation details about thermal TS generation from **main** program to new source files - [ ] Separate loading / extracting data from study and generate the TS --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> Co-authored-by: Florian OMNES --- .../utils/include/antares/utils/utils.h | 6 +- src/libs/antares/utils/utils.cpp | 12 + src/solver/application/application.cpp | 19 +- .../antares/solver/simulation/solver.hxx | 19 +- src/solver/ts-generator/availability.cpp | 164 +++--- .../antares/solver/ts-generator/generator.h | 16 +- src/tools/ts-generator/CMakeLists.txt | 14 +- .../tools/ts-generator/linksTSgenerator.h | 32 ++ .../tools/ts-generator/tsGenerationOptions.h | 31 ++ src/tools/ts-generator/linksTSgenerator.cpp | 347 +++++++++++++ src/tools/ts-generator/main.cpp | 485 ++---------------- .../ts-generator/tsGenerationOptions.cpp | 77 +++ 12 files changed, 634 insertions(+), 588 deletions(-) create mode 100644 src/tools/ts-generator/include/antares/tools/ts-generator/linksTSgenerator.h create mode 100644 src/tools/ts-generator/include/antares/tools/ts-generator/tsGenerationOptions.h create mode 100644 src/tools/ts-generator/linksTSgenerator.cpp create mode 100644 src/tools/ts-generator/tsGenerationOptions.cpp diff --git a/src/libs/antares/utils/include/antares/utils/utils.h b/src/libs/antares/utils/include/antares/utils/utils.h index 1043e7ca4e..a2f50a2e54 100644 --- a/src/libs/antares/utils/include/antares/utils/utils.h +++ b/src/libs/antares/utils/include/antares/utils/utils.h @@ -36,9 +36,10 @@ namespace Antares */ template void TransformNameIntoID(const AnyString& name, StringT& out); - std::string transformNameIntoID(const std::string& name); +std::string FormattedTime(const std::string& format); + /*! ** \brief Beautify a name, for renaming an area for example */ @@ -51,11 +52,8 @@ std::vector> splitStringIntoPairs(const std: namespace Utils { - bool isZero(double d); - double round(double d, unsigned precision); - } // namespace Utils } // namespace Antares diff --git a/src/libs/antares/utils/utils.cpp b/src/libs/antares/utils/utils.cpp index 31992d6020..e188b2b13a 100644 --- a/src/libs/antares/utils/utils.cpp +++ b/src/libs/antares/utils/utils.cpp @@ -96,6 +96,18 @@ void BeautifyName(std::string& out, const std::string& oldname) out = yuniOut.c_str(); } +std::string FormattedTime(const std::string& format) +{ + using namespace std::chrono; + auto time = system_clock::to_time_t(system_clock::now()); + std::tm local_time = *std::localtime(&time); + + char time_buffer[256]; + std::strftime(time_buffer, sizeof(time_buffer), format.c_str(), &local_time); + + return std::string(time_buffer); +} + std::vector> splitStringIntoPairs(const std::string& s, char delimiter1, char delimiter2) diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index a55873ea09..c65e849a15 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -435,20 +435,6 @@ void Application::runSimulationInAdequacyMode() observer); } -static std::string timeToString() -{ - using namespace std::chrono; - auto time = system_clock::to_time_t(system_clock::now()); - std::tm local_time = *std::localtime(&time); - - char time_buffer[256]; - std::strftime(time_buffer, sizeof(time_buffer), "%Y%m%d-%H%M%S", &local_time); - - std::string currentTime = time_buffer; - - return currentTime; -} - void Application::resetLogFilename() const { fs::path logfile = fs::path(pSettings.studyFolder.c_str()) / "logs"; @@ -459,8 +445,9 @@ void Application::resetLogFilename() const + ". Aborting now."); } - logfile /= "solver-"; // append the filename - logfile += timeToString() + ".log"; // complete filename with timestamp and extension + logfile /= "solver-"; // append the filename + logfile += FormattedTime("%Y%m%d-%H%M%S") + + ".log"; // complete filename with timestamp and extension // Assigning the log filename logs.logfile(logfile.string()); diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 2c0ae3bb1a..1aa04cb38f 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -454,15 +454,24 @@ void ISimulation::regenerateTimeSeries(uint year) if (refreshTSonCurrentYear) { auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); -#define SEP Yuni::IO::Separator - const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + "mc-" - + std::to_string(year); -#undef SEP - generateThermalTimeSeries(study, clusters, pResultWriter, savePath); + generateThermalTimeSeries(study, + clusters, + study.runtime->random[Data::seedTsGenThermal]); + + bool archive = study.parameters.timeSeriesToArchive & Data::timeSeriesThermal; + bool doWeWrite = archive && !study.parameters.noOutput; + if (doWeWrite) + { + fs::path savePath = fs::path(study.folderOutput.to()) / "ts-generator" + / "thermal" / "mc-" / std::to_string(year); + writeThermalTimeSeries(clusters, savePath); + } // apply the spinning if we generated some in memory clusters for (auto* cluster: clusters) + { cluster->calculationOfSpinning(); + } } }; } diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index efb5991093..a94fd99e46 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -19,8 +19,6 @@ ** along with Antares_Simulator. If not, see . */ -#include -#include #include #include // For Antares::IO::fileSetContent @@ -28,10 +26,6 @@ #include #include #include -#include -#include "antares/study/simulation.h" - -#define SEP Yuni::IO::Separator constexpr double FAILURE_RATE_EQ_1 = 0.999; @@ -45,14 +39,12 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* c forcedLaw(cluster->forcedLaw), plannedLaw(cluster->plannedLaw), prepro(cluster->prepro), - series(cluster->series.timeSeries), modulationCapacity(cluster->modulation[Data::thermalModulationCapacity]), name(cluster->name()) { } AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(LinkTSgenerationParams& source, - Data::TimeSeries& capacity, Matrix<>& modulation, const std::string& areaDestName): unitCount(source.unitCount), @@ -62,7 +54,6 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(LinkTSgenerationParams& forcedLaw(source.forcedLaw), plannedLaw(source.plannedLaw), prepro(source.prepro.get()), - series(capacity.timeSeries), modulationCapacity(modulation[0]), name(areaDestName) { @@ -70,20 +61,19 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(LinkTSgenerationParams& namespace { -class GeneratorTempData final +class AvailabilityTSgenerator final { public: - explicit GeneratorTempData(Data::Study&, unsigned, MersenneTwister&); - explicit GeneratorTempData(bool, unsigned, MersenneTwister&); + explicit AvailabilityTSgenerator(bool, unsigned, MersenneTwister&); - void generateTS(AvailabilityTSGeneratorData&) const; + Matrix run(AvailabilityTSGeneratorData&) const; private: bool derated; uint nbOfSeriesToGen_; - MersenneTwister& rndgenerator; + MersenneTwister& randomGenerator_; static constexpr int Log_size = 4000; @@ -101,30 +91,21 @@ class GeneratorTempData final const T& duration) const; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, - unsigned nbOfSeriesToGen, - MersenneTwister& rndGenerator): - derated(study.parameters.derated), - nbOfSeriesToGen_(nbOfSeriesToGen), - rndgenerator(rndGenerator) -{ -} - -GeneratorTempData::GeneratorTempData(bool derated, - unsigned int nbOfSeriesToGen, - MersenneTwister& rndGenerator): +AvailabilityTSgenerator::AvailabilityTSgenerator(bool derated, + unsigned int nbOfSeriesToGen, + MersenneTwister& randomGenerator): derated(derated), nbOfSeriesToGen_(nbOfSeriesToGen), - rndgenerator(rndGenerator) + randomGenerator_(randomGenerator) { } template -void GeneratorTempData::prepareIndispoFromLaw(Data::StatisticalLaw law, - double volatility, - std::array& A, - std::array& B, - const T& duration) const +void AvailabilityTSgenerator::prepareIndispoFromLaw(Data::StatisticalLaw law, + double volatility, + std::array& A, + std::array& B, + const T& duration) const { switch (law) { @@ -165,18 +146,18 @@ void GeneratorTempData::prepareIndispoFromLaw(Data::StatisticalLaw law, } } -int GeneratorTempData::durationGenerator(Data::StatisticalLaw law, - int expec, - double volat, - double a, - double b) const +int AvailabilityTSgenerator::durationGenerator(Data::StatisticalLaw law, + int expec, + double volat, + double a, + double b) const { if (volat == 0 || expec == 1) { return expec; } - double rndnumber = rndgenerator.next(); + double rndnumber = randomGenerator_.next(); switch (law) { @@ -197,13 +178,16 @@ int GeneratorTempData::durationGenerator(Data::StatisticalLaw law, return 0; } -void GeneratorTempData::generateTS(AvailabilityTSGeneratorData& tsGenerationData) const +Matrix AvailabilityTSgenerator::run(AvailabilityTSGeneratorData& tsGenerationData) const { assert(tsGenerationData.prepro); + Matrix to_return; + to_return.reset(nbOfSeriesToGen_, 24 * DAYS_PER_YEAR); + if (0 == tsGenerationData.unitCount || 0 == tsGenerationData.nominalCapacity) { - return; + return to_return; } const auto& preproData = *(tsGenerationData.prepro); @@ -317,18 +301,11 @@ void GeneratorTempData::generateTS(AvailabilityTSGeneratorData& tsGenerationData double last = 0; auto& modulation = tsGenerationData.modulationCapacity; - double* dstSeries = nullptr; const uint tsCount = nbOfSeriesToGen_ + 2; for (uint tsIndex = 0; tsIndex != tsCount; ++tsIndex) { uint hour = 0; - - if (tsIndex > 1) - { - dstSeries = tsGenerationData.series[tsIndex - 2]; - } - for (uint dayInTheYear = 0; dayInTheYear < DAYS_PER_YEAR; ++dayInTheYear) { assert(dayInTheYear < 366); @@ -388,7 +365,7 @@ void GeneratorTempData::generateTS(AvailabilityTSGeneratorData& tsGenerationData if (lf[dayInTheYear] > 0. && lf[dayInTheYear] <= FAILURE_RATE_EQ_1) { - A = rndgenerator.next(); + A = randomGenerator_.next(); last = FPOW[dayInTheYear][AUN]; if (A > last) @@ -424,7 +401,7 @@ void GeneratorTempData::generateTS(AvailabilityTSGeneratorData& tsGenerationData } last = PPOW[dayInTheYear][AUN_app]; - A = rndgenerator.next(); + A = randomGenerator_.next(); if (A > last) { @@ -578,7 +555,7 @@ void GeneratorTempData::generateTS(AvailabilityTSGeneratorData& tsGenerationData double AVPDayInTheYear = AVP[dayInTheYear]; for (uint h = 0; h != 24; ++h) { - dstSeries[hour] = std::round(AVPDayInTheYear * modulation[hour]); + to_return[tsIndex - 2][hour] = std::round(AVPDayInTheYear * modulation[hour]); ++hour; } } @@ -587,8 +564,9 @@ void GeneratorTempData::generateTS(AvailabilityTSGeneratorData& tsGenerationData if (derated) { - tsGenerationData.series.averageTimeseries(); + to_return.averageTimeseries(); } + return to_return; } } // namespace @@ -612,22 +590,7 @@ std::vector getAllClustersToGen(const Data::AreaList& are return clusters; } -static void writeResultsToDisk(const Data::Study& study, - Solver::IResultWriter& writer, - const Matrix<>& series, - const std::string& savePath) -{ - if (study.parameters.noOutput) - { - return; - } - - std::string buffer; - series.saveToBuffer(buffer, 0); - writer.addEntryFromBuffer(savePath, buffer); -} - -static void writeResultsToDisk(const Matrix<>& series, const std::filesystem::path& savePath) +void writeTStoDisk(const Matrix<>& series, const std::filesystem::path savePath) { std::string buffer; series.saveToBuffer(buffer, 0); @@ -642,45 +605,48 @@ static void writeResultsToDisk(const Matrix<>& series, const std::filesystem::pa bool generateThermalTimeSeries(Data::Study& study, const std::vector& clusters, - Solver::IResultWriter& writer, - const std::string& savePath) + MersenneTwister& thermalRandom) { logs.info(); logs.info() << "Generating the thermal time-series"; - bool archive = study.parameters.timeSeriesToArchive & Data::timeSeriesThermal; - - auto generator = GeneratorTempData(study, - study.parameters.nbTimeSeriesThermal, - study.runtime->random[Data::seedTsGenThermal]); + auto generator = AvailabilityTSgenerator(study.parameters.derated, + study.parameters.nbTimeSeriesThermal, + thermalRandom); for (auto* cluster: clusters) { AvailabilityTSGeneratorData tsGenerationData(cluster); - generator.generateTS(tsGenerationData); - - if (archive) // For compatibilty with in memory thermal TS generation - { - std::string filePath = savePath + SEP + cluster->parentArea->id + SEP + cluster->id() - + ".txt"; - writeResultsToDisk(study, writer, cluster->series.timeSeries, filePath); - } + cluster->series.timeSeries = generator.run(tsGenerationData); } return true; } +void writeThermalTimeSeries(const std::vector& clusters, + const fs::path& savePath) +{ + for (auto* cluster: clusters) + { + auto areaName = cluster->parentArea->id.to(); + auto clusterName = cluster->id(); + auto filePath = savePath / areaName / clusterName += ".txt"; + + writeTStoDisk(cluster->series.timeSeries, filePath); + } +} + // gp : we should try to add const identifiers before args here bool generateLinkTimeSeries(std::vector& links, StudyParamsForLinkTS& generalParams, - const std::string& savePath) + const fs::path& savePath) { logs.info(); logs.info() << "Generation of links time-series"; - auto generator = GeneratorTempData(generalParams.derated, - generalParams.nbLinkTStoGenerate, - generalParams.random); + auto generator = AvailabilityTSgenerator(generalParams.derated, + generalParams.nbLinkTStoGenerate, + generalParams.random); for (auto& link: links) { if (!link.hasValidData) @@ -695,33 +661,23 @@ bool generateLinkTimeSeries(std::vector& links, continue; // Skipping the link } - Data::TimeSeriesNumbers fakeTSnumbers; // gp : to quickly get rid of - Data::TimeSeries ts(fakeTSnumbers); - ts.resize(generalParams.nbLinkTStoGenerate, HOURS_PER_YEAR); - - // DIRECT + // === DIRECT ======================= AvailabilityTSGeneratorData tsConfigDataDirect(link, - ts, link.modulationCapacityDirect, link.namesPair.second); + auto generated_ts = generator.run(tsConfigDataDirect); - generator.generateTS(tsConfigDataDirect); + auto filePath = savePath / link.namesPair.first / link.namesPair.second += "_direct.txt"; + writeTStoDisk(generated_ts, filePath); - std::string filePath = savePath + SEP + link.namesPair.first + SEP + link.namesPair.second - + "_direct.txt"; - writeResultsToDisk(ts.timeSeries, filePath); - - // INDIRECT + // === INDIRECT ======================= AvailabilityTSGeneratorData tsConfigDataIndirect(link, - ts, link.modulationCapacityIndirect, link.namesPair.second); + generated_ts = generator.run(tsConfigDataIndirect); - generator.generateTS(tsConfigDataIndirect); - - filePath = savePath + SEP + link.namesPair.first + SEP + link.namesPair.second - + "_indirect.txt"; - writeResultsToDisk(ts.timeSeries, filePath); + filePath = savePath / link.namesPair.first / link.namesPair.second += "_indirect.txt"; + writeTStoDisk(generated_ts, filePath); } return true; diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index bfb2901bfa..5ffea85100 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -24,15 +24,14 @@ #include #include -#include #include #include #include #include -#include #include "xcast/xcast.h" +namespace fs = std::filesystem; using LinkPair = std::pair; using LinkPairs = std::vector; @@ -52,7 +51,7 @@ struct LinkTSgenerationParams { LinkPair namesPair; - unsigned unitCount = 0; + unsigned unitCount = 1; double nominalCapacity = 0; double forcedVolatility = 0.; @@ -76,7 +75,6 @@ class AvailabilityTSGeneratorData explicit AvailabilityTSGeneratorData(Data::ThermalCluster*); AvailabilityTSGeneratorData(LinkTSgenerationParams&, - Data::TimeSeries&, Matrix<>& modulation, const std::string& name); @@ -91,8 +89,6 @@ class AvailabilityTSGeneratorData Data::PreproAvailability* prepro; - Matrix<>& series; - Matrix<>::ColumnType& modulationCapacity; const std::string& name; @@ -110,12 +106,14 @@ bool GenerateTimeSeries(Data::Study& study, uint year, IResultWriter& writer); bool generateThermalTimeSeries(Data::Study& study, const std::vector& clusters, - Solver::IResultWriter& writer, - const std::string& savePath); + MersenneTwister& thermalRandom); + +void writeThermalTimeSeries(const std::vector& clusters, + const fs::path& savePath); bool generateLinkTimeSeries(std::vector& links, StudyParamsForLinkTS&, - const std::string& savePath); + const fs::path& savePath); std::vector getAllClustersToGen(const Data::AreaList& areas, bool globalThermalTSgeneration); diff --git a/src/tools/ts-generator/CMakeLists.txt b/src/tools/ts-generator/CMakeLists.txt index cea38ae0cd..f037e6f1dd 100644 --- a/src/tools/ts-generator/CMakeLists.txt +++ b/src/tools/ts-generator/CMakeLists.txt @@ -1,5 +1,9 @@ set(SRCS main.cpp + include/antares/tools/ts-generator/linksTSgenerator.h + include/antares/tools/ts-generator/tsGenerationOptions.h + tsGenerationOptions.cpp + linksTSgenerator.cpp ) set(execname "antares-ts-generator") @@ -13,15 +17,15 @@ INSTALL(EXPORT ${execname} target_link_libraries(${execname} PRIVATE - Antares::utils - antares-solver-ts-generator - Antares::study - Antares::checks + Antares::utils + antares-solver-ts-generator + Antares::study + Antares::checks ) target_include_directories(${execname} PRIVATE - "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/include" ) import_std_libs(${execname}) diff --git a/src/tools/ts-generator/include/antares/tools/ts-generator/linksTSgenerator.h b/src/tools/ts-generator/include/antares/tools/ts-generator/linksTSgenerator.h new file mode 100644 index 0000000000..1feaac5038 --- /dev/null +++ b/src/tools/ts-generator/include/antares/tools/ts-generator/linksTSgenerator.h @@ -0,0 +1,32 @@ + +#pragma once + +#include +#include "antares/tools/ts-generator/tsGenerationOptions.h" + +namespace fs = std::filesystem; + +namespace Antares::TSGenerator +{ + +class LinksTSgenerator +{ +public: + LinksTSgenerator(Settings&); + void extractData(); + bool generate(); + +private: + LinkPairs extractLinkNamesFromStudy(); + LinkPairs extractLinkNamesFromCmdLine(const LinkPairs&); + StudyParamsForLinkTS readGeneralParamsForLinksTS(); + void extractLinksSpecificTSparameters(); + + std::string linksFromCmdLineOptions_; + fs::path studyFolder_; + bool generateTSforAllLinks_ = false; + std::vector linkList_; + StudyParamsForLinkTS generalParams_; +}; + +} // namespace Antares::TSGenerator diff --git a/src/tools/ts-generator/include/antares/tools/ts-generator/tsGenerationOptions.h b/src/tools/ts-generator/include/antares/tools/ts-generator/tsGenerationOptions.h new file mode 100644 index 0000000000..1d83cce593 --- /dev/null +++ b/src/tools/ts-generator/include/antares/tools/ts-generator/tsGenerationOptions.h @@ -0,0 +1,31 @@ + +#pragma once + +#include + +#include + +namespace Antares::TSGenerator +{ +struct Settings +{ + std::string studyFolder; + + /// generate TS for all clusters if activated + bool allThermal = false; + /// generate TS for a list "area.cluster;area2.cluster2;" + std::string thermalListToGen = ""; + + /// generate TS for all links if activated + bool allLinks = false; + /// generate TS for a list "area.link;area2.link2;" + std::string linksListToGen; +}; + +bool parseOptions(int, char*[], Settings&); +std::unique_ptr createTsGeneratorParser(Settings&); + +bool checkOptions(Settings& options); +bool linkTSrequired(Settings& options); +bool thermalTSrequired(Settings& options); +} // namespace Antares::TSGenerator diff --git a/src/tools/ts-generator/linksTSgenerator.cpp b/src/tools/ts-generator/linksTSgenerator.cpp new file mode 100644 index 0000000000..7ad893194a --- /dev/null +++ b/src/tools/ts-generator/linksTSgenerator.cpp @@ -0,0 +1,347 @@ + +#include "antares/tools/ts-generator/linksTSgenerator.h" + +#include "antares/utils/utils.h" + +namespace Antares::TSGenerator +{ +// ================== +// Free functions +// ================== +std::vector extractTargetAreas(const fs::path& sourceLinkDir) +{ + std::vector to_return; + fs::path pathToIni = sourceLinkDir / "properties.ini"; + IniFile ini; + ini.open(pathToIni); // gp : we should handle reading issues + for (auto s = ini.firstSection; s; s = s->next) + { + to_return.push_back(transformNameIntoID(s->name)); + } + return to_return; +} + +bool pairs_match(const LinkPair& p1, const LinkPair& p2) +{ + return (p1.first == p2.first && p1.second == p2.second) + || (p1.first == p2.second && p1.second == p2.first); +} + +const LinkPair* getMatchingPairInCollection(const LinkPair& pair, const LinkPairs& collection) +{ + for (const auto& p: collection) + { + if (pairs_match(pair, p)) + { + return &p; + } + } + return nullptr; +} + +bool readLinkGeneralProperty(StudyParamsForLinkTS& params, + const Yuni::String& key, + const Yuni::String& value) +{ + if (key == "derated") + { + return value.to(params.derated); + } + if (key == "nbtimeserieslinks") + { + return value.to(params.nbLinkTStoGenerate); + } + if (key == "seed-tsgen-links") + { + unsigned int seed{0}; + if (!value.to(seed)) + { + return false; + } + params.random.reset(seed); + return true; + } + return true; +} + +std::vector CreateLinkList(const LinkPairs& linksFromCmdLine) +{ + std::vector to_return; + std::for_each(linksFromCmdLine.begin(), + linksFromCmdLine.end(), + [&to_return](const auto& link_pair) + { + LinkTSgenerationParams link; + link.namesPair = link_pair; + to_return.push_back(std::move(link)); + }); + return to_return; +} + +LinkTSgenerationParams* findLinkInList(const LinkPair& link_to_find, + std::vector& linkList) +{ + for (auto& link: linkList) + { + if (link.namesPair == link_to_find) + { + return &link; + } + } + return nullptr; +} + +bool readLinkIniProperty(LinkTSgenerationParams* link, + const Yuni::String& key, + const Yuni::String& value) +{ + if (key == "unitcount") + { + return value.to(link->unitCount); + } + + if (key == "nominalcapacity") + { + return value.to(link->nominalCapacity); + } + + if (key == "law.planned") + { + return value.to(link->plannedLaw); + } + + if (key == "law.forced") + { + return value.to(link->forcedLaw); + } + + if (key == "volatility.planned") + { + return value.to(link->plannedVolatility); + } + + if (key == "volatility.forced") + { + return value.to(link->forcedVolatility); + } + + if (key == "force-no-generation") + { + return value.to(link->forceNoGeneration); + } + return true; +} + +void readLinkIniProperties(LinkTSgenerationParams* link, IniFile::Section* section) +{ + for (const IniFile::Property* p = section->firstProperty; p; p = p->next) + { + if (!readLinkIniProperty(link, p->key, p->value)) + { + std::string linkName = link->namesPair.first + "." + link->namesPair.second; + logs.warning() << "Link '" << linkName << "' : reading value of '" << p->key + << "' went wrong"; + link->hasValidData = false; + } + } +} + +void readSourceAreaIniFile(fs::path pathToIni, + std::string sourceAreaName, + std::vector& linkList) +{ + IniFile ini; + ini.open(pathToIni); // gp : we should handle reading problems here + for (auto* section = ini.firstSection; section; section = section->next) + { + std::string targetAreaName = transformNameIntoID(section->name); + const LinkPair processedLink = std::make_pair(sourceAreaName, targetAreaName); + if (auto* foundLink = findLinkInList(processedLink, linkList); foundLink) + { + readLinkIniProperties(foundLink, section); + } + } +} + +void readIniProperties(std::vector& linkList, fs::path toLinksDir) +{ + for (auto& link: linkList) + { + std::string sourceAreaName = link.namesPair.first; + fs::path pathToIni = toLinksDir / sourceAreaName / "properties.ini"; + readSourceAreaIniFile(pathToIni, sourceAreaName, linkList); + } +} + +fs::path makePreproFile(const fs::path& preproFilePath, const std::string& changingEnd) +{ + auto to_return = preproFilePath; + to_return += changingEnd + ".txt"; + return to_return; +} + +bool readLinkPreproTimeSeries(LinkTSgenerationParams& link, fs::path sourceAreaDir) +{ + bool to_return = true; + const auto preproId = link.namesPair.first + "/" + link.namesPair.second; + link.prepro = std::make_unique(preproId, link.unitCount); + + auto preproFileRoot = sourceAreaDir / "prepro" / link.namesPair.second; + + // Testing files existence + auto preproFile = makePreproFile(preproFileRoot, ""); + auto modulationDirectFile = makePreproFile(preproFileRoot, "_mod_direct"); + auto modulationIndirectFile = makePreproFile(preproFileRoot, "_mod_indirect"); + std::vector paths{preproFile, modulationDirectFile, modulationIndirectFile}; + if (std::any_of(paths.begin(), paths.end(), [](auto& path) { return !fs::exists(path); })) + { + link.hasValidData = false; + return false; + } + + // Files loading + to_return = link.prepro->data.loadFromCSVFile(preproFile.string(), + Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && link.prepro->validate() && to_return; + + to_return = link.modulationCapacityDirect.loadFromCSVFile(modulationDirectFile.string(), + 1, + HOURS_PER_YEAR) + && to_return; + + to_return = link.modulationCapacityIndirect.loadFromCSVFile(modulationIndirectFile.string(), + 1, + HOURS_PER_YEAR) + && to_return; + + link.hasValidData = link.hasValidData && to_return; + return to_return; +} + +void readPreproTimeSeries(std::vector& linkList, fs::path toLinksDir) +{ + for (auto& link: linkList) + { + std::string sourceAreaName = link.namesPair.first; + fs::path sourceAreaDir = toLinksDir / sourceAreaName; + if (!readLinkPreproTimeSeries(link, sourceAreaDir)) + { + logs.warning() << "Could not load all prepro/modulation data for link '" + << link.namesPair.first << "." << link.namesPair.second << "'"; + } + } +} + +// ================== +// Class methods +// ================== +LinksTSgenerator::LinksTSgenerator(Settings& settings): + studyFolder_(settings.studyFolder), + linksFromCmdLineOptions_(settings.linksListToGen), + generateTSforAllLinks_(settings.allLinks) +{ +} + +void LinksTSgenerator::extractData() +{ + auto allLinksPairs = extractLinkNamesFromStudy(); + + LinkPairs namesLinksToGenerate; + if (generateTSforAllLinks_) + { + namesLinksToGenerate = allLinksPairs; + } + else + { + namesLinksToGenerate = extractLinkNamesFromCmdLine(allLinksPairs); + } + + linkList_ = CreateLinkList(namesLinksToGenerate); + extractLinksSpecificTSparameters(); + + generalParams_ = readGeneralParamsForLinksTS(); +} + +LinkPairs LinksTSgenerator::extractLinkNamesFromStudy() +{ + LinkPairs to_return; + fs::path linksDir = studyFolder_ / "input" / "links"; + for (const auto& item: fs::directory_iterator{linksDir}) + { + if (item.is_directory()) + { + std::string sourceAreaName = item.path().filename().generic_string(); + auto targetAreas = extractTargetAreas(item); + for (auto& targetAreaName: targetAreas) + { + auto linkPair = std::make_pair(sourceAreaName, targetAreaName); + to_return.push_back(linkPair); + } + } + } + return to_return; +} + +LinkPairs LinksTSgenerator::extractLinkNamesFromCmdLine(const LinkPairs& allLinks) +{ + LinkPairs to_return; + LinkPairs pairsFromCmdLine = splitStringIntoPairs(linksFromCmdLineOptions_, ';', '.'); + for (auto& p: pairsFromCmdLine) + { + if (const auto* found_pair = getMatchingPairInCollection(p, allLinks); found_pair) + { + to_return.push_back(*found_pair); + } + else + { + logs.error() << "Link '" << p.first << "." << p.second << "' not found"; + } + } + return to_return; +} + +StudyParamsForLinkTS LinksTSgenerator::readGeneralParamsForLinksTS() +{ + StudyParamsForLinkTS to_return; + fs::path pathToGeneraldata = studyFolder_ / "settings" / "generaldata.ini"; + IniFile ini; + ini.open(pathToGeneraldata); // gp : we should handle reading issues + for (auto* section = ini.firstSection; section; section = section->next) + { + // Skipping sections useless in the current context + Yuni::String sectionName = section->name; + if (sectionName != "general" && sectionName != "seeds - Mersenne Twister") + { + continue; + } + + for (const IniFile::Property* p = section->firstProperty; p; p = p->next) + { + if (!readLinkGeneralProperty(to_return, p->key, p->value)) + { + logs.warning() << ini.filename() << ": reading value of '" << p->key + << "' went wrong"; + } + } + } + return to_return; +} + +void LinksTSgenerator::extractLinksSpecificTSparameters() +{ + fs::path toLinksDir = studyFolder_ / "input" / "links"; + readIniProperties(linkList_, toLinksDir); + readPreproTimeSeries(linkList_, toLinksDir); +} + +bool LinksTSgenerator::generate() +{ + auto saveTSpath = fs::path(studyFolder_) / "output" / FormattedTime("%Y%m%d-%H%M"); + saveTSpath /= "ts-generator"; + saveTSpath /= "links"; + + return generateLinkTimeSeries(linkList_, generalParams_, saveTSpath); +} + +} // namespace Antares::TSGenerator diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index b1fabf2ff7..d923d26a6c 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -22,74 +22,25 @@ #include #include -#include -#include - -#include -#include -#include #include #include -#include #include #include -#include -#include +#include "antares/tools/ts-generator/linksTSgenerator.h" +#include "antares/tools/ts-generator/tsGenerationOptions.h" +using namespace Antares::TSGenerator; -using namespace Antares; using namespace Antares::TSGenerator; namespace fs = std::filesystem; -struct Settings -{ - std::string studyFolder; - - /// generate TS for all clusters if activated - bool allThermal = false; - /// generate TS for a list "area.cluster;area2.cluster2;" - std::string thermalListToGen = ""; - - /// generate TS for all links if activated - bool allLinks = false; - /// generate TS for a list "area.link;area2.link2;" - std::string linksListToGen = ""; -}; - -std::unique_ptr createTsGeneratorParser(Settings& settings) -{ - auto parser = std::make_unique(); - parser->addParagraph("Antares Time Series generator\n"); - - parser->addFlag(settings.allThermal, - ' ', - "all-thermal", - "Generate TS for all thermal clusters"); - parser->addFlag(settings.thermalListToGen, - ' ', - "thermal", - "Generate TS for a list of area IDs and thermal clusters IDs, " - "\nusage: --thermal=\"areaID.clusterID;area2ID.clusterID\""); - - parser->addFlag(settings.allLinks, ' ', "all-links", "Generate TS capacities for all links"); - parser->addFlag(settings.linksListToGen, - ' ', - "links", - "Generate TS capacities for a list of 2 area IDs, " - "usage: --links=\"areaID.area2ID;area3ID.area1ID\""); - - parser->remainingArguments(settings.studyFolder); - - return parser; -} - std::vector getClustersToGen(Data::AreaList& areas, const std::string& clustersToGen) { std::vector clusters; - const auto ids = splitStringIntoPairs(clustersToGen, ';', '.'); + const auto pairsAreaCluster = splitStringIntoPairs(clustersToGen, ';', '.'); - for (const auto& [areaID, clusterID]: ids) + for (const auto& [areaID, clusterID]: pairsAreaCluster) { logs.info() << "Searching for area: " << areaID << " and cluster: " << clusterID; @@ -113,419 +64,63 @@ std::vector getClustersToGen(Data::AreaList& areas, return clusters; } -// ===== New code for TS generation links ==================================== - -std::vector extractTargetAreas(fs::path sourceLinkDir) -{ - std::vector to_return; - fs::path pathToIni = sourceLinkDir / "properties.ini"; - IniFile ini; - ini.open(pathToIni); // gp : we should handle reading issues - for (auto* s = ini.firstSection; s; s = s->next) - { - std::string targetAreaName = transformNameIntoID(s->name); - to_return.push_back(targetAreaName); - } - return to_return; -} - -LinkPairs extractLinkNamesFromStudy(fs::path studyDir) -{ - LinkPairs to_return; - fs::path linksDir = studyDir / "input" / "links"; - for (const auto& item: fs::directory_iterator{linksDir}) - { - if (item.is_directory()) - { - std::string sourceAreaName = item.path().filename().generic_string(); - auto targetAreas = extractTargetAreas(item); - for (auto& targetAreaName: targetAreas) - { - auto linkPair = std::make_pair(sourceAreaName, targetAreaName); - to_return.push_back(linkPair); - } - } - } - return to_return; -} - -bool pairs_match(const LinkPair& p1, const LinkPair& p2) -{ - return (p1.first == p2.first && p1.second == p2.second) - || (p1.first == p2.second && p1.second == p2.first); -} - -const LinkPair* getMatchingPairInCollection(const LinkPair& pair, const LinkPairs& collection) -{ - for (const auto& p: collection) - { - if (pairs_match(pair, p)) - { - return &p; - } - } - return nullptr; -} - -LinkPairs extractLinkNamesFromCmdLine(const LinkPairs& allLinks, const std::string linksFromCmdLine) -{ - LinkPairs to_return; - LinkPairs pairsFromCmdLine = splitStringIntoPairs(linksFromCmdLine, ';', '.'); - for (auto& p: pairsFromCmdLine) - { - if (const auto* found_pair = getMatchingPairInCollection(p, allLinks); found_pair) - { - to_return.push_back(*found_pair); - } - else - { - logs.error() << "Link '" << p.first << "." << p.second << "' not found"; - } - } - return to_return; -} - -bool readLinkGeneralProperty(StudyParamsForLinkTS& params, - const Yuni::String& key, - const Yuni::String& value) -{ - if (key == "derated") - { - return value.to(params.derated); - } - if (key == "nbtimeserieslinks") - { - return value.to(params.nbLinkTStoGenerate); - } - if (key == "seed-tsgen-links") - { - unsigned int seed{0}; - if (!value.to(seed)) - { - return false; - } - params.random.reset(seed); - return true; - } - return true; // gp : should we return true here ? -} - -StudyParamsForLinkTS readGeneralParamsForLinksTS(fs::path studyDir) -{ - StudyParamsForLinkTS to_return; - fs::path pathToGeneraldata = studyDir / "settings" / "generaldata.ini"; - IniFile ini; - ini.open(pathToGeneraldata); // gp : we should handle reading issues - for (auto* section = ini.firstSection; section; section = section->next) - { - // Skipping sections useless in the current context - Yuni::String sectionName = section->name; - if (sectionName != "general" && sectionName != "seeds - Mersenne Twister") - { - continue; - } - - for (const IniFile::Property* p = section->firstProperty; p; p = p->next) - { - if (!readLinkGeneralProperty(to_return, p->key, p->value)) - { - logs.warning() << ini.filename() << ": reading value of '" << p->key - << "' went wrong"; - } - } - } - return to_return; -} - -std::vector CreateLinkList(const LinkPairs& linksFromCmdLine) -{ - std::vector to_return; - to_return.reserve(linksFromCmdLine.size()); - for (const auto& link_pair: linksFromCmdLine) - { - LinkTSgenerationParams params; - params.namesPair = link_pair; - to_return.push_back(std::move(params)); - } - return to_return; -} - -LinkTSgenerationParams* findLinkInList(const LinkPair& link_to_find, - std::vector& linkList) -{ - for (auto& link: linkList) - { - if (link.namesPair == link_to_find) - { - return &link; - } - } - return nullptr; -} - -bool readLinkIniProperty(LinkTSgenerationParams* link, - const Yuni::String& key, - const Yuni::String& value) +int main(int argc, char* argv[]) { - if (key == "unitcount") - { - return value.to(link->unitCount); - } - - if (key == "nominalcapacity") - { - return value.to(link->nominalCapacity); - } - - if (key == "law.planned") - { - return value.to(link->plannedLaw); - } - - if (key == "law.forced") - { - return value.to(link->forcedLaw); - } + logs.applicationName("ts-generator"); - if (key == "volatility.planned") + Settings settings; + if (!parseOptions(argc, argv, settings)) { - return value.to(link->plannedVolatility); + return 1; } - if (key == "volatility.forced") + if (!checkOptions(settings)) { - return value.to(link->forcedVolatility); + return 1; } - if (key == "force-no-generation") - { - return value.to(link->forceNoGeneration); - } - return true; -} + bool return_code{true}; -void readLinkIniProperties(LinkTSgenerationParams* link, IniFile::Section* section) -{ - for (const IniFile::Property* p = section->firstProperty; p; p = p->next) + if (thermalTSrequired(settings)) { - if (!readLinkIniProperty(link, p->key, p->value)) + // === Data for TS generation === + auto study = std::make_shared(true); + Data::StudyLoadOptions studyOptions; + if (!study->loadFromFolder(settings.studyFolder, studyOptions)) { - std::string linkName = link->namesPair.first + "." + link->namesPair.second; - logs.warning() << "Link '" << linkName << "' : reading value of '" << p->key - << "' went wrong"; - link->hasValidData = false; + logs.error() << "Invalid study given to the generator"; + return 1; } - } -} -void readSourceAreaIniFile(fs::path pathToIni, - std::string sourceAreaName, - std::vector& linkList) -{ - IniFile ini; - ini.open(pathToIni); // gp : we should handle reading issues - for (auto* section = ini.firstSection; section; section = section->next) - { - std::string targetAreaName = transformNameIntoID(section->name); - const LinkPair processedLink = std::make_pair(sourceAreaName, targetAreaName); - if (auto* foundLink = findLinkInList(processedLink, linkList); foundLink) + std::vector clusters; + if (settings.allThermal) { - readLinkIniProperties(foundLink, section); + clusters = getAllClustersToGen(study->areas, true); } - } -} - -void readIniProperties(std::vector& linkList, fs::path toLinksDir) -{ - for (auto& link: linkList) - { - std::string sourceAreaName = link.namesPair.first; - fs::path pathToIni = toLinksDir / sourceAreaName / "properties.ini"; - readSourceAreaIniFile(pathToIni, sourceAreaName, linkList); - } -} - -bool readLinkPreproTimeSeries(LinkTSgenerationParams& link, fs::path sourceAreaDir) -{ - bool to_return = true; - const auto preproId = link.namesPair.first + "/" + link.namesPair.second; - link.prepro = std::make_unique(preproId, link.unitCount); - - auto preproFileRoot = sourceAreaDir / "prepro" / link.namesPair.second; - - auto preproFile = preproFileRoot; - preproFile += ".txt"; - if (fs::exists(preproFile)) - { - to_return = link.prepro->data.loadFromCSVFile( - preproFile.string(), - Data::PreproAvailability::preproAvailabilityMax, - DAYS_PER_YEAR) - && link.prepro->validate() && to_return; - } - - auto modulationFileDirect = preproFileRoot; - modulationFileDirect += "_mod_direct.txt"; - if (fs::exists(modulationFileDirect)) - { - to_return = link.modulationCapacityDirect.loadFromCSVFile(modulationFileDirect.string(), - 1, - HOURS_PER_YEAR) - && to_return; - } - - auto modulationFileIndirect = preproFileRoot; - modulationFileIndirect += "_mod_indirect.txt"; - if (fs::exists(modulationFileIndirect)) - { - to_return = link.modulationCapacityIndirect.loadFromCSVFile(modulationFileIndirect.string(), - 1, - HOURS_PER_YEAR) - && to_return; - } - // Makes possible a skip of TS generation when time comes - link.hasValidData = link.hasValidData && to_return; - return to_return; -} - -void readPreproTimeSeries(std::vector& linkList, fs::path toLinksDir) -{ - for (auto& link: linkList) - { - std::string sourceAreaName = link.namesPair.first; - fs::path sourceAreaDir = toLinksDir / sourceAreaName; - if (!readLinkPreproTimeSeries(link, sourceAreaDir)) + else if (!settings.thermalListToGen.empty()) { - logs.warning() << "Could not load all prepro data for link '" << link.namesPair.first - << "." << link.namesPair.second << "'"; + clusters = getClustersToGen(study->areas, settings.thermalListToGen); } - } -} - -void readLinksSpecificTSparameters(std::vector& linkList, - fs::path studyFolder) -{ - fs::path toLinksDir = studyFolder / "input" / "links"; - readIniProperties(linkList, toLinksDir); - readPreproTimeSeries(linkList, toLinksDir); -} - -std::string DateAndTime() -{ - YString to_return; - unsigned int now = Yuni::DateTime::Now(); - Yuni::DateTime::TimestampToString(to_return, "%Y%m%d-%H%M", now); - return to_return.to(); -} -// ============================================================================ + // === TS generation === + MersenneTwister thermalRandom; + thermalRandom.reset(study->parameters.seed[Data::seedTsGenThermal]); + return_code = TSGenerator::generateThermalTimeSeries(*study, clusters, thermalRandom); -int main(int argc, char* argv[]) -{ - logs.applicationName("ts-generator"); - - Settings settings; - - auto parser = createTsGeneratorParser(settings); - switch (auto ret = parser->operator()(argc, argv); ret) - { - using namespace Yuni::GetOpt; - case ReturnCode::error: - logs.error() << "Unknown arguments, aborting"; - return parser->errors(); - case ReturnCode::help: - // End the program - return 0; - default: - break; - } - - if (settings.allThermal && !settings.thermalListToGen.empty()) - { - logs.error() << "Conflicting options, either choose all thermal clusters or a list"; - return 1; - } - - if (settings.allLinks && !settings.linksListToGen.empty()) - { - logs.error() << "Conflicting options, either choose all links or a list"; - return 1; - } - - auto study = std::make_shared(true); - Data::StudyLoadOptions studyOptions; - studyOptions.prepareOutput = true; - - if (!study->loadFromFolder(settings.studyFolder, studyOptions)) - { - logs.error() << "Invalid study given to the generator"; - return 1; - } - - study->initializeRuntimeInfos(); - // Force the writing of generated TS into output/YYYYMMDD-HHSSeco/ts-generator/thermal[/mc-0] - study->parameters.timeSeriesToArchive |= Antares::Data::timeSeriesThermal; - - try - { - Antares::Check::checkMinStablePower(true, study->areas); - } - catch (Error::InvalidParametersForThermalClusters& ex) - { - Antares::logs.error() << ex.what(); - } - - Benchmarking::DurationCollector durationCollector; - - auto resultWriter = Solver::resultWriterFactory(Data::ResultFormat::legacyFilesDirectories, - study->folderOutput, - nullptr, - durationCollector); - - const auto thermalSavePath = fs::path("ts-generator") / "thermal"; - - // ============ THERMAL : Getting data for generating time-series ========= - std::vector clusters; - if (settings.allThermal) - { - clusters = TSGenerator::getAllClustersToGen(study->areas, true); - } - else if (!settings.thermalListToGen.empty()) - { - clusters = getClustersToGen(study->areas, settings.thermalListToGen); - } - - for (auto& c: clusters) - { - logs.debug() << c->id(); + // === Writing generated TS on disk === + auto thermalSavePath = fs::path(settings.studyFolder) / "output" + / FormattedTime("%Y%m%d-%H%M"); + thermalSavePath /= "ts-generator"; + thermalSavePath /= "thermal"; + writeThermalTimeSeries(clusters, thermalSavePath); } - // ============ LINKS : Getting data for generating LINKS time-series ===== - auto allLinksPairs = extractLinkNamesFromStudy(settings.studyFolder); - auto linksFromCmdLine = extractLinkNamesFromCmdLine(allLinksPairs, settings.linksListToGen); - if (settings.allLinks) + if (linkTSrequired(settings)) { - linksFromCmdLine = allLinksPairs; + LinksTSgenerator linksTSgenerator(settings); + linksTSgenerator.extractData(); + return_code = linksTSgenerator.generate() && return_code; } - StudyParamsForLinkTS generalParams = readGeneralParamsForLinksTS(settings.studyFolder); - - std::vector linkList = CreateLinkList(linksFromCmdLine); - readLinksSpecificTSparameters(linkList, settings.studyFolder); - - auto saveLinksTSpath = fs::path(settings.studyFolder) / "output" / DateAndTime(); - saveLinksTSpath /= "ts-generator"; - saveLinksTSpath /= "links"; - - // ============ TS Generation ============================================= - - bool ret = TSGenerator::generateThermalTimeSeries(*study, - clusters, - *resultWriter, - thermalSavePath.string()); - - ret = TSGenerator::generateLinkTimeSeries(linkList, generalParams, saveLinksTSpath.string()) - && ret; - - return !ret; // return 0 for success + return !return_code; // return 0 for success } diff --git a/src/tools/ts-generator/tsGenerationOptions.cpp b/src/tools/ts-generator/tsGenerationOptions.cpp new file mode 100644 index 0000000000..29fa64b6ad --- /dev/null +++ b/src/tools/ts-generator/tsGenerationOptions.cpp @@ -0,0 +1,77 @@ +#include "antares/tools/ts-generator/tsGenerationOptions.h" + +#include + +namespace Antares::TSGenerator +{ + +std::unique_ptr createTsGeneratorParser(Settings& settings) +{ + auto parser = std::make_unique(); + parser->addParagraph("Antares Time Series generator\n"); + + parser->addFlag(settings.allThermal, + ' ', + "all-thermal", + "Generate TS for all thermal clusters"); + parser->addFlag(settings.thermalListToGen, + ' ', + "thermal", + "Generate TS for a list of area IDs and thermal clusters IDs, " + "\nusage: --thermal=\"areaID.clusterID;area2ID.clusterID\""); + + parser->addFlag(settings.allLinks, ' ', "all-links", "Generate TS capacities for all links"); + parser->addFlag(settings.linksListToGen, + ' ', + "links", + "Generate TS capacities for a list of 2 area IDs, " + "usage: --links=\"areaID.area2ID;area3ID.area1ID\""); + + parser->remainingArguments(settings.studyFolder); + + return parser; +} + +bool parseOptions(int argc, char* argv[], Settings& options) +{ + auto parser = createTsGeneratorParser(options); + switch (auto ret = parser->operator()(argc, argv); ret) + { + using namespace Yuni::GetOpt; + case ReturnCode::error: + logs.error() << "Unknown arguments, aborting"; + return false; + case ReturnCode::help: + return false; + default: + break; + } + return true; +} + +bool checkOptions(Settings& options) +{ + if (options.allThermal && !options.thermalListToGen.empty()) + { + logs.error() << "Conflicting options, either choose all thermal clusters or a list"; + return false; + } + + if (options.allLinks && !options.linksListToGen.empty()) + { + logs.error() << "Conflicting options, either choose all links or a list"; + return false; + } + return true; +} + +bool linkTSrequired(Settings& options) +{ + return options.allLinks || !options.linksListToGen.empty(); +} + +bool thermalTSrequired(Settings& options) +{ + return options.allThermal || !options.thermalListToGen.empty(); +} +} // namespace Antares::TSGenerator From 80ae93faf027ab483e51d8dc0c594afe82399cd0 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:15:05 +0200 Subject: [PATCH 074/127] Explain why MPS are named when the problem is infeasible (#2250) --- docs/user-guide/solver/08-command-line.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user-guide/solver/08-command-line.md b/docs/user-guide/solver/08-command-line.md index 0aa433c33c..8ef88dfd23 100644 --- a/docs/user-guide/solver/08-command-line.md +++ b/docs/user-guide/solver/08-command-line.md @@ -41,7 +41,7 @@ hide: | --optimization-range | Force the [simplex optimization range](04-parameters.md#simplex-range) ('day' or 'week') | | --no-constraints | Ignore all binding constraints | | --no-ts-import | Do not import timeseries into the input folder (this option may be useful for running old studies without upgrade) | -| -m, --mps-export | Export anonymous MPS, weekly or daily optimal UC+dispatch linear | +| -m, --mps-export | Export anonymous MPS, weekly or daily optimal UC+dispatch linear (MPS will be named if the problem is infeasible) | | -s, --named-mps-problems | Export named MPS, weekly or daily optimal UC+dispatch linear | | --solver-logs | Print solver logs | | --solver-parameters | Set solver-specific parameters, for instance `--solver-parameters="THREADS 1 PRESOLVE 1"` for XPRESS or `--solver-parameters="parallel/maxnthreads 1, lp/presolving TRUE"` for SCIP. Syntax is solver-dependent, and only supported for SCIP & XPRESS. | @@ -54,4 +54,4 @@ hide: | -p, --pid=VALUE | Specify the file where to write the process ID | | --list-solvers | Display a list of LP solvers available through OR-Tools and exit | | -v, --version | Print the version of the solver and exit | -| -h, --help | Display this help and exit | \ No newline at end of file +| -h, --help | Display this help and exit | From 7be5498aa05fa1a50535ddd8d9115a3f7bd42103 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 10 Jul 2024 16:14:04 +0200 Subject: [PATCH 075/127] Add tests in CI for version 9.2 (#2241) Co-authored-by: Florian OMNES --- .github/workflows/ubuntu.yml | 14 +++++++++++--- .github/workflows/windows-vcpkg.yml | 14 +++++++++++--- simtest.json | 2 +- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 15d8e1ba7a..9f129f04f9 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -191,7 +191,7 @@ jobs: variant: "milp-cbc" os: ${{ env.os }} - - name: Run tests introduced in v860 + - name: Run tests introduced in 8.6.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: @@ -199,7 +199,7 @@ jobs: batch-name: valid-v860 os: ${{ env.os }} - - name: Run tests introduced in v870 + - name: Run tests introduced in 8.7.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: @@ -207,7 +207,7 @@ jobs: batch-name: valid-v870 os: ${{ env.os }} - - name: Run tests introduced in v910 + - name: Run tests introduced in 9.1.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: @@ -215,6 +215,14 @@ jobs: batch-name: valid-v910 os: ${{ env.os }} + - name: Run tests introduced in 9.2.0 + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{ env.SIMTEST }} + batch-name: valid-v920 + os: ${{ env.os }} + - name: Run short-tests if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index 53062edba7..3ad4ddaae8 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -202,7 +202,7 @@ jobs: variant: "milp-cbc" os: ${{ env.test-platform }} - - name: Run tests introduced in v860 + - name: Run tests introduced in 8.6.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: @@ -210,7 +210,7 @@ jobs: batch-name: valid-v860 os: ${{ env.test-platform }} - - name: Run tests introduced in v870 + - name: Run tests introduced in 8.7.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: @@ -218,7 +218,7 @@ jobs: batch-name: valid-v870 os: ${{ env.test-platform }} - - name: Run tests introduced in v910 + - name: Run tests introduced in 9.1.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests with: @@ -226,6 +226,14 @@ jobs: batch-name: valid-v910 os: ${{ env.test-platform }} + - name: Run tests introduced in 9.2.0 + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{ env.SIMTEST }} + batch-name: valid-v920 + os: ${{ env.os }} + - name: Run short-tests if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests diff --git a/simtest.json b/simtest.json index 422fd8e3bd..f5912ade9e 100644 --- a/simtest.json +++ b/simtest.json @@ -1,3 +1,3 @@ { - "version": "v9.2.0a" + "version": "v9.2.0b" } From 6cd09f5942f05f60faa408f5e2614eb8e054a495 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:40:02 +0200 Subject: [PATCH 076/127] Rename test-platform to os for windows CI (#2253) --- .github/workflows/windows-vcpkg.yml | 35 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index 3ad4ddaae8..bcd2ef9e5a 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -37,8 +37,7 @@ jobs: # Indicates the location of the vcpkg as a Git submodule of the project repository. VCPKG_ROOT: ${{ github.workspace }}/vcpkg ORTOOLS_DIR: ${{ github.workspace }}/or-tools - os: windows-latest - test-platform: windows-2022 + os: windows-2022 vcpkgPackages: wxwidgets boost-test triplet: x64-windows-release # Caching strategy of VCPKG dependencies @@ -97,7 +96,7 @@ jobs: - name: Download pre-compiled librairies uses: ./.github/workflows/download-extract-precompiled-libraries-zip with: - os: ${{env.os}} + os: windows-latest ortools-url: ${{env.ORTOOLS_URL}} ortools-dir: ${{env.ORTOOLS_DIR}} @@ -155,7 +154,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: valid-named-mps - os: ${{ env.test-platform }} + os: ${{ env.os }} variant: "named-mps" - name: Run unfeasibility-related tests @@ -183,7 +182,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: adequacy-patch-CSR - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run tests about infinity on BCs RHS if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} @@ -191,7 +190,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v830 - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run MILP with CBC if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} @@ -200,7 +199,7 @@ jobs: simtest-tag: ${{ env.SIMTEST }} batch-name: valid-milp variant: "milp-cbc" - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run tests introduced in 8.6.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} @@ -208,7 +207,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v860 - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run tests introduced in 8.7.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} @@ -216,7 +215,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v870 - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run tests introduced in 9.1.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} @@ -224,7 +223,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: valid-v910 - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run tests introduced in 9.2.0 if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} @@ -240,7 +239,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: short-tests - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run mps tests if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} @@ -248,7 +247,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: valid-mps - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run parallel tests if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} @@ -256,7 +255,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: valid-parallel - os: ${{ env.test-platform }} + os: ${{ env.os }} variant: "parallel" - name: Run tests for time series generator tool @@ -265,7 +264,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: ts-generator - os: ${{ env.test-platform }} + os: ${{ env.os }} variant: "tsgenerator" - name: Run medium-tests @@ -274,7 +273,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: medium-tests - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run long-tests-1 if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} @@ -282,7 +281,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-1 - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run long-tests-2 if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} @@ -290,7 +289,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-2 - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Run long-tests-3 if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} @@ -298,7 +297,7 @@ jobs: with: simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-3 - os: ${{ env.test-platform }} + os: ${{ env.os }} - name: Solver archive creation shell: bash From 8cc64f998723b7facb69a0fa2c63d47eeb175482 Mon Sep 17 00:00:00 2001 From: Juliette-Gerbaux <130555142+Juliette-Gerbaux@users.noreply.github.com> Date: Thu, 11 Jul 2024 16:19:12 +0200 Subject: [PATCH 077/127] Fix bug hydro heuristic with mingen (ANT-1825) (#2258) Removing lines that create infeasibility and that are not necessary. --------- Co-authored-by: Juliette-Gerbaux Co-authored-by: Florian OMNES --- src/solver/simulation/sim_calcul_economique.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index f9f47eb65a..2402ddd548 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -837,12 +837,6 @@ void SIM_RenseignementProblemeHebdo(const Study& study, } marginGen = weekGenerationTarget; - - if (problem.CaracteristiquesHydrauliques[k].NiveauInitialReservoir - < weekTarget_tmp) - { - marginGen = problem.CaracteristiquesHydrauliques[k].NiveauInitialReservoir; - } } if (not problem.CaracteristiquesHydrauliques[k].TurbinageEntreBornes) From 89ac6c8b604701347b5f888eb567d072bc695b6b Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Wed, 17 Jul 2024 10:34:15 +0200 Subject: [PATCH 078/127] Infeasibility anaylsis : make it more changeable (#2232) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create classes for each constraint type, with a common interface. Additional tests to come. --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> Co-authored-by: Florian Omnès --- .../CMakeLists.txt | 4 +- .../constraint-slack-analysis.cpp | 73 ++++--- .../constraint.cpp | 160 --------------- .../constraint-slack-analysis.h | 12 +- .../infeasible-problem-analysis/constraint.h | 62 ------ .../infeasible-problem-analysis/report.h | 23 +-- .../watched-constraints.h | 113 +++++++++++ .../infeasible-problem-analysis/report.cpp | 104 ++++------ .../watched-constraints.cpp | 191 ++++++++++++++++++ .../test-unfeasible-problem-analyzer.cpp | 49 ++--- 10 files changed, 436 insertions(+), 355 deletions(-) delete mode 100644 src/solver/infeasible-problem-analysis/constraint.cpp delete mode 100644 src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h create mode 100644 src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/watched-constraints.h create mode 100644 src/solver/infeasible-problem-analysis/watched-constraints.cpp diff --git a/src/solver/infeasible-problem-analysis/CMakeLists.txt b/src/solver/infeasible-problem-analysis/CMakeLists.txt index 424235facc..72b93ad153 100644 --- a/src/solver/infeasible-problem-analysis/CMakeLists.txt +++ b/src/solver/infeasible-problem-analysis/CMakeLists.txt @@ -10,8 +10,8 @@ set(SRC_INFEASIBLE_PROBLEM_ANALYSIS include/antares/solver/infeasible-problem-analysis/unfeasible-pb-analyzer.h include/antares/solver/infeasible-problem-analysis/report.h report.cpp - include/antares/solver/infeasible-problem-analysis/constraint.h - constraint.cpp + include/antares/solver/infeasible-problem-analysis/watched-constraints.h + watched-constraints.cpp ) add_library(infeasible_problem_analysis ${SRC_INFEASIBLE_PROBLEM_ANALYSIS}) diff --git a/src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp b/src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp index 785d4670f8..099ac70db6 100644 --- a/src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp +++ b/src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp @@ -31,12 +31,23 @@ using namespace operations_research; +namespace +{ +bool compareSlackSolutions(const MPVariable* a, const MPVariable* b) +{ + return a->solution_value() > b->solution_value(); +} + +constexpr unsigned int nbMaxSlackVarsToKeep = 10; +} // namespace + namespace Antares::Optimization { void ConstraintSlackAnalysis::run(MPSolver* problem) { - addSlackVariables(problem); + selectConstraintsToWatch(problem); + addSlackVariablesToConstraints(problem); if (slackVariables_.empty()) { logs.error() << title() << " : no constraints have been selected"; @@ -53,9 +64,21 @@ void ConstraintSlackAnalysis::run(MPSolver* problem) } hasDetectedInfeasibilityCause_ = true; + + sortSlackVariablesByValue(); + trimSlackVariables(); +} + +void ConstraintSlackAnalysis::selectConstraintsToWatch(MPSolver* problem) +{ + ConstraintsFactory factory; + std::regex rgx = factory.constraintsFilter(); + std::ranges::copy_if(problem->constraints(), + std::back_inserter(constraintsToWatch_), + [&rgx](auto* c) { return std::regex_search(c->name(), rgx); }); } -void ConstraintSlackAnalysis::addSlackVariables(MPSolver* problem) +void ConstraintSlackAnalysis::addSlackVariablesToConstraints(MPSolver* problem) { /* Optimization: We assess that less than 1 every 3 constraint will match @@ -64,29 +87,21 @@ void ConstraintSlackAnalysis::addSlackVariables(MPSolver* problem) */ const unsigned int selectedConstraintsInverseRatio = 3; slackVariables_.reserve(problem->NumConstraints() / selectedConstraintsInverseRatio); - std::regex rgx(constraint_name_pattern); const double infinity = MPSolver::infinity(); - for (MPConstraint* constraint: problem->constraints()) + for (MPConstraint* c: constraintsToWatch_) { - if (std::regex_search(constraint->name(), rgx)) + if (c->lb() > -infinity) { - if (constraint->lb() != -infinity) - { - const MPVariable* slack = problem->MakeNumVar(0, - infinity, - constraint->name() + "::low"); - constraint->SetCoefficient(slack, 1.); - slackVariables_.push_back(slack); - } - - if (constraint->ub() != infinity) - { - const MPVariable* slack = problem->MakeNumVar(0, - infinity, - constraint->name() + "::up"); - constraint->SetCoefficient(slack, -1.); - slackVariables_.push_back(slack); - } + const MPVariable* slack = problem->MakeNumVar(0, infinity, c->name() + "::low"); + c->SetCoefficient(slack, 1.); + slackVariables_.push_back(slack); + } + + if (c->ub() < infinity) + { + const MPVariable* slack = problem->MakeNumVar(0, infinity, c->name() + "::up"); + c->SetCoefficient(slack, -1.); + slackVariables_.push_back(slack); } } } @@ -104,10 +119,22 @@ void ConstraintSlackAnalysis::buildObjective(MPSolver* problem) const objective->SetMinimization(); } +void ConstraintSlackAnalysis::sortSlackVariablesByValue() +{ + std::sort(std::begin(slackVariables_), std::end(slackVariables_), ::compareSlackSolutions); +} + +void ConstraintSlackAnalysis::trimSlackVariables() +{ + unsigned int nbSlackVars = slackVariables_.size(); + slackVariables_.resize(std::min(nbMaxSlackVarsToKeep, nbSlackVars)); +} + void ConstraintSlackAnalysis::printReport() const { InfeasibleProblemReport report(slackVariables_); - report.prettyPrint(); + report.logSuspiciousConstraints(); + report.logInfeasibilityCauses(); } } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp deleted file mode 100644 index 2c4fd6d085..0000000000 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ -#include "antares/solver/infeasible-problem-analysis/constraint.h" - -#include -#include -#include -#include - -#include -#include -#include - -namespace -{ -const std::string kUnknown = ""; -} - -namespace Antares::Optimization -{ -Constraint::Constraint(const std::string& name, const double slackValue): - name_(name), - slackValue_(slackValue) -{ -} - -void Constraint::extractComponentsFromName() -{ - boost::algorithm::split_regex(nameComponents_, name_, boost::regex("::")); -} - -double Constraint::getSlackValue() const -{ - return slackValue_; -} - -class StringIsNotWellFormated: public std::runtime_error -{ -public: - StringIsNotWellFormated(const std::string& error_message): - std::runtime_error(error_message) - { - } -}; - -std::string StringBetweenAngleBrackets(const std::string& constraintName) -{ - std::vector split_name; - boost::split(split_name, constraintName, boost::is_any_of("<>")); - - std::string err_msg = "Error: "; - if (split_name.size() < 3) - { - err_msg += "constraint name '" + constraintName + "' misses '<' and/or '>' bracket"; - throw StringIsNotWellFormated(err_msg); - } - if (split_name[1].empty()) - { - err_msg += "constraint name '" + constraintName + "' must be of format '**'"; - throw StringIsNotWellFormated(err_msg); - } - return split_name[1]; -} - -std::string Constraint::areaName() const -{ - return StringBetweenAngleBrackets(nameComponents_.at(1)); -} - -std::string Constraint::timeStep() const -{ - return StringBetweenAngleBrackets(nameComponents_.at(nameComponents_.size() - 2)); -} - -ConstraintType Constraint::type() const -{ - assert(nameComponents_.size() > 1); - if (nameComponents_.at(1) == "hourly") - { - return ConstraintType::binding_constraint_hourly; - } - if (nameComponents_.at(1) == "daily") - { - return ConstraintType::binding_constraint_daily; - } - if (nameComponents_.at(1) == "weekly") - { - return ConstraintType::binding_constraint_weekly; - } - if (nameComponents_.at(0) == "FictiveLoads") - { - return ConstraintType::fictitious_load; - } - if (nameComponents_.at(0) == "AreaHydroLevel") - { - return ConstraintType::hydro_reservoir_level; - } - if (nameComponents_.at(0) == "HydroPower") - { - return ConstraintType::hydro_production_weekly; - } - if (nameComponents_.at(0) == "Level") - { - return ConstraintType::short_term_storage_level; - } - return ConstraintType::none; -} - -std::string Constraint::shortName() const -{ - return nameComponents_.at(0); -} - -std::string Constraint::STSname() const -{ - return StringBetweenAngleBrackets(nameComponents_.at(2)); -} - -std::string Constraint::prettyPrint() const -{ - switch (type()) - { - case ConstraintType::binding_constraint_hourly: - return "Hourly binding constraint '" + shortName() + "' at hour " + timeStep(); - case ConstraintType::binding_constraint_daily: - return "Daily binding constraint '" + shortName() + "' at day " + timeStep(); - case ConstraintType::binding_constraint_weekly: - return "Weekly binding constraint '" + shortName(); - case ConstraintType::fictitious_load: - return "Last resort shedding status at area '" + areaName() + "' at hour " + timeStep(); - case ConstraintType::hydro_reservoir_level: - return "Hydro reservoir constraint at area '" + areaName() + "' at hour " + timeStep(); - case ConstraintType::hydro_production_weekly: - return "Hydro weekly production at area '" + areaName() + "'"; - case ConstraintType::short_term_storage_level: - return "Short-term-storage reservoir constraint at area '" + areaName() + "' in STS '" - + STSname() + "' at hour " + timeStep(); - default: - return kUnknown; - } -} -} // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h index bb56228b2f..462d5f965f 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h @@ -23,9 +23,11 @@ #include #include "unfeasibility-analysis.h" +#include "watched-constraints.h" namespace operations_research { +class MPConstraint; class MPVariable; class MPSolver; } // namespace operations_research @@ -40,7 +42,6 @@ namespace Antares::Optimization class ConstraintSlackAnalysis: public UnfeasibilityAnalysis { public: - ConstraintSlackAnalysis() = default; ~ConstraintSlackAnalysis() override = default; void run(operations_research::MPSolver* problem) override; @@ -52,13 +53,14 @@ class ConstraintSlackAnalysis: public UnfeasibilityAnalysis } private: + void selectConstraintsToWatch(operations_research::MPSolver* problem); + void addSlackVariablesToConstraints(operations_research::MPSolver* problem); void buildObjective(operations_research::MPSolver* problem) const; - void addSlackVariables(operations_research::MPSolver* problem); + void sortSlackVariablesByValue(); + void trimSlackVariables(); + std::vector constraintsToWatch_; std::vector slackVariables_; - const std::string constraint_name_pattern = "^AreaHydroLevel::|::hourly::|::daily::|::weekly::|" - "^FictiveLoads::|^Level::|" - "^HydroPower::"; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h deleted file mode 100644 index 52fb799692..0000000000 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ -#pragma once - -#include -#include - -namespace Antares::Optimization -{ -enum class ConstraintType -{ - binding_constraint_hourly, - binding_constraint_daily, - binding_constraint_weekly, - fictitious_load, - hydro_reservoir_level, - hydro_production_weekly, - short_term_storage_level, - none -}; - -class Constraint -{ -public: - Constraint() = default; - Constraint(const std::string& name, const double slackValue); - - double getSlackValue() const; - - void extractComponentsFromName(); - std::string prettyPrint() const; - ConstraintType type() const; - -private: - std::string name_; - std::vector nameComponents_; - double slackValue_; - - std::string areaName() const; - std::string STSname() const; - std::string timeStep() const; - std::string shortName() const; -}; -} // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h index 898f4df359..ef242b1f36 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h @@ -21,10 +21,12 @@ #pragma once #include +#include #include #include -#include "constraint.h" +#include "ortools/linear_solver/linear_solver.h" +#include "watched-constraints.h" namespace operations_research { @@ -37,21 +39,14 @@ class InfeasibleProblemReport { public: InfeasibleProblemReport() = delete; - explicit InfeasibleProblemReport( - const std::vector& slackVariables); - void prettyPrint(); - -private: - void turnSlackVarsIntoConstraints( - const std::vector& slackVariables); - void sortConstraintsBySlackValue(); - void trimConstraints(); - void sortConstraintsByType(); + explicit InfeasibleProblemReport(const std::vector&); void logSuspiciousConstraints(); void logInfeasibilityCauses(); - std::vector constraints_; - std::map nbConstraintsByType_; - const unsigned int nbMaxVariables = 10; +private: + void buildConstraintsFromSlackVars(const std::vector&); + void filterConstraintsToOneByType(); + + std::vector> constraints_; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/watched-constraints.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/watched-constraints.h new file mode 100644 index 0000000000..1c1c533d71 --- /dev/null +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/watched-constraints.h @@ -0,0 +1,113 @@ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Antares::Optimization +{ +class WatchedConstraint +{ +public: + explicit WatchedConstraint(const std::string& name, const double slackValue); + virtual ~WatchedConstraint() = default; + virtual std::string infeasibility() = 0; + virtual std::string infeasibilityCause() = 0; + double slackValue() const; + +protected: + const std::vector& splitName() const; + +private: + std::vector splitName_; + double slack_value_; +}; + +class HourlyBC: public WatchedConstraint +{ + using WatchedConstraint::WatchedConstraint; + +public: + ~HourlyBC() override = default; + std::string infeasibility() override; + std::string infeasibilityCause() override; +}; + +class DailyBC: public WatchedConstraint +{ + using WatchedConstraint::WatchedConstraint; + +public: + ~DailyBC() override = default; + std::string infeasibility() override; + std::string infeasibilityCause() override; +}; + +class WeeklyBC: public WatchedConstraint +{ + using WatchedConstraint::WatchedConstraint; + +public: + ~WeeklyBC() override = default; + std::string infeasibility() override; + std::string infeasibilityCause() override; +}; + +class FictitiousLoad: public WatchedConstraint +{ + using WatchedConstraint::WatchedConstraint; + +public: + ~FictitiousLoad() override = default; + std::string infeasibility() override; + std::string infeasibilityCause() override; +}; + +class HydroLevel: public WatchedConstraint +{ + using WatchedConstraint::WatchedConstraint; + +public: + ~HydroLevel() override = default; + std::string infeasibility() override; + std::string infeasibilityCause() override; +}; + +class STS: public WatchedConstraint +{ + using WatchedConstraint::WatchedConstraint; + +public: + ~STS() override = default; + std::string infeasibility() override; + std::string infeasibilityCause() override; +}; + +class HydroProduction: public WatchedConstraint +{ + using WatchedConstraint::WatchedConstraint; + +public: + ~HydroProduction() override = default; + std::string infeasibility() override; + std::string infeasibilityCause() override; +}; + +class ConstraintsFactory +{ +public: + explicit ConstraintsFactory(); + std::unique_ptr create(const std::string&, const double) const; + std::regex constraintsFilter(); + +private: + std::map(const std::string&, const double)>> + regex_to_ctypes_; +}; + +} // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index 5154cffa0e..dc43da140a 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -21,107 +21,79 @@ #include "antares/solver/infeasible-problem-analysis/report.h" #include +#include +#include #include -#include "antares/solver/infeasible-problem-analysis/constraint.h" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#include "ortools/linear_solver/linear_solver.h" -#pragma GCC diagnostic pop - -using namespace operations_research; - -static bool compareSlackSolutions(const Antares::Optimization::Constraint& a, - const Antares::Optimization::Constraint& b) -{ - return a.getSlackValue() > b.getSlackValue(); -} namespace Antares::Optimization { InfeasibleProblemReport::InfeasibleProblemReport( - const std::vector& slackVariables) + const std::vector& slackVariables) { - turnSlackVarsIntoConstraints(slackVariables); - sortConstraintsBySlackValue(); - trimConstraints(); - sortConstraintsByType(); + buildConstraintsFromSlackVars(slackVariables); } -void InfeasibleProblemReport::turnSlackVarsIntoConstraints( - const std::vector& slackVariables) +void InfeasibleProblemReport::buildConstraintsFromSlackVars( + const std::vector& slackVariables) { - for (const MPVariable* slack: slackVariables) + const ConstraintsFactory constraintsFactory; + for (const auto* slackVar: slackVariables) { - constraints_.emplace_back(slack->name(), slack->solution_value()); + auto constraint = constraintsFactory.create(slackVar->name(), slackVar->solution_value()); + if (constraint) + { + constraints_.push_back(std::move(constraint)); + } } } -void InfeasibleProblemReport::sortConstraintsBySlackValue() +bool lessTypeName(const std::shared_ptr a, + const std::shared_ptr b) { - std::sort(std::begin(constraints_), std::end(constraints_), ::compareSlackSolutions); + return std::type_index(typeid(*a)) < std::type_index(typeid(*b)); } -void InfeasibleProblemReport::trimConstraints() +bool sameType(const std::shared_ptr a, + const std::shared_ptr b) { - unsigned int nbConstraints = constraints_.size(); - constraints_.resize(std::min(nbMaxVariables, nbConstraints)); + return std::type_index(typeid(*a)) == std::type_index(typeid(*b)); } -void InfeasibleProblemReport::sortConstraintsByType() +bool greaterValue(const std::shared_ptr a, std::shared_ptr b) { - for (auto& c: constraints_) - { - c.extractComponentsFromName(); - nbConstraintsByType_[c.type()]++; - } + return a->slackValue() > b->slackValue(); +} + +void InfeasibleProblemReport::filterConstraintsToOneByType() +{ + // 1. Grouping constraints by C++ type (inside a group, order of instances remains unchanged) + std::ranges::stable_sort(constraints_, lessTypeName); + // 2. Keeping the first instances of each group, and rejecting others (= duplicates) to the end + // of vector + auto duplicates = std::ranges::unique(constraints_, sameType); + // 3. Removing trailing duplicates + constraints_.erase(duplicates.begin(), duplicates.end()); + // 4. Sorting remaining constraints by slack value (in descending order) + std::ranges::sort(constraints_, greaterValue); } void InfeasibleProblemReport::logSuspiciousConstraints() { - Antares::logs.error() << "The following constraints are suspicious (first = most suspicious)"; for (const auto& c: constraints_) { - Antares::logs.error() << c.prettyPrint(); + Antares::logs.error() << c->infeasibility(); } } void InfeasibleProblemReport::logInfeasibilityCauses() { + filterConstraintsToOneByType(); Antares::logs.error() << "Possible causes of infeasibility:"; - if (nbConstraintsByType_[ConstraintType::hydro_reservoir_level] > 0) - { - Antares::logs.error() << "* Hydro reservoir impossible to manage with cumulative options " - "\"hard bounds without heuristic\""; - } - if (nbConstraintsByType_[ConstraintType::hydro_production_weekly] > 0) - { - Antares::logs.error() << "* impossible to generate exactly the weekly hydro target"; - } - if (nbConstraintsByType_[ConstraintType::fictitious_load] > 0) - { - Antares::logs.error() << "* Last resort shedding status,"; - } - if (nbConstraintsByType_[ConstraintType::short_term_storage_level] > 0) - { - Antares::logs.error() - << "* Short-term storage reservoir level impossible to manage. Please check inflows, " - "lower & upper curves and initial level (if prescribed),"; - } - - const unsigned int bcCount = nbConstraintsByType_[ConstraintType::binding_constraint_hourly] - + nbConstraintsByType_[ConstraintType::binding_constraint_daily] - + nbConstraintsByType_[ConstraintType::binding_constraint_weekly]; - if (bcCount > 0) + for (const auto& c: constraints_) { - Antares::logs.error() << "* Binding constraints,"; + Antares::logs.error() << c->infeasibilityCause(); } } -void InfeasibleProblemReport::prettyPrint() -{ - logSuspiciousConstraints(); - logInfeasibilityCauses(); -} - } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/watched-constraints.cpp b/src/solver/infeasible-problem-analysis/watched-constraints.cpp new file mode 100644 index 0000000000..e054f49f03 --- /dev/null +++ b/src/solver/infeasible-problem-analysis/watched-constraints.cpp @@ -0,0 +1,191 @@ +#include "antares/solver/infeasible-problem-analysis/watched-constraints.h" + +#include + +#include +#include +#include + +class StringIsNotWellFormated: public std::runtime_error +{ +public: + StringIsNotWellFormated(const std::string& error_message): + std::runtime_error(error_message) + { + } +}; + +std::string StringBetweenAngleBrackets(const std::string& constraintName) +{ + std::vector split_name; + boost::split(split_name, constraintName, boost::is_any_of("<>")); + + std::string err_msg = "Error: "; + if (split_name.size() < 3) + { + err_msg += "constraint name '" + constraintName + "' misses '<' and/or '>' bracket"; + throw StringIsNotWellFormated(err_msg); + } + if (split_name[1].empty()) + { + err_msg += "constraint name '" + constraintName + "' must be of format '**'"; + throw StringIsNotWellFormated(err_msg); + } + return split_name[1]; +} + +std::string timeStep(std::vector splitName) +{ + return StringBetweenAngleBrackets(splitName.at(splitName.size() - 2)); +} + +std::string shortName(std::vector splitName) +{ + return splitName.at(0); +} + +std::string areaName(std::vector splitName) +{ + return StringBetweenAngleBrackets(splitName.at(1)); +} + +std::string STSname(std::vector splitName) +{ + return StringBetweenAngleBrackets(splitName.at(2)); +} + +namespace Antares::Optimization +{ + +// --- Generic constraint --- +WatchedConstraint::WatchedConstraint(const std::string& name, const double slackValue): + slack_value_(slackValue) +{ + boost::algorithm::split_regex(splitName_, name, boost::regex("::")); +} + +const std::vector& WatchedConstraint::splitName() const +{ + return splitName_; +} + +double WatchedConstraint::slackValue() const +{ + return slack_value_; +} + +std::string HourlyBC::infeasibility() +{ + return "Hourly BC '" + shortName(splitName()) + "' at hour " + timeStep(splitName()); +} + +std::string HourlyBC::infeasibilityCause() +{ + return "* Hourly binding constraints."; +} + +// --- Daily BC constraint --- +std::string DailyBC::infeasibility() +{ + return "Daily BC '" + shortName(splitName()) + "' at day " + timeStep(splitName()); +} + +std::string DailyBC::infeasibilityCause() +{ + return "* Daily binding constraints,"; +} + +// --- Weekly BC constraint --- +std::string WeeklyBC::infeasibility() +{ + return "Weekly BC '" + shortName(splitName()); +} + +std::string WeeklyBC::infeasibilityCause() +{ + return "* Weekly binding constraints."; +} + +// --- Fictitious load constraint --- +std::string FictitiousLoad::infeasibility() +{ + return "Last resort shedding status at area '" + areaName(splitName()) + "' at hour " + + timeStep(splitName()); +} + +std::string FictitiousLoad::infeasibilityCause() +{ + return "* Last resort shedding status."; +} + +// --- Hydro level constraint --- +std::string HydroLevel::infeasibility() +{ + return "Hydro level constraint at area '" + areaName(splitName()) + "' at hour " + + timeStep(splitName()); +} + +std::string HydroLevel::infeasibilityCause() +{ + return "* Hydro reservoir impossible to manage with cumulative options " + "\"hard bounds without heuristic\""; +} + +// --- Short term storage constraint --- +std::string STS::infeasibility() +{ + return "Short-term-storage reservoir constraint at area '" + areaName(splitName()) + + "' in STS '" + STSname(splitName()) + "' at hour " + timeStep(splitName()); +} + +std::string STS::infeasibilityCause() +{ + return "* Short-term storage reservoir level impossible to manage. Please check inflows, " + "lower & upper curves and initial level (if prescribed),"; +} + +// --- Hydro production constraint --- +std::string HydroProduction::infeasibility() +{ + return "Hydro weekly production at area '" + areaName(splitName()) + "'"; +} + +std::string HydroProduction::infeasibilityCause() +{ + return "* impossible to generate exactly the weekly hydro target"; +} + +// --- Constraints factory --- +ConstraintsFactory::ConstraintsFactory() +{ + regex_to_ctypes_ = { + {"::hourly::", std::make_unique}, + {"::daily::", std::make_unique}, + {"::weekly::", std::make_unique}, + {"^FictiveLoads::", std::make_unique}, + {"^AreaHydroLevel::", std::make_unique}, + {"^Level::", std::make_unique}, + {"^HydroPower::", std::make_unique}}; +} + +std::unique_ptr ConstraintsFactory::create(const std::string& name, + const double value) const +{ + auto it = std::ranges::find_if(regex_to_ctypes_, + [&name](auto& pair) + { return std::regex_search(name, std::regex(pair.first)); }); + if (it != regex_to_ctypes_.end()) + { + return it->second(name, value); + } + return nullptr; +} + +std::regex ConstraintsFactory::constraintsFilter() +{ + auto keyView = std::views::keys(regex_to_ctypes_); + std::vector regex_ids = {keyView.begin(), keyView.end()}; + return std::regex(boost::algorithm::join(regex_ids, "|")); +} + +} // namespace Antares::Optimization diff --git a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp index 8d960f7381..20086d505f 100644 --- a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp +++ b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp @@ -135,48 +135,51 @@ BOOST_AUTO_TEST_CASE(analysis_should_detect_inconsistent_variable_bounds) /*! * Creates a problem with 2 variables linked by 1 constraint: * - Variable 1 must be greater than 1 - * - Variable 2 must be lesser than -1 + * - Variable 2 must be smaller than -1 * - but if feasible is false, constraint enforces that variable 2 is greater than variable 1 --> * infeasible */ -std::unique_ptr createProblem(const std::string& constraintName, bool feasible) + +std::unique_ptr createProblem(const std::string& constraintName) { std::unique_ptr problem(MPSolver::CreateSolver("GLOP")); const double infinity = problem->infinity(); - auto var1 = problem->MakeNumVar(1, infinity, "var1"); - auto var2 = problem->MakeNumVar(-infinity, -1, "var2"); + problem->MakeNumVar(1, infinity, "var1"); + problem->MakeNumVar(-infinity, -1, "var2"); auto constraint = problem->MakeRowConstraint(constraintName); constraint->SetBounds(0, infinity); - if (feasible) - { - constraint->SetCoefficient(var1, 1); - constraint->SetCoefficient(var2, -1); - } - else - { - constraint->SetCoefficient(var1, -1); - constraint->SetCoefficient(var2, 1); - } return problem; } std::unique_ptr createFeasibleProblem(const std::string& constraintName) { - return createProblem(constraintName, true); + auto problem = createProblem(constraintName); + auto constraint = problem->LookupConstraintOrNull(constraintName); + auto var1 = problem->LookupVariableOrNull("var1"); + auto var2 = problem->LookupVariableOrNull("var2"); + constraint->SetCoefficient(var1, 1); + constraint->SetCoefficient(var2, -1); + return problem; } std::unique_ptr createUnfeasibleProblem(const std::string& constraintName) { - return createProblem(constraintName, false); + auto problem = createProblem(constraintName); + auto constraint = problem->LookupConstraintOrNull(constraintName); + auto var1 = problem->LookupVariableOrNull("var1"); + auto var2 = problem->LookupVariableOrNull("var2"); + constraint->SetCoefficient(var1, -1); + constraint->SetCoefficient(var2, 1); + return problem; } -static const std::string validConstraintNames[] = { - "BC-name-1::hourly::hour<36>", - "BC-name-2::daily::day<67>", - "BC-name-3::weekly::week<12>", - "FictiveLoads::hour<25>", - "AreaHydroLevel::hour<8>", -}; +static const std::string validConstraintNames[] = {"BC-name-1::hourly::hour<36>", + "BC-name-2::daily::day<67>", + "BC-name-3::weekly::week<12>", + "FictiveLoads::area::hour<25>", + "AreaHydroLevel::area::hour<8>", + "Level::area::hour<28>", + "HydroPower::area::week<45>"}; BOOST_DATA_TEST_CASE(analysis_should_detect_unfeasible_constraint, bdata::make(validConstraintNames), From 6c3646b19459ce23cf41c8b40989fc30e2a877b0 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:06:15 +0200 Subject: [PATCH 079/127] Remove manual dynamic memory usage (#2254) Replaced new[] with vectors Made RunTimeInfos static --- src/api/API.cpp | 2 +- src/libs/antares/study/CMakeLists.txt | 1 - .../antares/study/progression/progression.h | 10 +-- .../include/antares/study/runtime/runtime.h | 12 ++- .../include/antares/study/runtime/runtime.hxx | 37 --------- .../study/include/antares/study/study.h | 4 +- .../antares/study/progression/progression.cpp | 2 +- src/libs/antares/study/runtime/runtime.cpp | 1 + src/libs/antares/study/study.cpp | 43 +++++----- src/libs/antares/study/study.importprepro.cpp | 2 +- .../application/ScenarioBuilderOwner.cpp | 2 +- src/solver/application/application.cpp | 3 +- src/solver/simulation/adequacy.cpp | 4 +- src/solver/simulation/common-eco-adq.cpp | 16 ++-- src/solver/simulation/economy.cpp | 2 +- .../solver/simulation/common-eco-adq.h | 2 +- .../antares/solver/simulation/solver.hxx | 49 ++++++----- .../antares/solver/simulation/solver_utils.h | 81 +++++-------------- .../simulation/sim_alloc_probleme_hebdo.cpp | 26 +++--- .../simulation/sim_allocation_tableaux.cpp | 4 +- .../simulation/sim_calcul_economique.cpp | 12 +-- src/solver/simulation/timeseries-numbers.cpp | 23 +++--- src/solver/ts-generator/hydro.cpp | 18 ++--- .../antares/solver/ts-generator/generator.hxx | 8 +- .../solver/variable/adequacy/overallCost.h | 2 +- .../variable/commons/spatial-aggregate.h | 2 +- .../solver/variable/economy/links/flowQuad.h | 2 +- .../variable/economy/nbOfDispatchedUnits.h | 4 +- .../economy/nbOfDispatchedUnitsByPlant.h | 6 +- .../variable/economy/nonProportionalCost.h | 4 +- .../economy/npCostByDispatchablePlant.h | 4 +- .../solver/variable/economy/operatingCost.h | 4 +- .../solver/variable/economy/overallCost.h | 4 +- .../economy/productionByDispatchablePlant.h | 2 +- .../antares/solver/variable/storage/average.h | 2 +- .../solver/variable/storage/averagedata.h | 2 +- .../antares/solver/variable/storage/raw.h | 2 +- .../antares/solver/variable/storage/rawdata.h | 2 +- src/solver/variable/state.cpp | 12 +-- src/solver/variable/storage/averagedata.cpp | 8 +- src/solver/variable/storage/intermediate.cpp | 4 +- src/solver/variable/storage/rawdata.cpp | 8 +- .../variable/surveyresults/surveyresults.cpp | 20 ++--- src/tests/inmemory-study/in-memory-study.cpp | 2 +- src/tests/src/api_internal/test_api.cpp | 2 +- .../src/libs/antares/study/test_study.cpp | 2 +- .../test-store-timeseries-number.cpp | 7 +- .../solver/simulation/test-time_series.cpp | 7 +- .../solver/simulation/tests-ts-numbers.cpp | 39 +++++---- src/tools/ts-generator/linksTSgenerator.cpp | 2 +- 50 files changed, 209 insertions(+), 310 deletions(-) delete mode 100644 src/libs/antares/study/include/antares/study/runtime/runtime.hxx diff --git a/src/api/API.cpp b/src/api/API.cpp index 38e9778eab..a76eb934ec 100644 --- a/src/api/API.cpp +++ b/src/api/API.cpp @@ -78,7 +78,7 @@ SimulationResults APIInternal::execute() const study_->parameters.resultFormat, study_->folderOutput, ioQueueService, durationCollector); SimulationObserver simulationObserver; // Run the simulation - switch (study_->runtime->mode) + switch (study_->runtime.mode) { case Data::SimulationMode::Economy: case Data::SimulationMode::Expansion: diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index 3ec77caaed..e9a05827ac 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -208,7 +208,6 @@ set(SRC_STUDY include/antares/study/load-options.h load-options.cpp include/antares/study/runtime/runtime.h - include/antares/study/runtime/runtime.hxx runtime/runtime.cpp include/antares/study/runtime.h include/antares/study/study.h diff --git a/src/libs/antares/study/include/antares/study/progression/progression.h b/src/libs/antares/study/include/antares/study/progression/progression.h index bcdeca82ac..5e013df957 100644 --- a/src/libs/antares/study/include/antares/study/progression/progression.h +++ b/src/libs/antares/study/include/antares/study/progression/progression.h @@ -76,11 +76,11 @@ class Progression final public: //! The total number of ticks to achieve - int maxTickCount; + unsigned maxTickCount; //! The current number of ticks - std::atomic tickCount; + std::atomic tickCount; //! The last number of ticks, to reduce the log verbosity - int lastTickCount; + unsigned lastTickCount; // Caption to use when displaying logs // Example: 'year: 10000, task: thermal' Yuni::CString<40, false> caption; @@ -104,7 +104,7 @@ class Progression final return *this; } - Task& operator+=(int value) + Task& operator+=(unsigned value) { pPart.tickCount += value; return *this; @@ -138,7 +138,7 @@ class Progression final ** \internal The number of ticks should remain an `int` because ** we can not use unsigned atomic integer */ - void add(uint year, Section section, int nbTicks); + void add(uint year, Section section, unsigned nbTicks); void add(Section section, int nbTicks); diff --git a/src/libs/antares/study/include/antares/study/runtime/runtime.h b/src/libs/antares/study/include/antares/study/runtime/runtime.h index 0ea07ce3bc..d87761674f 100644 --- a/src/libs/antares/study/include/antares/study/runtime/runtime.h +++ b/src/libs/antares/study/include/antares/study/runtime/runtime.h @@ -25,11 +25,13 @@ #include #include -#include "antares/study/study.h" +#include namespace Antares::Data { +class Study; + enum RangeLimitsIndex { rangeBegin = 0, @@ -139,8 +141,12 @@ class StudyRuntimeInfos void checkThermalTSGeneration(Study& study); }; // struct StudyRuntimeInfos -} // namespace Antares::Data +#ifdef NDEBUG +inline void StudyRangeLimits::checkIntegrity() const +{ +} +#endif -#include "runtime.hxx" +} // namespace Antares::Data #endif // __ANTARES_LIBS_STUDY_RUNTIME_RUNTIME_INFOS_H__ diff --git a/src/libs/antares/study/include/antares/study/runtime/runtime.hxx b/src/libs/antares/study/include/antares/study/runtime/runtime.hxx deleted file mode 100644 index 0e04ed3b93..0000000000 --- a/src/libs/antares/study/include/antares/study/runtime/runtime.hxx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ -#ifndef __ANTARES_LIBS_STUDY_RUNTIME_RUNTIME_INFOS_HXX__ -#define __ANTARES_LIBS_STUDY_RUNTIME_RUNTIME_INFOS_HXX__ - -namespace Antares -{ -namespace Data -{ -#ifdef NDEBUG -inline void StudyRangeLimits::checkIntegrity() const -{ -} -#endif - -} // namespace Data -} // namespace Antares - -#endif // __ANTARES_LIBS_STUDY_RUNTIME_RUNTIME_INFOS_HXX__ diff --git a/src/libs/antares/study/include/antares/study/study.h b/src/libs/antares/study/include/antares/study/study.h index 03e2df8bed..65f8f531fd 100644 --- a/src/libs/antares/study/include/antares/study/study.h +++ b/src/libs/antares/study/include/antares/study/study.h @@ -31,6 +31,7 @@ #include #include +#include #include #include "antares/antares/antares.h" #include "antares/study/binding_constraint/BindingConstraintGroupRepository.h" @@ -596,7 +597,7 @@ class Study: public Yuni::NonCopyable, public LayerData ** ** These informations are only needed when a study is processed. */ - StudyRuntimeInfos* runtime = nullptr; + StudyRuntimeInfos runtime; // Antares::Solver::Variable::State* state; @@ -690,7 +691,6 @@ YString StudyCreateOutputPath(SimulationMode mode, int64_t startTime); } // namespace Antares::Data -#include "runtime.h" #include "study.hxx" #endif /* __ANTARES_LIBS_STUDY_STUDY_H__ */ diff --git a/src/libs/antares/study/progression/progression.cpp b/src/libs/antares/study/progression/progression.cpp index a78c86959f..28c1d3288e 100644 --- a/src/libs/antares/study/progression/progression.cpp +++ b/src/libs/antares/study/progression/progression.cpp @@ -42,7 +42,7 @@ Progression::Task::Task(const Antares::Data::Study& study, uint year, Section se assert(&pProgression); } -void Progression::add(uint year, Section section, int nbTicks) +void Progression::add(uint year, Section section, unsigned nbTicks) { // This section is not thread-safe because always called before really launching // the simulation diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index 1bb7e46386..61be13d6cf 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -21,6 +21,7 @@ #include "antares/study/runtime/runtime.h" +#include #include #include "antares/antares/fatal-error.h" #include "antares/study/area/scratchpad.h" diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 5b1dde8c5f..01d91b3abb 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -104,8 +104,6 @@ Study::~Study() void Study::clear() { - // Releasing runtime infos - FreeAndNil(runtime); FreeAndNil(scenarioRules); FreeAndNil(uiinfo); @@ -504,9 +502,7 @@ void Study::getNumberOfCores(const bool forceParallel, const uint nbYearsParalle bool Study::initializeRuntimeInfos() { - delete runtime; - runtime = new StudyRuntimeInfos(); - return runtime->loadFromStudy(*this); + return runtime.loadFromStudy(*this); } void Study::performTransformationsBeforeLaunchingSimulation() @@ -1164,25 +1160,24 @@ struct TS final void Study::initializeProgressMeter(bool tsGeneratorOnly) { - uint years = tsGeneratorOnly ? 1 : (runtime->rangeLimits.year[rangeEnd] + 1); - assert(runtime); + uint years = tsGeneratorOnly ? 1 : (runtime.rangeLimits.year[rangeEnd] + 1); - int ticksPerYear = 0; - int ticksPerOutput = 0; + unsigned ticksPerYear = 0; + unsigned ticksPerOutput = 0; if (not tsGeneratorOnly) { // One tick at the begining and 2 at the end of the year // Output - Areas - ticksPerOutput += (int)areas.size(); + ticksPerOutput += areas.size(); // Output - Links - ticksPerOutput += (int)runtime->interconnectionsCount(); + ticksPerOutput += runtime.interconnectionsCount(); // Output - digest ticksPerOutput += 1; ticksPerYear = 1; } - int n; + unsigned n; for (uint y = 0; y != years; ++y) { @@ -1191,7 +1186,7 @@ void Study::initializeProgressMeter(bool tsGeneratorOnly) n = parameters.nbTimeSeriesLoad * areas.size() * 365; if (0 != (timeSeriesLoad & parameters.timeSeriesToArchive)) { - n += (int)areas.size(); + n += areas.size(); } progression.add(y, Solver::Progression::sectTSGLoad, n); } @@ -1200,7 +1195,7 @@ void Study::initializeProgressMeter(bool tsGeneratorOnly) n = parameters.nbTimeSeriesSolar * areas.size() * 365; if (0 != (timeSeriesSolar & parameters.timeSeriesToArchive)) { - n += (int)areas.size(); + n += areas.size(); } progression.add(y, Solver::Progression::sectTSGSolar, n); } @@ -1209,7 +1204,7 @@ void Study::initializeProgressMeter(bool tsGeneratorOnly) n = parameters.nbTimeSeriesWind * areas.size() * 365; if (0 != (timeSeriesWind & parameters.timeSeriesToArchive)) { - n += (int)areas.size(); + n += areas.size(); } progression.add(y, Solver::Progression::sectTSGWind, n); } @@ -1219,17 +1214,17 @@ void Study::initializeProgressMeter(bool tsGeneratorOnly) n = parameters.nbTimeSeriesHydro; if (0 != (timeSeriesHydro & parameters.timeSeriesToArchive)) { - n += (int)areas.size(); + n += areas.size(); } progression.add(y, Solver::Progression::sectTSGHydro, n); } if (TS::IsNeeded(*this, y)) { - n = runtime->thermalPlantTotalCount; + n = runtime.thermalPlantTotalCount; if (0 != (timeSeriesThermal & parameters.timeSeriesToArchive)) { - n += (int)runtime->thermalPlantTotalCount; - n += (int)runtime->thermalPlantTotalCountMustRun; + n += runtime.thermalPlantTotalCount; + n += runtime.thermalPlantTotalCountMustRun; } progression.add(y, Solver::Progression::sectTSGThermal, n); } @@ -1249,23 +1244,23 @@ void Study::initializeProgressMeter(bool tsGeneratorOnly) n = 0; if (0 != (timeSeriesLoad & parameters.exportTimeSeriesInInput)) { - n += (int)areas.size(); + n += areas.size(); } if (0 != (timeSeriesSolar & parameters.exportTimeSeriesInInput)) { - n += (int)areas.size(); + n += areas.size(); } if (0 != (timeSeriesWind & parameters.exportTimeSeriesInInput)) { - n += (int)areas.size(); + n += areas.size(); } if (0 != (timeSeriesHydro & parameters.exportTimeSeriesInInput)) { - n += (int)areas.size(); + n += areas.size(); } if (0 != (timeSeriesThermal & parameters.exportTimeSeriesInInput)) { - n += (int)areas.size(); + n += areas.size(); } if (n) { diff --git a/src/libs/antares/study/study.importprepro.cpp b/src/libs/antares/study/study.importprepro.cpp index f7c8082050..69a0fe058b 100644 --- a/src/libs/antares/study/study.importprepro.cpp +++ b/src/libs/antares/study/study.importprepro.cpp @@ -33,7 +33,7 @@ bool Study::importTimeseriesIntoInput() { // Special case: some thermal clusters may force TS generation const bool importThermal = parameters.haveToImport(timeSeriesThermal) - && runtime->thermalTSRefresh; + && runtime.thermalTSRefresh; // Something to import ? if ((parameters.exportTimeSeriesInInput && parameters.timeSeriesToGenerate) || importThermal) { diff --git a/src/solver/application/ScenarioBuilderOwner.cpp b/src/solver/application/ScenarioBuilderOwner.cpp index 69f9d11799..f2f0c90c7e 100644 --- a/src/solver/application/ScenarioBuilderOwner.cpp +++ b/src/solver/application/ScenarioBuilderOwner.cpp @@ -39,7 +39,7 @@ void Antares::Solver::ScenarioBuilderOwner::callScenarioBuilder() // We will resize all matrix related to the time-series numbers // This operation can be done once since the number of years is constant // for a single simulation - study_.resizeAllTimeseriesNumbers(1 + study_.runtime->rangeLimits.year[Data::rangeEnd]); + study_.resizeAllTimeseriesNumbers(1 + study_.runtime.rangeLimits.year[Data::rangeEnd]); if (not TimeSeriesNumbers::CheckNumberOfColumns(study_.areas)) { throw FatalError( diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index c65e849a15..334e8f86d7 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -224,7 +224,6 @@ void Application::readDataForTheStudy(Data::StudyLoadOptions& options) writeComment(study); } - // Runtime data dedicated for the solver if (!study.initializeRuntimeInfos()) { throw Error::RuntimeInfoInitialization(); @@ -391,7 +390,7 @@ void Application::execute() pStudy->computePThetaInfForThermalClusters(); // Run the simulation - switch (pStudy->runtime->mode) + switch (pStudy->runtime.mode) { case Data::SimulationMode::Economy: case Data::SimulationMode::Expansion: diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index f4759a0ab1..eed49029e8 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -258,7 +258,7 @@ bool Adequacy::year(Progression::Task& progression, state.resSpilled.zero(); auto nbAreas = study.areas.size(); - auto& runtime = *(study.runtime); + auto& runtime = study.runtime; for (uint i = 0; i != nbHoursInAWeek; ++i) { @@ -399,7 +399,7 @@ static std::vector retrieveBalance( void Adequacy::simulationEnd() { - if (!preproOnly && study.runtime->interconnectionsCount() > 0) + if (!preproOnly && study.runtime.interconnectionsCount() > 0) { auto balance = retrieveBalance(study, variables); ComputeFlowQuad(study, pProblemesHebdo[0], balance, pNbWeeks); diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index 27d2cdae6c..bfc697372a 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -60,9 +60,9 @@ static void RecalculDesEchangesMoyens(Data::Study& study, std::vector avgDirect; std::vector avgIndirect; - for (uint j = 0; j < study.runtime->interconnectionsCount(); ++j) + for (uint j = 0; j < study.runtime.interconnectionsCount(); ++j) { - auto* link = study.runtime->areaLink[j]; + auto* link = study.runtime.areaLink[j]; int ret = retrieveAverageNTC(study, link->directCapacities.timeSeries, link->timeseriesNumbers, @@ -100,7 +100,7 @@ static void RecalculDesEchangesMoyens(Data::Study& study, } catch (Data::UnfeasibleProblemError&) { - study.runtime->quadraticOptimizationHasFailed = true; + study.runtime.quadraticOptimizationHasFailed = true; } for (uint i = 0; i < (uint)problem.NombreDePasDeTemps; ++i) @@ -108,7 +108,7 @@ static void RecalculDesEchangesMoyens(Data::Study& study, const uint indx = i + PasDeTempsDebut; auto& ntcValues = problem.ValeursDeNTC[i]; - for (uint j = 0; j < study.runtime->interconnectionsCount(); ++j) + for (uint j = 0; j < study.runtime.interconnectionsCount(); ++j) { transitMoyenInterconnexionsRecalculQuadratique[j][indx] = ntcValues.ValeurDuFlux[j]; } @@ -123,9 +123,9 @@ bool ShouldUseQuadraticOptimisation(const Data::Study& study) return false; } - for (uint j = 0; j < study.runtime->interconnectionsCount(); ++j) + for (uint j = 0; j < study.runtime.interconnectionsCount(); ++j) { - auto& lnk = *(study.runtime->areaLink[j]); + auto& lnk = *(study.runtime.areaLink[j]); auto& impedances = lnk.parameters[Data::fhlImpedances]; for (uint hour = 0; hour < HOURS_PER_YEAR; ++hour) @@ -162,7 +162,7 @@ void ComputeFlowQuad(Data::Study& study, { logs.info() << " The quadratic optimisation has been skipped"; - for (uint j = 0; j < study.runtime->interconnectionsCount(); ++j) + for (uint j = 0; j < study.runtime.interconnectionsCount(); ++j) { for (uint w = 0; w != nbWeeks; ++w) { @@ -360,7 +360,7 @@ void SetInitialHydroLevel(Data::Study& study, void BuildThermalPartOfWeeklyProblem(Data::Study& study, PROBLEME_HEBDO& problem, const int PasDeTempsDebut, - double** thermalNoises, + std::vector>& thermalNoises, unsigned int year) { int hourInYear = PasDeTempsDebut; diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index f14d4cabf0..269fcd26ff 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -263,7 +263,7 @@ static std::vector retrieveBalance( void Economy::simulationEnd() { - if (!preproOnly && study.runtime->interconnectionsCount() > 0) + if (!preproOnly && study.runtime.interconnectionsCount() > 0) { auto balance = retrieveBalance(study, variables); ComputeFlowQuad(study, pProblemesHebdo[0], balance, pNbWeeks); diff --git a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h index 0bf24cd71d..1139bb9ff9 100644 --- a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h +++ b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h @@ -63,7 +63,7 @@ void SetInitialHydroLevel(Data::Study& study, void BuildThermalPartOfWeeklyProblem(Data::Study& study, PROBLEME_HEBDO& problem, const int PasDeTempsDebut, - double** thermalNoises, + std::vector>& thermalNoises, unsigned int year); /*! diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 1aa04cb38f..539c1d298e 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -146,10 +146,9 @@ public: // Getting random tables for this year yearRandomNumbers& randomForCurrentYear = randomForParallelYears.pYears[indexYear]; - double* randomReservoirLevel = nullptr; // 1 - Applying random levels for current year - randomReservoirLevel = randomForCurrentYear.pReservoirLevels; + auto randomReservoirLevel = randomForCurrentYear.pReservoirLevels; // 2 - Preparing the Time-series numbers // removed @@ -159,7 +158,7 @@ public: // 4 - Hydraulic ventilation pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] - { hydroManagement.makeVentilation(randomReservoirLevel, y, scratchmap); }; + { hydroManagement.makeVentilation(randomReservoirLevel.data(), y, scratchmap); }; // Updating the state state.year = y; @@ -326,9 +325,9 @@ void ISimulation::run() logs.info(); // Launching the simulation for all years - logs.info() << "MC-Years : [" << (study.runtime->rangeLimits.year[Data::rangeBegin] + 1) - << " .. " << (1 + study.runtime->rangeLimits.year[Data::rangeEnd]) - << "], total: " << study.runtime->rangeLimits.year[Data::rangeCount]; + logs.info() << "MC-Years : [" << (study.runtime.rangeLimits.year[Data::rangeBegin] + 1) + << " .. " << (1 + study.runtime.rangeLimits.year[Data::rangeEnd]) + << "], total: " << study.runtime.rangeLimits.year[Data::rangeCount]; // Current state std::vector state(pNbMaxPerformedYearsInParallel, Variable::State(study)); @@ -338,7 +337,7 @@ void ISimulation::run() ImplementationType::initializeState(state[numSpace], numSpace); } - uint finalYear = 1 + study.runtime->rangeLimits.year[Data::rangeEnd]; + uint finalYear = 1 + study.runtime.rangeLimits.year[Data::rangeEnd]; { pDurationCollector("mc_years") << [finalYear, &state, this] { loopThroughYears(0, finalYear, state); }; @@ -456,7 +455,7 @@ void ISimulation::regenerateTimeSeries(uint year) auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); generateThermalTimeSeries(study, clusters, - study.runtime->random[Data::seedTsGenThermal]); + study.runtime.random[Data::seedTsGenThermal]); bool archive = study.parameters.timeSeriesToArchive & Data::timeSeriesThermal; bool doWeWrite = archive && !study.parameters.noOutput; @@ -512,7 +511,7 @@ uint ISimulation::buildSetsOfParallelYears( // Some thermal clusters may override the global parameter. // Therefore, we may want to refresh TS even if pData.haveToRefreshTSThermal == false bool haveToRefreshTSThermal = pData.haveToRefreshTSThermal - || study.runtime->thermalTSRefresh; + || study.runtime.thermalTSRefresh; refreshing = refreshing || (haveToRefreshTSThermal && (y % pData.refreshIntervalThermal == 0)); @@ -606,43 +605,43 @@ void ISimulation::allocateMemoryForRandomNumbers( { // General : randomForParallelYears.pYears[y].setNbAreas(nbAreas); - randomForParallelYears.pYears[y].pNbClustersByArea = new size_t[nbAreas]; + randomForParallelYears.pYears[y].pNbClustersByArea.resize(nbAreas); // Thermal noises : - randomForParallelYears.pYears[y].pThermalNoisesByArea = new double*[nbAreas]; + randomForParallelYears.pYears[y].pThermalNoisesByArea.resize(nbAreas); for (uint a = 0; a != nbAreas; ++a) { // logs.info() << " area : " << a << " :"; auto& area = *(study.areas.byIndex[a]); size_t nbClusters = area.thermal.list.allClustersCount(); - randomForParallelYears.pYears[y].pThermalNoisesByArea[a] = new double[nbClusters]; + randomForParallelYears.pYears[y].pThermalNoisesByArea[a].resize(nbClusters); randomForParallelYears.pYears[y].pNbClustersByArea[a] = nbClusters; } // Reservoir levels - randomForParallelYears.pYears[y].pReservoirLevels = new double[nbAreas]; + randomForParallelYears.pYears[y].pReservoirLevels.resize(nbAreas); // Noises on unsupplied and spilled energy - randomForParallelYears.pYears[y].pUnsuppliedEnergy = new double[nbAreas]; - randomForParallelYears.pYears[y].pSpilledEnergy = new double[nbAreas]; + randomForParallelYears.pYears[y].pUnsuppliedEnergy.resize(nbAreas); + randomForParallelYears.pYears[y].pSpilledEnergy.resize(nbAreas); // Hydro costs noises switch (study.parameters.power.fluctuations) { case Data::lssFreeModulations: { - randomForParallelYears.pYears[y].pHydroCostsByArea_freeMod = new double*[nbAreas]; + randomForParallelYears.pYears[y].pHydroCostsByArea_freeMod.resize(nbAreas); for (uint a = 0; a != nbAreas; ++a) { - randomForParallelYears.pYears[y].pHydroCostsByArea_freeMod[a] = new double[8784]; + randomForParallelYears.pYears[y].pHydroCostsByArea_freeMod[a].resize(8784); } break; } case Data::lssMinimizeRamping: case Data::lssMinimizeExcursions: { - randomForParallelYears.pYears[y].pHydroCosts_rampingOrExcursion = new double[nbAreas]; + randomForParallelYears.pYears[y].pHydroCosts_rampingOrExcursion.resize(nbAreas); break; } case Data::lssUnknown: @@ -661,8 +660,6 @@ void ISimulation::computeRandomNumbers( std::map& isYearPerformed, MersenneTwister& randomHydroGenerator) { - auto& runtime = *study.runtime; - uint indexYear = 0; std::vector::iterator ity; @@ -687,7 +684,7 @@ void ISimulation::computeRandomNumbers( for (auto& cluster: area.thermal.list.all()) { uint clusterIndex = cluster->areaWideIndex; - double thermalNoise = runtime.random[Data::seedThermalCosts].next(); + double thermalNoise = study.runtime.random[Data::seedThermalCosts].next(); if (isPerformed) { randomForYears.pYears[indexYear].pThermalNoisesByArea[a][clusterIndex] @@ -746,8 +743,8 @@ void ISimulation::computeRandomNumbers( // ... Unsupplied and spilled energy costs noises (french : bruits sur la defaillance // positive et negatives) ... references to the random number generators - auto& randomUnsupplied = study.runtime->random[Data::seedUnsuppliedEnergyCosts]; - auto& randomSpilled = study.runtime->random[Data::seedSpilledEnergyCosts]; + auto& randomUnsupplied = study.runtime.random[Data::seedUnsuppliedEnergyCosts]; + auto& randomSpilled = study.runtime.random[Data::seedSpilledEnergyCosts]; int currentSpilledEnergySeed = study.parameters.seed[Data::seedSpilledEnergyCosts]; int defaultSpilledEnergySeed = Data::antaresSeedDefaultValue @@ -787,7 +784,7 @@ void ISimulation::computeRandomNumbers( }); // each area // ... Hydro costs noises ... - auto& randomHydro = study.runtime->random[Data::seedHydroCosts]; + auto& randomHydro = study.runtime.random[Data::seedHydroCosts]; Data::PowerFluctuations powerFluctuations = study.parameters.power.fluctuations; switch (powerFluctuations) @@ -803,8 +800,8 @@ void ISimulation::computeRandomNumbers( { for (auto i = study.areas.begin(); i != end; ++i) { - double* noise = randomForYears.pYears[indexYear] - .pHydroCostsByArea_freeMod[areaIndex]; + auto& noise = randomForYears.pYears[indexYear] + .pHydroCostsByArea_freeMod[areaIndex]; std::set setHydroCostsNoises; for (uint j = 0; j != 8784; ++j) { diff --git a/src/solver/simulation/include/antares/solver/simulation/solver_utils.h b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h index 363b7839f8..d0d8748034 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver_utils.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h @@ -118,52 +118,10 @@ class yearRandomNumbers public: yearRandomNumbers() { - pThermalNoisesByArea = nullptr; - pNbClustersByArea = nullptr; pNbAreas = 0; } - ~yearRandomNumbers() - { - // General - delete[] pNbClustersByArea; - - // Thermal noises - for (uint a = 0; a != pNbAreas; a++) - { - delete[] pThermalNoisesByArea[a]; - } - delete[] pThermalNoisesByArea; - - // Reservoir levels, spilled and unsupplied energy - delete[] pReservoirLevels; - delete[] pUnsuppliedEnergy; - delete[] pSpilledEnergy; - - // Hydro costs noises - switch (pPowerFluctuations) - { - case Data::lssFreeModulations: - { - for (uint a = 0; a != pNbAreas; a++) - { - delete[] pHydroCostsByArea_freeMod[a]; - } - delete[] pHydroCostsByArea_freeMod; - break; - } - - case Data::lssMinimizeRamping: - case Data::lssMinimizeExcursions: - { - delete[] pHydroCosts_rampingOrExcursion; - break; - } - - case Data::lssUnknown: - break; - } - } + ~yearRandomNumbers() = default; void setNbAreas(uint nbAreas) { @@ -178,18 +136,18 @@ class yearRandomNumbers void reset() { // General - memset(pNbClustersByArea, 0, pNbAreas * sizeof(size_t)); + pNbClustersByArea.assign(pNbAreas, 0); // Thermal noises for (uint a = 0; a != pNbAreas; a++) { - memset(pThermalNoisesByArea[a], 0, pNbClustersByArea[a] * sizeof(double)); + pThermalNoisesByArea[a].assign(pNbClustersByArea[a], 0); } // Reservoir levels, spilled and unsupplied energy costs - memset(pReservoirLevels, 0, pNbAreas * sizeof(double)); - memset(pUnsuppliedEnergy, 0, pNbAreas * sizeof(double)); - memset(pSpilledEnergy, 0, pNbAreas * sizeof(double)); + pReservoirLevels.assign(pNbAreas, 0); + pUnsuppliedEnergy.assign(pNbAreas, 0); + pSpilledEnergy.assign(pNbAreas, 0); // Hydro costs noises switch (pPowerFluctuations) @@ -198,7 +156,7 @@ class yearRandomNumbers { for (uint a = 0; a != pNbAreas; a++) { - memset(pHydroCostsByArea_freeMod[a], 0, 8784 * sizeof(double)); + pHydroCostsByArea_freeMod[a].assign(8784, 0); } break; } @@ -206,7 +164,7 @@ class yearRandomNumbers case Data::lssMinimizeRamping: case Data::lssMinimizeExcursions: { - memset(pHydroCosts_rampingOrExcursion, 0, pNbAreas * sizeof(double)); + pHydroCosts_rampingOrExcursion.assign(pNbAreas, 0); break; } @@ -220,19 +178,19 @@ class yearRandomNumbers Data::PowerFluctuations pPowerFluctuations; // Data for thermal noises - double** pThermalNoisesByArea; - size_t* pNbClustersByArea; + std::vector> pThermalNoisesByArea; + std::vector pNbClustersByArea; // Data for reservoir levels - double* pReservoirLevels; + std::vector pReservoirLevels; // Data for unsupplied and spilled energy costs - double* pUnsuppliedEnergy; - double* pSpilledEnergy; + std::vector pUnsuppliedEnergy; + std::vector pSpilledEnergy; // Hydro costs noises - double** pHydroCostsByArea_freeMod; - double* pHydroCosts_rampingOrExcursion; + std::vector> pHydroCostsByArea_freeMod; + std::vector pHydroCosts_rampingOrExcursion; }; class randomNumbers @@ -242,7 +200,7 @@ class randomNumbers pMaxNbPerformedYears(maxNbPerformedYearsInAset) { // Allocate a table of parallel years structures - pYears = new yearRandomNumbers[maxNbPerformedYearsInAset]; + pYears.resize(maxNbPerformedYearsInAset); // Tells these structures their power fluctuations mode for (uint y = 0; y < maxNbPerformedYearsInAset; ++y) @@ -251,10 +209,7 @@ class randomNumbers } } - ~randomNumbers() - { - delete[] pYears; - } + ~randomNumbers() = default; void reset() { @@ -267,7 +222,7 @@ class randomNumbers } uint pMaxNbPerformedYears; - yearRandomNumbers* pYears; + std::vector pYears; // Associates : // year number (0, ..., total nb of years to compute - 1) --> index of the year's space diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index 03126fa752..936a8e5ac0 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -39,7 +39,7 @@ void SIM_AllocationProblemeHebdo(const Data::Study& study, { SIM_AllocationProblemeDonneesGenerales(problem, study, NombreDePasDeTemps); SIM_AllocationProblemePasDeTemps(problem, study, NombreDePasDeTemps); - SIM_AllocationLinks(problem, study.runtime->interconnectionsCount(), NombreDePasDeTemps); + SIM_AllocationLinks(problem, study.runtime.interconnectionsCount(), NombreDePasDeTemps); SIM_AllocationConstraints(problem, study, NombreDePasDeTemps); SIM_AllocateAreas(problem, study, NombreDePasDeTemps); } @@ -55,7 +55,7 @@ void SIM_AllocationProblemeDonneesGenerales(PROBLEME_HEBDO& problem, { uint nbPays = study.areas.size(); - const uint linkCount = study.runtime->interconnectionsCount(); + const uint linkCount = study.runtime.interconnectionsCount(); problem.DefaillanceNegativeUtiliserPMinThermique.assign(nbPays, false); problem.DefaillanceNegativeUtiliserHydro.assign(nbPays, false); @@ -132,8 +132,8 @@ void SIM_AllocationProblemePasDeTemps(PROBLEME_HEBDO& problem, { uint nbPays = study.areas.size(); - const uint linkCount = study.runtime->interconnectionsCount(); - const uint shortTermStorageCount = study.runtime->shortTermStorageCount; + const uint linkCount = study.runtime.interconnectionsCount(); + const uint shortTermStorageCount = study.runtime.shortTermStorageCount; auto activeConstraints = study.bindingConstraints.activeConstraints(); @@ -159,7 +159,7 @@ void SIM_AllocationProblemePasDeTemps(PROBLEME_HEBDO& problem, 0); variablesMapping.NumeroDeVariableDuPalierThermique - .assign(study.runtime->thermalPlantTotalCount, 0); + .assign(study.runtime.thermalPlantTotalCount, 0); variablesMapping.NumeroDeVariablesDeLaProdHyd.assign(nbPays, 0); variablesMapping.NumeroDeVariablesDePompage.assign(nbPays, 0); variablesMapping.NumeroDeVariablesDeNiveau.assign(nbPays, 0); @@ -172,13 +172,13 @@ void SIM_AllocationProblemePasDeTemps(PROBLEME_HEBDO& problem, variablesMapping.NumeroDeVariablesVariationHydALaHausse.assign(nbPays, 0); variablesMapping.NumeroDeVariableDuNombreDeGroupesEnMarcheDuPalierThermique - .assign(study.runtime->thermalPlantTotalCount, 0); + .assign(study.runtime.thermalPlantTotalCount, 0); variablesMapping.NumeroDeVariableDuNombreDeGroupesQuiDemarrentDuPalierThermique - .assign(study.runtime->thermalPlantTotalCount, 0); + .assign(study.runtime.thermalPlantTotalCount, 0); variablesMapping.NumeroDeVariableDuNombreDeGroupesQuiSArretentDuPalierThermique - .assign(study.runtime->thermalPlantTotalCount, 0); + .assign(study.runtime.thermalPlantTotalCount, 0); variablesMapping.NumeroDeVariableDuNombreDeGroupesQuiTombentEnPanneDuPalierThermique - .assign(study.runtime->thermalPlantTotalCount, 0); + .assign(study.runtime.thermalPlantTotalCount, 0); variablesMapping.SIM_ShortTermStorage.InjectionVariable.assign(shortTermStorageCount, 0); variablesMapping.SIM_ShortTermStorage.WithdrawalVariable.assign(shortTermStorageCount, 0); @@ -205,14 +205,14 @@ void SIM_AllocationProblemePasDeTemps(PROBLEME_HEBDO& problem, problem.CorrespondanceCntNativesCntOptim[k] .NumeroDeContrainteDesContraintesDeDureeMinDeMarche - .assign(study.runtime->thermalPlantTotalCount, 0); + .assign(study.runtime.thermalPlantTotalCount, 0); problem.CorrespondanceCntNativesCntOptim[k] .NumeroDeContrainteDesContraintesDeDureeMinDArret - .assign(study.runtime->thermalPlantTotalCount, 0); + .assign(study.runtime.thermalPlantTotalCount, 0); problem.CorrespondanceCntNativesCntOptim[k] .NumeroDeLaDeuxiemeContrainteDesContraintesDesGroupesQuiTombentEnPanne - .assign(study.runtime->thermalPlantTotalCount, 0); + .assign(study.runtime.thermalPlantTotalCount, 0); problem.VariablesDualesDesContraintesDeNTC[k] .VariableDualeParInterconnexion.assign(linkCount, 0.); @@ -278,7 +278,7 @@ void SIM_AllocationConstraints(PROBLEME_HEBDO& problem, problem.MatriceDesContraintesCouplantes[constraintIndex] .PaysDuPalierDispatch.assign(bc->clusterCount(), 0); - // TODO : create a numberOfTimeSteps method in class of runtime->bindingConstraint + // TODO : create a numberOfTimeSteps method in class of runtime.bindingConstraint unsigned int nbTimeSteps; switch (bc->type()) { diff --git a/src/solver/simulation/sim_allocation_tableaux.cpp b/src/solver/simulation/sim_allocation_tableaux.cpp index 4b8674639d..ef788dfedd 100644 --- a/src/solver/simulation/sim_allocation_tableaux.cpp +++ b/src/solver/simulation/sim_allocation_tableaux.cpp @@ -29,9 +29,9 @@ using namespace Antares; void SIM_AllocationTableaux(const Data::Study& study) { - transitMoyenInterconnexionsRecalculQuadratique.resize(study.runtime->interconnectionsCount()); + transitMoyenInterconnexionsRecalculQuadratique.resize(study.runtime.interconnectionsCount()); - for (uint i = 0; i != study.runtime->interconnectionsCount(); i++) + for (uint i = 0; i != study.runtime.interconnectionsCount(); i++) { transitMoyenInterconnexionsRecalculQuadratique[i].assign(HOURS_PER_YEAR, 0.); } diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 2402ddd548..9fd210f1fd 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -87,7 +87,7 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, { problem.adequacyPatchRuntimeData = std::make_shared( study.areas, - study.runtime->areaLink); + study.runtime.areaLink); } problem.WaterValueAccurate = (study.parameters.hydroPricing.hpMode @@ -101,9 +101,9 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, problem.NombreDePays = study.areas.size(); - problem.NombreDInterconnexions = study.runtime->interconnectionsCount(); + problem.NombreDInterconnexions = study.runtime.interconnectionsCount(); - problem.NumberOfShortTermStorages = study.runtime->shortTermStorageCount; + problem.NumberOfShortTermStorages = study.runtime.shortTermStorageCount; auto activeConstraints = study.bindingConstraints.activeConstraints(); problem.NombreDeContraintesCouplantes = activeConstraints.size(); @@ -219,9 +219,9 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, importShortTermStorages(study.areas, problem.ShortTermStorage); - for (uint i = 0; i < study.runtime->interconnectionsCount(); ++i) + for (uint i = 0; i < study.runtime.interconnectionsCount(); ++i) { - auto& link = *(study.runtime->areaLink[i]); + auto& link = *(study.runtime.areaLink[i]); problem.PaysOrigineDeLInterconnexion[i] = link.from->index; problem.PaysExtremiteDeLInterconnexion[i] = link.with->index; } @@ -411,7 +411,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, { const auto& parameters = study.parameters; - auto& studyruntime = *study.runtime; + auto& studyruntime = study.runtime; const uint nbPays = study.areas.size(); const size_t pasDeTempsSizeDouble = problem.NombreDePasDeTemps * sizeof(double); diff --git a/src/solver/simulation/timeseries-numbers.cpp b/src/solver/simulation/timeseries-numbers.cpp index 446a0efa08..fecb8ba4eb 100644 --- a/src/solver/simulation/timeseries-numbers.cpp +++ b/src/solver/simulation/timeseries-numbers.cpp @@ -475,7 +475,7 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i if (!isTSintramodal[indexTS]) { area.load.series.timeseriesNumbers[year] = (uint32_t)(floor( - study.runtime->random[seedTimeseriesNumbers].next() + study.runtime.random[seedTimeseriesNumbers].next() * area.load.series.timeSeries.width)); } @@ -487,7 +487,7 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i if (!isTSintramodal[indexTS]) { area.solar.series.timeseriesNumbers[year] = (uint32_t)(floor( - study.runtime->random[seedTimeseriesNumbers].next() + study.runtime.random[seedTimeseriesNumbers].next() * area.solar.series.timeSeries.width)); } @@ -499,7 +499,7 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i if (!isTSintramodal[indexTS]) { area.wind.series.timeseriesNumbers[year] = (uint32_t)(floor( - study.runtime->random[seedTimeseriesNumbers].next() + study.runtime.random[seedTimeseriesNumbers].next() * area.wind.series.timeSeries.width)); } @@ -511,8 +511,7 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i if (!isTSintramodal[indexTS]) { area.hydro.series->timeseriesNumbers[year] = (uint32_t)(floor( - study.runtime->random[seedTimeseriesNumbers].next() - * area.hydro.series->TScount())); + study.runtime.random[seedTimeseriesNumbers].next() * area.hydro.series->TScount())); } // ------------- @@ -524,14 +523,14 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i { if (!cluster->enabled) { - study.runtime->random[seedTimeseriesNumbers].next(); + study.runtime.random[seedTimeseriesNumbers].next(); } else { if (!isTSintramodal[indexTS]) { cluster->series.timeseriesNumbers[year] = (uint32_t)(floor( - study.runtime->random[seedTimeseriesNumbers].next() + study.runtime.random[seedTimeseriesNumbers].next() * cluster->series.timeSeries.width)); } } @@ -549,7 +548,7 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i // There is no TS generation for renewable clusters uint nbTimeSeries = cluster->series.timeSeries.width; cluster->series.timeseriesNumbers[year] = (uint32_t)(floor( - study.runtime->random[seedTimeseriesNumbers].next() * nbTimeSeries)); + study.runtime.random[seedTimeseriesNumbers].next() * nbTimeSeries)); } } @@ -567,7 +566,7 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i if (nbTimeSeries > 1) { link.timeseriesNumbers[year] = (uint32_t)(floor( - study.runtime->random[seedTimeseriesNumbers].next() * nbTimeSeries)); + study.runtime.random[seedTimeseriesNumbers].next() * nbTimeSeries)); } } } @@ -579,7 +578,7 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i auto& groupTsNumber = group->timeseriesNumbers[year]; if (nbTimeSeries > 1) { - groupTsNumber = (uint32_t)(floor(study.runtime->random[seedTimeseriesNumbers].next() + groupTsNumber = (uint32_t)(floor(study.runtime.random[seedTimeseriesNumbers].next() * nbTimeSeries)); } } @@ -753,7 +752,7 @@ bool TimeSeriesNumbers::Generate(Study& study) return GenerateDeratedMode(study); } - const uint years = 1 + study.runtime->rangeLimits.year[rangeEnd]; + const uint years = 1 + study.runtime.rangeLimits.year[rangeEnd]; const array isTSintramodal = { (bool)(timeSeriesLoad & parameters.intraModal), @@ -783,7 +782,7 @@ bool TimeSeriesNumbers::Generate(Study& study) drawTSnumbersForIntraModal(intramodal_draws, isTSintramodal, nbTimeseriesByMode, - study.runtime->random); + study.runtime.random); storeTSnumbersForIntraModal(intramodal_draws, isTSintramodal, year, study.areas); // NOT intra-modal TS : draw and store TS numbers diff --git a/src/solver/ts-generator/hydro.cpp b/src/solver/ts-generator/hydro.cpp index 2d31f08b22..168b290dfb 100644 --- a/src/solver/ts-generator/hydro.cpp +++ b/src/solver/ts-generator/hydro.cpp @@ -63,7 +63,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu Solver::Progression::Task progression(study, currentYear, Solver::Progression::sectTSGHydro); - auto& studyRTI = *(study.runtime); + auto& studyRTI = study.runtime; auto& calendar = study.calendar; uint DIM = MONTHS_PER_YEAR * study.areas.size(); @@ -72,7 +72,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu Matrix CHSKY; CHSKY.reset(DIM, DIM); - double* QCHOLTemp = new double[DIM]; + std::vector QCHOLTemp(DIM); Matrix B; B.reset(DIM, DIM); @@ -84,7 +84,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu B.entry, nullmatrx, study.areas.size(), - QCHOLTemp, + QCHOLTemp.data(), true)) { throw FatalError("TS Generator: Hydro: Invalid correlation matrix"); @@ -122,7 +122,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu B.entry, nullmatrx, DIM, - QCHOLTemp, + QCHOLTemp.data(), true); if (r < 1.) { @@ -134,15 +134,13 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu } } - Solver::Cholesky(CHSKY.entry, B.entry, DIM, QCHOLTemp); + Solver::Cholesky(CHSKY.entry, B.entry, DIM, QCHOLTemp.data()); B.clear(); CORRE.clear(); + QCHOLTemp.clear(); - delete[] QCHOLTemp; - QCHOLTemp = nullptr; - - double* NORM = new double[DIM]; + std::vector NORM(DIM); for (uint i = 0; i != DIM; ++i) { NORM[i] = 0.; @@ -308,8 +306,6 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu } } - delete[] NORM; - return true; } diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.hxx b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.hxx index 6596a4f7ab..7455c1accc 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.hxx +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.hxx @@ -58,16 +58,16 @@ bool GenerateTimeSeries(Data::Study& study, uint year, IResultWriter& writer) switch (T) { case Data::timeSeriesLoad: - xcast->random = &(study.runtime->random[Data::seedTsGenLoad]); + xcast->random = &(study.runtime.random[Data::seedTsGenLoad]); break; case Data::timeSeriesSolar: - xcast->random = &(study.runtime->random[Data::seedTsGenSolar]); + xcast->random = &(study.runtime.random[Data::seedTsGenSolar]); break; case Data::timeSeriesWind: - xcast->random = &(study.runtime->random[Data::seedTsGenWind]); + xcast->random = &(study.runtime.random[Data::seedTsGenWind]); break; case Data::timeSeriesHydro: - xcast->random = &(study.runtime->random[Data::seedTsGenHydro]); + xcast->random = &(study.runtime.random[Data::seedTsGenHydro]); break; default: xcast->random = nullptr; diff --git a/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h b/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h index f730a3d865..3bdcee903b 100644 --- a/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h +++ b/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h @@ -194,7 +194,7 @@ class OverallCost: public Variable::IVariable, NextT, VCardOv void yearEndBuildForEachThermalCluster(State& state, uint year, unsigned int numSpace) { // Get end year calculations - for (unsigned int i = 0; i < state.study.runtime->rangeLimits.hour[Data::rangeCount]; ++i) + for (unsigned int i = 0; i < state.study.runtime.rangeLimits.hour[Data::rangeCount]; ++i) { pValuesForTheCurrentYear[numSpace][i] += state.thermalClusterOperatingCostForYear[i]; } diff --git a/src/solver/variable/include/antares/solver/variable/commons/spatial-aggregate.h b/src/solver/variable/include/antares/solver/variable/commons/spatial-aggregate.h index ea966c4977..851dbb9999 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/spatial-aggregate.h +++ b/src/solver/variable/include/antares/solver/variable/commons/spatial-aggregate.h @@ -221,7 +221,7 @@ class SpatialAggregate VariableAccessorType::InitializeAndReset(pValuesForTheCurrentYear[numSpace], study); } - auto& limits = study.runtime->rangeLimits; + auto& limits = study.runtime.rangeLimits; pRatioYear = 100. / (double)limits.year[Data::rangeCount]; pRatioDay = 100. / (double)limits.day[Data::rangeCount]; diff --git a/src/solver/variable/include/antares/solver/variable/economy/links/flowQuad.h b/src/solver/variable/include/antares/solver/variable/economy/links/flowQuad.h index b7d00a3fb8..b6de8329ae 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/links/flowQuad.h +++ b/src/solver/variable/include/antares/solver/variable/economy/links/flowQuad.h @@ -129,7 +129,7 @@ class FlowQuad: public Variable::IVariable, NextT, VCardFlowQuad void initializeFromStudy(Data::Study& study) { // Average on all years - pNbHours = study.runtime->rangeLimits.hour[Data::rangeEnd] + 1; + pNbHours = study.runtime.rangeLimits.hour[Data::rangeEnd] + 1; AncestorType::pResults.initializeFromStudy(study); AncestorType::pResults.reset(); diff --git a/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnits.h b/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnits.h index a2af682a67..173343f61f 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnits.h +++ b/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnits.h @@ -198,8 +198,8 @@ class NbOfDispatchedUnits void yearEndBuildForEachThermalCluster(State& state, uint year, unsigned int numSpace) { // Get end year calculations - for (unsigned int i = state.study.runtime->rangeLimits.hour[Data::rangeBegin]; - i <= state.study.runtime->rangeLimits.hour[Data::rangeEnd]; + for (unsigned int i = state.study.runtime.rangeLimits.hour[Data::rangeBegin]; + i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i) { pValuesForTheCurrentYear[numSpace][i] += state.thermalClusterDispatchedUnitsCountForYear diff --git a/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h b/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h index 2bc519a94c..37f19ea3d6 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h @@ -234,7 +234,7 @@ class NbOfDispatchedUnitsByPlant: public Variable::IVariablerangeLimits.hour[Data::rangeEnd]; ++i) + for (unsigned int i = 0; i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i) { state.thermalClusterDispatchedUnitsCountForYear[i] += static_cast( pValuesForTheCurrentYear[numSpace][state.thermalCluster->areaWideIndex].hour[i]); @@ -247,8 +247,8 @@ class NbOfDispatchedUnitsByPlant: public Variable::IVariablerangeLimits.hour[Data::rangeBegin]; - i <= state.study.runtime->rangeLimits.hour[Data::rangeEnd]; + for (unsigned int i = state.study.runtime.rangeLimits.hour[Data::rangeBegin]; + i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i) { pValuesForTheCurrentYear[numSpace][state.thermalCluster->areaWideIndex].hour[i] diff --git a/src/solver/variable/include/antares/solver/variable/economy/nonProportionalCost.h b/src/solver/variable/include/antares/solver/variable/economy/nonProportionalCost.h index be8436d29a..8d26594739 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/nonProportionalCost.h +++ b/src/solver/variable/include/antares/solver/variable/economy/nonProportionalCost.h @@ -198,8 +198,8 @@ class NonProportionalCost void yearEndBuildForEachThermalCluster(State& state, uint year, unsigned int numSpace) { // Get end year calculations - for (unsigned int i = state.study.runtime->rangeLimits.hour[Data::rangeBegin]; - i <= state.study.runtime->rangeLimits.hour[Data::rangeEnd]; + for (unsigned int i = state.study.runtime.rangeLimits.hour[Data::rangeBegin]; + i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i) { pValuesForTheCurrentYear[numSpace][i] += state diff --git a/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h index b0587d51a2..79304684b3 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h @@ -236,8 +236,8 @@ class NonProportionalCostByDispatchablePlant void yearEndBuildForEachThermalCluster(State& state, uint year, unsigned int numSpace) { // Get end year calculations - for (unsigned int i = state.study.runtime->rangeLimits.hour[Data::rangeBegin]; - i <= state.study.runtime->rangeLimits.hour[Data::rangeEnd]; + for (unsigned int i = state.study.runtime.rangeLimits.hour[Data::rangeBegin]; + i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i) { pValuesForTheCurrentYear[numSpace][state.thermalCluster->areaWideIndex].hour[i] diff --git a/src/solver/variable/include/antares/solver/variable/economy/operatingCost.h b/src/solver/variable/include/antares/solver/variable/economy/operatingCost.h index 0df88e6711..df95f6d65c 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/operatingCost.h +++ b/src/solver/variable/include/antares/solver/variable/economy/operatingCost.h @@ -196,8 +196,8 @@ class OperatingCost: public Variable::IVariable, NextT, VCa void yearEndBuildForEachThermalCluster(State& state, uint year, unsigned int numSpace) { // Get end year calculations - for (unsigned int i = state.study.runtime->rangeLimits.hour[Data::rangeBegin]; - i <= state.study.runtime->rangeLimits.hour[Data::rangeEnd]; + for (unsigned int i = state.study.runtime.rangeLimits.hour[Data::rangeBegin]; + i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i) { pValuesForTheCurrentYear[numSpace][i] += state.thermalClusterOperatingCostForYear[i]; diff --git a/src/solver/variable/include/antares/solver/variable/economy/overallCost.h b/src/solver/variable/include/antares/solver/variable/economy/overallCost.h index 43c13f6620..ccb6632e9e 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/overallCost.h +++ b/src/solver/variable/include/antares/solver/variable/economy/overallCost.h @@ -194,8 +194,8 @@ class OverallCost: public Variable::IVariable, NextT, VCardOv void yearEndBuildForEachThermalCluster(State& state, uint year, unsigned int numSpace) { // Get end year calculations - for (unsigned int i = state.study.runtime->rangeLimits.hour[Data::rangeBegin]; - i <= state.study.runtime->rangeLimits.hour[Data::rangeEnd]; + for (unsigned int i = state.study.runtime.rangeLimits.hour[Data::rangeBegin]; + i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i) { pValuesForTheCurrentYear[numSpace][i] += state.thermalClusterOperatingCostForYear[i]; diff --git a/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h index 2e401844eb..b54245b644 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h @@ -255,7 +255,7 @@ class ProductionByDispatchablePlant uint year, unsigned int numSpace) { - for (unsigned int i = 0; i <= state.study.runtime->rangeLimits.hour[Data::rangeEnd]; ++i) + for (unsigned int i = 0; i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i) { state.thermalClusterProductionForYear[i] += pValuesForTheCurrentYear [numSpace] diff --git a/src/solver/variable/include/antares/solver/variable/storage/average.h b/src/solver/variable/include/antares/solver/variable/storage/average.h index 380915e284..fbeaf16a5b 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/average.h +++ b/src/solver/variable/include/antares/solver/variable/storage/average.h @@ -116,7 +116,7 @@ struct Average: public NextT avgdata.monthly); break; case Category::annual: - InternalExportValues<1, VCardT, Category::annual>(report, avgdata.year); + InternalExportValues<1, VCardT, Category::annual>(report, avgdata.year.data()); break; } } diff --git a/src/solver/variable/include/antares/solver/variable/storage/averagedata.h b/src/solver/variable/include/antares/solver/variable/storage/averagedata.h index 0ed11ae239..132b70317d 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/averagedata.h +++ b/src/solver/variable/include/antares/solver/variable/storage/averagedata.h @@ -62,7 +62,7 @@ class AverageData double weekly[WEEKS_PER_YEAR]; double daily[DAYS_PER_YEAR]; Antares::Memory::Stored::Type hourly; - double* year; + std::vector year; unsigned int nbYearsCapacity; mutable double allYears; // FIX MEEE - Remove the mutable as soon as possible std::vector yearsWeight; diff --git a/src/solver/variable/include/antares/solver/variable/storage/raw.h b/src/solver/variable/include/antares/solver/variable/storage/raw.h index e71356953f..fe6c444840 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/raw.h +++ b/src/solver/variable/include/antares/solver/variable/storage/raw.h @@ -120,7 +120,7 @@ struct Raw: public NextT rawdata.monthly); break; case Category::annual: - InternalExportValues(report, rawdata.year); + InternalExportValues(report, rawdata.year.data()); break; } } diff --git a/src/solver/variable/include/antares/solver/variable/storage/rawdata.h b/src/solver/variable/include/antares/solver/variable/storage/rawdata.h index 6a2c118c05..a0c60cc89d 100644 --- a/src/solver/variable/include/antares/solver/variable/storage/rawdata.h +++ b/src/solver/variable/include/antares/solver/variable/storage/rawdata.h @@ -60,7 +60,7 @@ class RawData double weekly[WEEKS_PER_YEAR]; double daily[DAYS_PER_YEAR]; Antares::Memory::Stored::Type hourly; - double* year; + std::vector year; mutable double allYears; unsigned int nbYearsCapacity; diff --git a/src/solver/variable/state.cpp b/src/solver/variable/state.cpp index ca8d5b2677..6657a5a23b 100644 --- a/src/solver/variable/state.cpp +++ b/src/solver/variable/state.cpp @@ -230,9 +230,9 @@ void State::yearEndBuildFromThermalClusterIndex(const uint clusterAreaWideIndex) uint maxDurationON; // nombre d'heures de fonctionnement d'un groupe au delà duquel un // arrêt/redémarrage est préférable uint maxUnitNeeded = 0; - uint startHourForCurrentYear = study.runtime->rangeLimits.hour[Data::rangeBegin]; + uint startHourForCurrentYear = study.runtime.rangeLimits.hour[Data::rangeBegin]; uint endHourForCurrentYear = startHourForCurrentYear - + study.runtime->rangeLimits.hour[Data::rangeCount]; + + study.runtime.rangeLimits.hour[Data::rangeCount]; assert(endHourForCurrentYear <= HOURS_PER_YEAR); @@ -377,9 +377,9 @@ void State::yearEndBuildThermalClusterCalculateStartupCosts( const std::array& ON_opt, const Data::ThermalCluster* currentCluster) { - uint startHourForCurrentYear = study.runtime->rangeLimits.hour[Data::rangeBegin]; + uint startHourForCurrentYear = study.runtime.rangeLimits.hour[Data::rangeBegin]; uint endHourForCurrentYear = startHourForCurrentYear - + study.runtime->rangeLimits.hour[Data::rangeCount]; + + study.runtime.rangeLimits.hour[Data::rangeCount]; for (uint hour = startHourForCurrentYear; hour < endHourForCurrentYear; ++hour) { @@ -427,9 +427,9 @@ std::array State::computeEconomicallyOptimalNbClustersONfo const std::array& ON_min, const std::array& ON_max) const { - uint startHourForCurrentYear = study.runtime->rangeLimits.hour[Data::rangeBegin]; + uint startHourForCurrentYear = study.runtime.rangeLimits.hour[Data::rangeBegin]; uint endHourForCurrentYear = startHourForCurrentYear - + study.runtime->rangeLimits.hour[Data::rangeCount]; + + study.runtime.rangeLimits.hour[Data::rangeCount]; // Nombre de groupes économiquement optimal en fonctionnement à l'heure h std::array ON_opt; diff --git a/src/solver/variable/storage/averagedata.cpp b/src/solver/variable/storage/averagedata.cpp index 4a88945bb6..fac0080bf1 100644 --- a/src/solver/variable/storage/averagedata.cpp +++ b/src/solver/variable/storage/averagedata.cpp @@ -31,7 +31,6 @@ namespace Antares::Solver::Variable::R::AllYears { AverageData::AverageData(): hourly(nullptr), - year(nullptr), nbYearsCapacity(0), allYears(0.) { @@ -40,7 +39,6 @@ AverageData::AverageData(): AverageData::~AverageData() { Antares::Memory::Release(hourly); - delete[] year; } void AverageData::reset() @@ -49,14 +47,14 @@ void AverageData::reset() (void)::memset(monthly, 0, sizeof(double) * MONTHS_PER_YEAR); (void)::memset(weekly, 0, sizeof(double) * WEEKS_PER_YEAR); (void)::memset(daily, 0, sizeof(double) * DAYS_PER_YEAR); - (void)::memset(year, 0, sizeof(double) * nbYearsCapacity); + year.assign(nbYearsCapacity, 0); } void AverageData::initializeFromStudy(Data::Study& study) { Antares::Memory::Allocate(hourly, HOURS_PER_YEAR); - nbYearsCapacity = study.runtime->rangeLimits.year[Data::rangeEnd] + 1; - year = new double[nbYearsCapacity]; + nbYearsCapacity = study.runtime.rangeLimits.year[Data::rangeEnd] + 1; + year.resize(nbYearsCapacity); yearsWeight = study.parameters.getYearsWeight(); yearsWeightSum = study.parameters.getYearsWeightSum(); diff --git a/src/solver/variable/storage/intermediate.cpp b/src/solver/variable/storage/intermediate.cpp index 4799085aaf..a796b9676d 100644 --- a/src/solver/variable/storage/intermediate.cpp +++ b/src/solver/variable/storage/intermediate.cpp @@ -44,9 +44,9 @@ IntermediateValues::IntermediateValues(): void IntermediateValues::initializeFromStudy(Data::Study& study) { - pRange = &study.runtime->rangeLimits; + pRange = &study.runtime.rangeLimits; calendar = &study.calendarOutput; - pRuntimeInfo = study.runtime; + pRuntimeInfo = &study.runtime; } void IntermediateValues::computeStatisticsAdequacyForTheCurrentYear() diff --git a/src/solver/variable/storage/rawdata.cpp b/src/solver/variable/storage/rawdata.cpp index 4baf8531bd..a1b4c2fecf 100644 --- a/src/solver/variable/storage/rawdata.cpp +++ b/src/solver/variable/storage/rawdata.cpp @@ -29,7 +29,6 @@ namespace Antares::Solver::Variable::R::AllYears { RawData::RawData(): hourly(nullptr), - year(nullptr), allYears(0.) { } @@ -37,14 +36,13 @@ RawData::RawData(): RawData::~RawData() { Antares::Memory::Release(hourly); - delete[] year; } void RawData::initializeFromStudy(const Data::Study& study) { Antares::Memory::Allocate(hourly, HOURS_PER_YEAR); - nbYearsCapacity = study.runtime->rangeLimits.year[Data::rangeEnd] + 1; - year = new double[nbYearsCapacity]; + nbYearsCapacity = study.runtime.rangeLimits.year[Data::rangeEnd] + 1; + year.resize(nbYearsCapacity); } void RawData::reset() @@ -54,7 +52,7 @@ void RawData::reset() (void)::memset(monthly, 0, sizeof(double) * MONTHS_PER_YEAR); (void)::memset(weekly, 0, sizeof(double) * WEEKS_PER_YEAR); (void)::memset(daily, 0, sizeof(double) * DAYS_PER_YEAR); - (void)::memset(year, 0, sizeof(double) * nbYearsCapacity); + year.assign(nbYearsCapacity, 0); } void RawData::merge(unsigned int y, const IntermediateValues& rhs) diff --git a/src/solver/variable/surveyresults/surveyresults.cpp b/src/solver/variable/surveyresults/surveyresults.cpp index bb763a1b80..8df87678e4 100644 --- a/src/solver/variable/surveyresults/surveyresults.cpp +++ b/src/solver/variable/surveyresults/surveyresults.cpp @@ -231,17 +231,16 @@ namespace Variable { static inline uint GetRangeLimit(const Data::Study& study, int precisionLevel, int index) { - assert(study.runtime && "invalid runtime data"); switch (precisionLevel) { case Category::hourly: - return study.runtime->rangeLimits.hour[index]; + return study.runtime.rangeLimits.hour[index]; case Category::daily: - return study.runtime->rangeLimits.day[index]; + return study.runtime.rangeLimits.day[index]; case Category::weekly: - return study.runtime->rangeLimits.week[index]; + return study.runtime.rangeLimits.week[index]; case Category::monthly: - return study.runtime->rangeLimits.month[index]; + return study.runtime.rangeLimits.month[index]; case Category::annual: return 0; default: @@ -357,13 +356,10 @@ inline void SurveyResults::AppendDoubleValue(uint& error, if (std::isnan(v)) { buffer.append("\tNaN", 4); - if (++error == 1) + // We should disabled errors on NaN if the quadratic optimization has failed + if (++error == 1 && !data.study.runtime.quadraticOptimizationHasFailed) { - // We should disabled errors on NaN if the quadratic optimization has failed - if (not data.study.runtime->quadraticOptimizationHasFailed) - { - logs.error() << "'NaN' value detected"; - } + logs.error() << "'NaN' value detected"; } } else @@ -608,7 +604,7 @@ void SurveyResults::exportDigestAllYears(std::string& buffer) { // Main Header { - const unsigned int nbLinks = data.study.runtime->interconnectionsCount(); + const unsigned int nbLinks = data.study.runtime.interconnectionsCount(); buffer.append("\tdigest\n\tVARIABLES\tAREAS\tLINKS\n") .append("\t") .append(std::to_string(data.columnIndex)) diff --git a/src/tests/inmemory-study/in-memory-study.cpp b/src/tests/inmemory-study/in-memory-study.cpp index 30efd246bf..1f3f78c194 100644 --- a/src/tests/inmemory-study/in-memory-study.cpp +++ b/src/tests/inmemory-study/in-memory-study.cpp @@ -56,7 +56,7 @@ void addScratchpadToEachArea(Study& study) { for (unsigned int i = 0; i < study.maxNbYearsInParallel; ++i) { - area->scratchpad.emplace_back(*study.runtime, *area); + area->scratchpad.emplace_back(study.runtime, *area); } } } diff --git a/src/tests/src/api_internal/test_api.cpp b/src/tests/src/api_internal/test_api.cpp index d60f6315d5..fe006c9bd6 100644 --- a/src/tests/src/api_internal/test_api.cpp +++ b/src/tests/src/api_internal/test_api.cpp @@ -44,8 +44,8 @@ class InMemoryStudyLoader: public Antares::IStudyLoader StudyBuilder builder; builder.addAreaToStudy("area1"); builder.addAreaToStudy("area2"); - builder.setNumberMCyears(1); builder.study->initializeRuntimeInfos(); + builder.setNumberMCyears(1); builder.study->parameters.resultFormat = ResultFormat::inMemory; builder.study->prepareOutput(); return std::move(builder.study); diff --git a/src/tests/src/libs/antares/study/test_study.cpp b/src/tests/src/libs/antares/study/test_study.cpp index 104b304c0e..0ecb082cd1 100644 --- a/src/tests/src/libs/antares/study/test_study.cpp +++ b/src/tests/src/libs/antares/study/test_study.cpp @@ -139,7 +139,7 @@ BOOST_FIXTURE_TEST_CASE(short_term_storage_delete, OneAreaStudy) BOOST_CHECK(findDisabledCluster("Cluster1") != sts.end()); BOOST_CHECK(findDisabledCluster("Cluster2") != sts.end()); - study->initializeRuntimeInfos(); // This should remove all disabled short-term storages + study->initializeRuntimeInfos(); // Check that only "Cluster1" is found BOOST_CHECK(findDisabledCluster("Cluster1") != sts.end()); diff --git a/src/tests/src/solver/simulation/test-store-timeseries-number.cpp b/src/tests/src/solver/simulation/test-store-timeseries-number.cpp index 16cbb59fc2..1e68ef95be 100644 --- a/src/tests/src/solver/simulation/test-store-timeseries-number.cpp +++ b/src/tests/src/solver/simulation/test-store-timeseries-number.cpp @@ -44,10 +44,9 @@ void initializeStudy(Study& study) { study.parameters.derated = false; - study.runtime = new StudyRuntimeInfos(); - study.runtime->rangeLimits.year[rangeBegin] = 0; - study.runtime->rangeLimits.year[rangeEnd] = 0; - study.runtime->rangeLimits.year[rangeCount] = 1; + study.runtime.rangeLimits.year[rangeBegin] = 0; + study.runtime.rangeLimits.year[rangeEnd] = 0; + study.runtime.rangeLimits.year[rangeCount] = 1; study.parameters.renewableGeneration.toAggregated(); // Default diff --git a/src/tests/src/solver/simulation/test-time_series.cpp b/src/tests/src/solver/simulation/test-time_series.cpp index 42f1fbddf4..b999c17b48 100644 --- a/src/tests/src/solver/simulation/test-time_series.cpp +++ b/src/tests/src/solver/simulation/test-time_series.cpp @@ -40,10 +40,9 @@ void initializeStudy(Study& study) { study.parameters.derated = false; - study.runtime = new StudyRuntimeInfos(); - study.runtime->rangeLimits.year[rangeBegin] = 0; - study.runtime->rangeLimits.year[rangeEnd] = 0; - study.runtime->rangeLimits.year[rangeCount] = 1; + study.runtime.rangeLimits.year[rangeBegin] = 0; + study.runtime.rangeLimits.year[rangeEnd] = 0; + study.runtime.rangeLimits.year[rangeCount] = 1; study.parameters.renewableGeneration.toAggregated(); // Default diff --git a/src/tests/src/solver/simulation/tests-ts-numbers.cpp b/src/tests/src/solver/simulation/tests-ts-numbers.cpp index 9767cbe525..8dbd450d53 100644 --- a/src/tests/src/solver/simulation/tests-ts-numbers.cpp +++ b/src/tests/src/solver/simulation/tests-ts-numbers.cpp @@ -38,9 +38,8 @@ void initializeStudy(Study::Ptr study, unsigned int nbYears = 1) { study->parameters.derated = false; - study->runtime = new StudyRuntimeInfos(); - study->runtime->rangeLimits.year[rangeBegin] = 0; - study->runtime->rangeLimits.year[rangeEnd] = nbYears - 1; + study->runtime.rangeLimits.year[rangeBegin] = 0; + study->runtime.rangeLimits.year[rangeEnd] = nbYears - 1; study->parameters.renewableGeneration.toAggregated(); // Default @@ -130,7 +129,7 @@ BOOST_AUTO_TEST_CASE(two_areas_with_5_ready_made_ts_on_load___check_intra_modal_ Area* area_1 = addAreaToStudy(study, "Area 1"); Area* area_2 = addAreaToStudy(study, "Area 2"); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); area_1->load.series.timeSeries.resize(5, 1); area_2->load.series.timeSeries.resize(5, 1); @@ -157,7 +156,7 @@ static bool intramodal_load_two_areas(unsigned width_area_1, unsigned width_area Area* area_1 = addAreaToStudy(study, "Area 1"); Area* area_2 = addAreaToStudy(study, "Area 2"); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); area_1->load.series.timeSeries.resize(width_area_1, 1); area_2->load.series.timeSeries.resize(width_area_2, 1); @@ -199,7 +198,7 @@ BOOST_AUTO_TEST_CASE( auto thCluster_21 = addClusterToArea(area_2, "th-cluster-21"); thCluster_21->series.timeSeries.resize(4, 1); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(Generate(*study)); @@ -231,7 +230,7 @@ BOOST_AUTO_TEST_CASE( auto thCluster_21 = addClusterToArea(area_2, "th-cluster-21"); thCluster_21->series.timeSeries.resize(4, 1); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(Generate(*study)); @@ -263,7 +262,7 @@ BOOST_AUTO_TEST_CASE( auto thCluster_21 = addClusterToArea(area_2, "th-cluster-21"); thCluster_21->series.timeSeries.resize(3, 1); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(not Generate(*study)); } @@ -291,7 +290,7 @@ BOOST_AUTO_TEST_CASE( auto rnCluster_21 = addClusterToArea(area_2, "rn-cluster-21"); rnCluster_21->series.timeSeries.resize(4, 1); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(Generate(*study)); @@ -323,7 +322,7 @@ BOOST_AUTO_TEST_CASE( auto rnCluster_21 = addClusterToArea(area_2, "rn-cluster-21"); rnCluster_21->series.timeSeries.resize(4, 1); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(Generate(*study)); @@ -357,7 +356,7 @@ BOOST_AUTO_TEST_CASE( auto rnCluster_21 = addClusterToArea(area_2, "rn-cluster-21"); rnCluster_21->series.timeSeries.resize(4, 1); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(not Generate(*study)); } @@ -389,7 +388,7 @@ BOOST_AUTO_TEST_CASE( auto thCluster_1 = addClusterToArea(area, "th-cluster-1"); auto thCluster_2 = addClusterToArea(area, "th-cluster-2"); - area->resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + area->resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); TSGenerator::ResizeGeneratedTimeSeries(study->areas, study->parameters); BOOST_CHECK(Generate(*study)); @@ -425,7 +424,7 @@ BOOST_AUTO_TEST_CASE( auto thCluster_1 = addClusterToArea(area, "th-cluster-1"); auto thCluster_2 = addClusterToArea(area, "th-cluster-2"); - area->resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + area->resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); TSGenerator::ResizeGeneratedTimeSeries(study->areas, study->parameters); BOOST_CHECK(Generate(*study)); @@ -461,7 +460,7 @@ BOOST_AUTO_TEST_CASE( auto thCluster_1 = addClusterToArea(area, "th-cluster-1"); auto thCluster_2 = addClusterToArea(area, "th-cluster-2"); - area->resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + area->resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); TSGenerator::ResizeGeneratedTimeSeries(study->areas, study->parameters); BOOST_CHECK(not Generate(*study)); @@ -486,7 +485,7 @@ BOOST_AUTO_TEST_CASE( auto rnCluster_1 = addClusterToArea(area, "rn-cluster-1"); rnCluster_1->series.timeSeries.resize(5, 1); - area->resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + area->resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(Generate(*study)); @@ -515,7 +514,7 @@ BOOST_AUTO_TEST_CASE( auto rnCluster_1 = addClusterToArea(area, "rn-cluster-1"); rnCluster_1->series.timeSeries.resize(4, 1); - area->resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + area->resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(not Generate(*study)); } @@ -539,7 +538,7 @@ BOOST_AUTO_TEST_CASE( auto rnCluster_1 = addClusterToArea(area, "rn-cluster-1"); rnCluster_1->series.timeSeries.resize(1, 1); - area->resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + area->resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); BOOST_CHECK(Generate(*study)); } @@ -581,7 +580,7 @@ BOOST_AUTO_TEST_CASE(load_wind_thermal_in_intra_and_inter_modal____check_all_ts_ area_2->wind.series.timeSeries.resize(5, 1); // Ready made TS for wind auto thCluster_area_2 = addClusterToArea(area_2, "th-cluster-area-2"); - study->areas.resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + study->areas.resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); TSGenerator::ResizeGeneratedTimeSeries(study->areas, study->parameters); BOOST_CHECK(Generate(*study)); @@ -629,14 +628,14 @@ BOOST_AUTO_TEST_CASE(check_all_drawn_ts_numbers_are_bounded_between_0_and_nb_of_ auto thCluster = addClusterToArea(area, "th-cluster"); - area->resizeAllTimeseriesNumbers(1 + study->runtime->rangeLimits.year[rangeEnd]); + area->resizeAllTimeseriesNumbers(1 + study->runtime.rangeLimits.year[rangeEnd]); auto bc = study->bindingConstraints.add("dummy"); bc->group("dummy"); study->bindingConstraintsGroups.add(bc->group()); bc->RHSTimeSeries().resize(42, 1); study->bindingConstraintsGroups.resizeAllTimeseriesNumbers( - 1 + study->runtime->rangeLimits.year[rangeEnd]); + 1 + study->runtime.rangeLimits.year[rangeEnd]); TSGenerator::ResizeGeneratedTimeSeries(study->areas, study->parameters); BOOST_CHECK(Generate(*study)); diff --git a/src/tools/ts-generator/linksTSgenerator.cpp b/src/tools/ts-generator/linksTSgenerator.cpp index 7ad893194a..a200386a7e 100644 --- a/src/tools/ts-generator/linksTSgenerator.cpp +++ b/src/tools/ts-generator/linksTSgenerator.cpp @@ -237,8 +237,8 @@ void readPreproTimeSeries(std::vector& linkList, fs::pat // Class methods // ================== LinksTSgenerator::LinksTSgenerator(Settings& settings): - studyFolder_(settings.studyFolder), linksFromCmdLineOptions_(settings.linksListToGen), + studyFolder_(settings.studyFolder), generateTSforAllLinks_(settings.allLinks) { } From 67f31e4e1295d4ebf9ba0d8fc54740eeb88b67d7 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Fri, 19 Jul 2024 15:54:45 +0200 Subject: [PATCH 080/127] Remove manual dynamic allocations in Xcast (#2270) #2244 --- src/libs/antares/study/area/list.cpp | 44 ++-- .../study/include/antares/study/area/area.h | 2 +- .../include/antares/solver/misc/cholesky.hxx | 6 +- .../antares/solver/ts-generator/xcast/xcast.h | 90 +++---- src/solver/ts-generator/xcast/core.cpp | 13 +- src/solver/ts-generator/xcast/xcast.cpp | 221 +++++------------- 6 files changed, 130 insertions(+), 246 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index de3c2e9b1f..46a2e98c6f 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -449,43 +449,31 @@ const AreaLink* AreaList::findLink(const AreaName& area, const AreaName& with) c void AreaList::clear() { - delete[] byIndex; - byIndex = nullptr; + byIndex.clear(); - if (!areas.empty()) - { - Area::Map copy; - copy.swap(areas); + Area::Map copy; + copy.swap(areas); - auto end = copy.end(); - for (auto i = copy.begin(); i != end; ++i) - { - delete i->second; - } + auto end = copy.end(); + for (auto i = copy.begin(); i != end; ++i) + { + delete i->second; } } void AreaList::rebuildIndexes() { - delete[] byIndex; + byIndex.clear(); - if (areas.empty()) - { - byIndex = nullptr; - } - else - { - using AreaWeakPtr = Area*; - byIndex = new AreaWeakPtr[areas.size()]; + byIndex.resize(areas.size()); - uint indx = 0; - auto end = areas.end(); - for (auto i = areas.begin(); i != end; ++i, ++indx) - { - Area* area = i->second; - byIndex[indx] = area; - area->index = indx; - } + uint indx = 0; + auto end = areas.end(); + for (auto i = areas.begin(); i != end; ++i, ++indx) + { + Area* area = i->second; + byIndex[indx] = area; + area->index = indx; } } diff --git a/src/libs/antares/study/include/antares/study/area/area.h b/src/libs/antares/study/include/antares/study/area/area.h index 6661ab8556..7550d9840f 100644 --- a/src/libs/antares/study/include/antares/study/area/area.h +++ b/src/libs/antares/study/include/antares/study/area/area.h @@ -689,7 +689,7 @@ class AreaList final: public Yuni::NonCopyable public: //! All areas by their index - Area** byIndex = nullptr; + std::vector byIndex; //! All areas in the list Area::Map areas; diff --git a/src/solver/misc/include/antares/solver/misc/cholesky.hxx b/src/solver/misc/include/antares/solver/misc/cholesky.hxx index 26c333d785..90418c17b2 100644 --- a/src/solver/misc/include/antares/solver/misc/cholesky.hxx +++ b/src/solver/misc/include/antares/solver/misc/cholesky.hxx @@ -42,7 +42,7 @@ bool Cholesky(U1& L, U2& A, uint size, T* temp) for (uint i = 0; i < size; ++i) { - typename MatrixSubColumn::Type Li = L[i]; + auto& Li = L[i]; // on calcule d'abord L[i][i] som = A[i][i]; @@ -58,8 +58,8 @@ bool Cholesky(U1& L, U2& A, uint size, T* temp) // maintenant on cherche L[k][i], k > i. for (uint k = i + 1; k < size; ++k) { - typename MatrixSubColumn::Type Lk = L[k]; - typename MatrixSubColumn::Type Ak = A[k]; + auto& Lk = L[k]; + auto& Ak = A[k]; if (temp[k] == Ak[k]) { diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/xcast/xcast.h b/src/solver/ts-generator/include/antares/solver/ts-generator/xcast/xcast.h index 55bb128e85..34b588b972 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/xcast/xcast.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/xcast/xcast.h @@ -74,7 +74,7 @@ class XCast final: private Yuni::NonCopyable /*! ** \brief Destructor */ - ~XCast(); + ~XCast() = default; //@} //! \name Loading @@ -105,7 +105,6 @@ class XCast final: private Yuni::NonCopyable private: void allocateTemporaryData(); - void destroyTemporaryData(); template void updateMissingCoefficients(PredicateT& predicate); @@ -180,7 +179,7 @@ class XCast final: private Yuni::NonCopyable //! The correlation matrix for the current month const Matrix* pCorrMonth; - bool pNeverInitialized; + bool pNeverInitialized = true; uint Nombre_points_intermediaire; //! True when starting a new month (some data may have to be reinitialized) @@ -192,57 +191,58 @@ class XCast final: private Yuni::NonCopyable uint pNDPMatrixCount; uint pLevellingCount; - bool pAccuracyOnCorrelation; + bool pAccuracyOnCorrelation = false; bool All_normal; // all processes are Normal - float* A; // les variables de A à CO sont des vues de ALPH à CORR pour un mois particulier - float* B; - float* G; - float* D; - int* M; - float* T; - Data::XCast::Distribution* L; - bool* BO; - float* MA; - float* MI; - float** FO; // contrainte : FO >=0 + // les variables de A à CO sont des vues de ALPH à CORR pour un mois particulier + std::vector A; + std::vector B; + std::vector G; + std::vector D; + std::vector M; + std::vector T; + std::vector L; + std::vector BO; + std::vector MA; + std::vector MI; + std::vector> FO; // contrainte : FO >=0 float STEP; float SQST; - float* POSI; - float** CORR; - float* MAXI; - float* MINI; - float* Presque_maxi; - float* Presque_mini; - float* ESPE; - float* STDE; - float** LISS; - float** DATL; - - float* DIFF; - float* TREN; - float* WIEN; - float* BROW; - - float* BASI; // used only if all processes are Normal - float* ALPH; // used only if all processes are Normal - float* BETA; // used only if all processes are Normal - - float** Triangle_reference; - float** Triangle_courant; - float** Carre_reference; - float** Carre_courant; - - float* D_COPIE; - - float** DATA; + std::vector POSI; + std::vector> CORR; + std::vector MAXI; + std::vector MINI; + std::vector Presque_maxi; + std::vector Presque_mini; + std::vector ESPE; + std::vector STDE; + std::vector> LISS; + std::vector> DATL; + + std::vector DIFF; + std::vector TREN; + std::vector WIEN; + std::vector BROW; + + std::vector BASI; // used only if all processes are Normal + std::vector ALPH; // used only if all processes are Normal + std::vector BETA; // used only if all processes are Normal + + std::vector> Triangle_reference; + std::vector> Triangle_courant; + std::vector> Carre_reference; + std::vector> Carre_courant; + + std::vector D_COPIE; + + std::vector> DATA; // cholesky temporary data - float* pQCHOLTotal; + std::vector pQCHOLTotal; //! - bool* pUseConversion; + std::vector pUseConversion; //! Name of the current timeseries Yuni::CString<32, false> pTSName; diff --git a/src/solver/ts-generator/xcast/core.cpp b/src/solver/ts-generator/xcast/core.cpp index a3d373e2c1..1eab73d534 100644 --- a/src/solver/ts-generator/xcast/core.cpp +++ b/src/solver/ts-generator/xcast/core.cpp @@ -93,7 +93,7 @@ bool XCast::generateValuesForTheCurrentDay() // si les parametres ont change on reinitialise certaines variables intermediaires if (pNewMonth) { - if (Cholesky(Triangle_courant, pCorrMonth->entry, processCount, pQCHOLTotal)) + if (Cholesky(Triangle_courant, pCorrMonth->entry, processCount, pQCHOLTotal.data())) { // C n'est pas sdp, mais peut-etre proche de sdp // on tente un abattement de 0.999 @@ -107,7 +107,10 @@ bool XCast::generateValuesForTheCurrentDay() } } - if (Cholesky(Triangle_courant, pCorrMonth->entry, processCount, pQCHOLTotal)) + if (Cholesky(Triangle_courant, + pCorrMonth->entry, + processCount, + pQCHOLTotal.data())) { // la matrice C n'est pas admissible, on abandonne logs.error() << "TS " << pTSName << " generator: invalid correlation matrix"; @@ -227,7 +230,7 @@ bool XCast::generateValuesForTheCurrentDay() Carre_reference, pCorrMonth->entry, processCount, - pQCHOLTotal); + pQCHOLTotal.data()); if (shrink == -1.f) { // sortie impossible car on a v�rifi� que C est d.p @@ -414,7 +417,7 @@ bool XCast::generateValuesForTheCurrentDay() for (uint s = 0; s != processCount; ++s) { - float* corr_s = CORR[s]; + auto& corr_s = CORR[s]; auto& userMonthlyCorr = pCorrMonth->column(s); for (uint t = 0; t < s; ++t) { @@ -453,7 +456,7 @@ bool XCast::generateValuesForTheCurrentDay() Carre_courant, Carre_reference, processCount, - pQCHOLTotal); + pQCHOLTotal.data()); if (shrink <= 1.f) { if (shrink == -1.f) diff --git a/src/solver/ts-generator/xcast/xcast.cpp b/src/solver/ts-generator/xcast/xcast.cpp index 56f7234119..b431e8d8ff 100644 --- a/src/solver/ts-generator/xcast/xcast.cpp +++ b/src/solver/ts-generator/xcast/xcast.cpp @@ -52,17 +52,10 @@ enum XCast::XCast(Data::Study& study, Data::TimeSeriesType ts, IResultWriter& writer): study(study), timeSeriesType(ts), - pNeverInitialized(true), - pAccuracyOnCorrelation(false), pWriter(writer) { } -XCast::~XCast() -{ - destroyTemporaryData(); -} - template void XCast::exportTimeSeriesToTheOutput(Progression::Task& progression, PredicateT& predicate) { @@ -114,8 +107,6 @@ void XCast::applyTransferFunction(PredicateT& predicate) float a[maxPoints]; float b[maxPoints]; - float* dailyResults; - const uint processCount = (uint)pData.localareas.size(); for (uint s = 0; s != processCount; ++s) @@ -145,7 +136,7 @@ void XCast::applyTransferFunction(PredicateT& predicate) b[i] = (p0[y] * p1[x] - p1[y] * p0[x]) / (p1[x] - p0[x]); } - dailyResults = DATA[s]; + auto& dailyResults = DATA[s]; for (h = 0; h != HOURS_PER_DAY; ++h) { for (i = 0; i != tf.width; ++i) @@ -200,162 +191,64 @@ void XCast::updateMissingCoefficients(PredicateT& predicate) } } -namespace -{ -template -class Allocator -{ -public: - Allocator(): - allocated(0) - { - } - - ~Allocator() - { - logs.debug() << " allocated " << (allocated / 1024) << "Ko"; - } - - template - inline T* allocate(const size_t s) - { - allocated += sizeof(T) * s; - return new T[s]; - } - -public: - size_t allocated; -}; - -template<> -class Allocator<0> -{ -public: - template - inline T* allocate(const size_t s) const - { - return new T[s]; - } -}; - -} // namespace - void XCast::allocateTemporaryData() { uint p = (uint)pData.localareas.size(); - Allocator m; - - A = m.allocate(p); - B = m.allocate(p); - G = m.allocate(p); - D = m.allocate(p); - M = m.allocate(p); - T = m.allocate(p); - BO = m.allocate(p); - MA = m.allocate(p); - MI = m.allocate(p); - L = m.allocate(p); - POSI = m.allocate(p); - MAXI = m.allocate(p); - MINI = m.allocate(p); - ESPE = m.allocate(p); - STDE = m.allocate(p); - DIFF = m.allocate(p); - TREN = m.allocate(p); - WIEN = m.allocate(p + 1); - BROW = m.allocate(p); - - BASI = m.allocate(p); - ALPH = m.allocate(p); - BETA = m.allocate(p); - - D_COPIE = m.allocate(p); - - pUseConversion = m.allocate(p); - - Presque_maxi = m.allocate(p); - Presque_mini = m.allocate(p); - pQCHOLTotal = m.allocate(p); - - CORR = m.allocate(p); - Triangle_reference = m.allocate(p); - Triangle_courant = m.allocate(p); - FO = m.allocate(p); - LISS = m.allocate(p); - DATL = m.allocate(p); - DATA = m.allocate(p); - Carre_courant = m.allocate(p); - Carre_reference = m.allocate(p); + A.resize(p); + B.resize(p); + G.resize(p); + D.resize(p); + M.resize(p); + T.resize(p); + BO.resize(p); + MA.resize(p); + MI.resize(p); + L.resize(p); + POSI.resize(p); + MAXI.resize(p); + MINI.resize(p); + ESPE.resize(p); + STDE.resize(p); + DIFF.resize(p); + TREN.resize(p); + WIEN.resize(p + 1); + BROW.resize(p); + + BASI.resize(p); + ALPH.resize(p); + BETA.resize(p); + + D_COPIE.resize(p); + + pUseConversion.resize(p); + + Presque_maxi.resize(p); + Presque_mini.resize(p); + pQCHOLTotal.resize(p); + + CORR.resize(p); + Triangle_reference.resize(p); + Triangle_courant.resize(p); + FO.resize(p); + LISS.resize(p); + DATL.resize(p); + DATA.resize(p); + Carre_courant.resize(p); + Carre_reference.resize(p); for (uint i = 0; i != p; ++i) { - Triangle_reference[i] = m.allocate(p); - Triangle_courant[i] = m.allocate(p); - Carre_courant[i] = m.allocate(p); - Carre_reference[i] = m.allocate(p); - - CORR[i] = m.allocate(p); - FO[i] = m.allocate(24); - LISS[i] = m.allocate(24); - DATL[i] = m.allocate(24); - DATA[i] = m.allocate(24); - } -} - -void XCast::destroyTemporaryData() -{ - if (!pNeverInitialized) - { - uint p = (uint)pData.localareas.size(); - for (uint i = 0; i != p; ++i) - { - delete[] CORR[i]; - delete[] FO[i]; - delete[] LISS[i]; - delete[] DATL[i]; - delete[] Triangle_reference[i]; - delete[] Triangle_courant[i]; - delete[] DATA[i]; - delete[] Carre_courant[i]; - delete[] Carre_reference[i]; - } - delete[] Carre_courant; - delete[] Carre_reference; - delete[] D_COPIE; - delete[] DATA; - delete[] Triangle_reference; - delete[] Triangle_courant; - delete[] LISS; - delete[] DATL; - delete[] CORR; - delete[] FO; - delete[] A; - delete[] B; - delete[] G; - delete[] D; - delete[] M; - delete[] T; - delete[] L; - delete[] BO; - delete[] MA; - delete[] MI; - delete[] POSI; - delete[] MAXI; - delete[] MINI; - delete[] Presque_maxi; - delete[] Presque_mini; - delete[] ESPE; - delete[] STDE; - delete[] DIFF; - delete[] TREN; - delete[] WIEN; - delete[] BROW; - delete[] BASI; - delete[] ALPH; - delete[] BETA; - delete[] pQCHOLTotal; - delete[] pUseConversion; + Triangle_reference[i].resize(p); + Triangle_courant[i].resize(p); + Carre_courant[i].resize(p); + Carre_reference[i].resize(p); + + CORR[i].resize(p); + FO[i].resize(24); + LISS[i].resize(24); + DATL[i].resize(24); + DATA[i].resize(24); } } @@ -476,7 +369,7 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi MA[s] = +std::numeric_limits::max(); } } - memcpy(FO[s], xcastdata.K[realmonth], sizeof(float) * HOURS_PER_DAY); + memcpy(FO[s].data(), xcastdata.K[realmonth], sizeof(float) * HOURS_PER_DAY); } uint nbDaysPerMonth = study.calendar.months[month].days; @@ -491,7 +384,7 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi for (uint s = 0; s != processCount; ++s) { - float* dailyResults = DATA[s]; + auto& dailyResults = DATA[s]; for (uint h = 0; h != HOURS_PER_DAY; ++h) { @@ -512,7 +405,7 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi } auto& column = srcData.translation[0]; - float* dailyResults = DATA[s]; + auto& dailyResults = DATA[s]; assert(hourInTheYear + HOURS_PER_DAY <= srcData.translation.height && "Bound checking"); @@ -529,7 +422,7 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi for (uint s = 0; s != processCount; ++s) { - float* dailyResults = DATA[s]; + auto& dailyResults = DATA[s]; for (uint h = 0; h != HOURS_PER_DAY; ++h) { @@ -548,7 +441,7 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi auto& series = predicate.matrix(currentArea); assert(tsIndex < series.width); auto& column = series.column(tsIndex); - float* dailyResults = DATA[s]; + auto& dailyResults = DATA[s]; for (uint h = 0; h != HOURS_PER_DAY; ++h) { From bc23762201b1bcf3b560cde06000c968758180fe Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Mon, 22 Jul 2024 14:34:02 +0200 Subject: [PATCH 081/127] Infeasibility analyzer : improve unit tests (#2249) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mainly add new unit tests for slack analysis. Also add condition (threshold) on slack variable values. --------- Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> Co-authored-by: Florian Omnès --- .../constraint-slack-analysis.cpp | 29 ++- .../constraint-slack-analysis.h | 4 + .../infeasible-problem-analysis/report.h | 6 +- .../infeasible-problem-analysis/report.cpp | 21 +- .../watched-constraints.cpp | 2 +- .../test-unfeasible-problem-analyzer.cpp | 194 ++++++++++++++---- 6 files changed, 192 insertions(+), 64 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp b/src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp index 099ac70db6..68c11ff003 100644 --- a/src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp +++ b/src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp @@ -33,7 +33,7 @@ using namespace operations_research; namespace { -bool compareSlackSolutions(const MPVariable* a, const MPVariable* b) +bool greaterSlackSolutions(const MPVariable* a, const MPVariable* b) { return a->solution_value() > b->solution_value(); } @@ -50,7 +50,7 @@ void ConstraintSlackAnalysis::run(MPSolver* problem) addSlackVariablesToConstraints(problem); if (slackVariables_.empty()) { - logs.error() << title() << " : no constraints have been selected"; + logs.warning() << title() << " : no constraints have been selected"; return; } @@ -63,10 +63,12 @@ void ConstraintSlackAnalysis::run(MPSolver* problem) return; } - hasDetectedInfeasibilityCause_ = true; - sortSlackVariablesByValue(); trimSlackVariables(); + if (hasDetectedInfeasibilityCause_ = anySlackVariableNonZero(); !hasDetectedInfeasibilityCause_) + { + logs.warning() << title() << " : no violation detected for selected constraints."; + } } void ConstraintSlackAnalysis::selectConstraintsToWatch(MPSolver* problem) @@ -121,7 +123,7 @@ void ConstraintSlackAnalysis::buildObjective(MPSolver* problem) const void ConstraintSlackAnalysis::sortSlackVariablesByValue() { - std::sort(std::begin(slackVariables_), std::end(slackVariables_), ::compareSlackSolutions); + std::sort(std::begin(slackVariables_), std::end(slackVariables_), ::greaterSlackSolutions); } void ConstraintSlackAnalysis::trimSlackVariables() @@ -130,11 +132,24 @@ void ConstraintSlackAnalysis::trimSlackVariables() slackVariables_.resize(std::min(nbMaxSlackVarsToKeep, nbSlackVars)); } +bool ConstraintSlackAnalysis::anySlackVariableNonZero() +{ + return std::ranges::any_of(slackVariables_, + [&](auto& v) { return v->solution_value() > thresholdNonZero; }); +} + +const std::vector& +ConstraintSlackAnalysis::largestSlackVariables() +{ + return slackVariables_; +} + void ConstraintSlackAnalysis::printReport() const { InfeasibleProblemReport report(slackVariables_); - report.logSuspiciousConstraints(); - report.logInfeasibilityCauses(); + report.storeSuspiciousConstraints(); + report.storeInfeasibilityCauses(); + std::ranges::for_each(report.getLogs(), [](auto& line) { logs.notice() << line; }); } } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h index 462d5f965f..352176a41e 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h @@ -52,15 +52,19 @@ class ConstraintSlackAnalysis: public UnfeasibilityAnalysis return "Slack variables analysis"; } + const std::vector& largestSlackVariables(); + private: void selectConstraintsToWatch(operations_research::MPSolver* problem); void addSlackVariablesToConstraints(operations_research::MPSolver* problem); void buildObjective(operations_research::MPSolver* problem) const; void sortSlackVariablesByValue(); void trimSlackVariables(); + bool anySlackVariableNonZero(); std::vector constraintsToWatch_; std::vector slackVariables_; + const double thresholdNonZero = 1e-06; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h index ef242b1f36..1d498eb653 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h @@ -40,13 +40,15 @@ class InfeasibleProblemReport public: InfeasibleProblemReport() = delete; explicit InfeasibleProblemReport(const std::vector&); - void logSuspiciousConstraints(); - void logInfeasibilityCauses(); + void storeSuspiciousConstraints(); + void storeInfeasibilityCauses(); + std::vector getLogs(); private: void buildConstraintsFromSlackVars(const std::vector&); void filterConstraintsToOneByType(); std::vector> constraints_; + std::vector report_; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index dc43da140a..4be4463400 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -24,8 +24,6 @@ #include #include -#include - namespace Antares::Optimization { InfeasibleProblemReport::InfeasibleProblemReport( @@ -69,8 +67,7 @@ void InfeasibleProblemReport::filterConstraintsToOneByType() { // 1. Grouping constraints by C++ type (inside a group, order of instances remains unchanged) std::ranges::stable_sort(constraints_, lessTypeName); - // 2. Keeping the first instances of each group, and rejecting others (= duplicates) to the end - // of vector + // 2. Keeping the first instances of each group, and rejecting others (= duplicates) to the end. auto duplicates = std::ranges::unique(constraints_, sameType); // 3. Removing trailing duplicates constraints_.erase(duplicates.begin(), duplicates.end()); @@ -78,22 +75,28 @@ void InfeasibleProblemReport::filterConstraintsToOneByType() std::ranges::sort(constraints_, greaterValue); } -void InfeasibleProblemReport::logSuspiciousConstraints() +void InfeasibleProblemReport::storeSuspiciousConstraints() { + report_.push_back("Violated constraints:"); for (const auto& c: constraints_) { - Antares::logs.error() << c->infeasibility(); + report_.push_back(c->infeasibility()); } } -void InfeasibleProblemReport::logInfeasibilityCauses() +void InfeasibleProblemReport::storeInfeasibilityCauses() { filterConstraintsToOneByType(); - Antares::logs.error() << "Possible causes of infeasibility:"; + report_.push_back("Possible causes of infeasibility:"); for (const auto& c: constraints_) { - Antares::logs.error() << c->infeasibilityCause(); + report_.push_back(c->infeasibilityCause()); } } +std::vector InfeasibleProblemReport::getLogs() +{ + return report_; +} + } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/watched-constraints.cpp b/src/solver/infeasible-problem-analysis/watched-constraints.cpp index e054f49f03..3404dc06d2 100644 --- a/src/solver/infeasible-problem-analysis/watched-constraints.cpp +++ b/src/solver/infeasible-problem-analysis/watched-constraints.cpp @@ -36,7 +36,7 @@ std::string StringBetweenAngleBrackets(const std::string& constraintName) std::string timeStep(std::vector splitName) { - return StringBetweenAngleBrackets(splitName.at(splitName.size() - 2)); + return StringBetweenAngleBrackets(splitName.rbegin()[1]); } std::string shortName(std::vector splitName) diff --git a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp index 20086d505f..2155fd48c4 100644 --- a/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp +++ b/src/tests/src/solver/infeasible-problem-analysis/test-unfeasible-problem-analyzer.cpp @@ -22,12 +22,14 @@ #define BOOST_TEST_MODULE unfeasible_problem_analyzer #include +#include #include #include #include #include "antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h" +#include "antares/solver/infeasible-problem-analysis/report.h" #include "antares/solver/infeasible-problem-analysis/unfeasible-pb-analyzer.h" #include "antares/solver/infeasible-problem-analysis/variables-bounds-consistency.h" @@ -36,6 +38,7 @@ namespace bdata = boost::unit_test::data; using namespace operations_research; using Antares::Optimization::ConstraintSlackAnalysis; +using Antares::Optimization::InfeasibleProblemReport; using Antares::Optimization::UnfeasibilityAnalysis; using Antares::Optimization::UnfeasiblePbAnalyzer; using Antares::Optimization::VariableBounds; @@ -83,7 +86,50 @@ class AnalysisMock: public UnfeasibilityAnalysis bool& hasPrinted_; }; -BOOST_AUTO_TEST_SUITE(unfeasible_problem_analyzer) +void addOneVarConstraintToProblem(MPSolver* problem, + const std::string& constraintName, + double varLowBnd, + double varUpBnd, + double ConstLowBnd) +{ + std::string varName = "lonely-var-in-" + constraintName; + auto* var = problem->MakeNumVar(varLowBnd, varUpBnd, varName); + auto* constraint = problem->MakeRowConstraint(constraintName); + constraint->SetCoefficient(var, 1); + constraint->SetBounds(ConstLowBnd, problem->infinity()); +} + +std::unique_ptr createFeasibleProblem(const std::string& constraintName) +{ + std::unique_ptr problem(MPSolver::CreateSolver("GLOP")); + // Following constraint is easily satisfied + addOneVarConstraintToProblem(problem.get(), constraintName, 0., 1., 0.); + return problem; +} + +std::unique_ptr createUnfeasibleProblem(const std::string& constraintName) +{ + std::unique_ptr problem(MPSolver::CreateSolver("GLOP")); + // Following constraint cannot be satisfied + addOneVarConstraintToProblem(problem.get(), constraintName, 0., 1., 2.); + return problem; +} + +std::unique_ptr createProblemWith_n_violatedConstraints(const int n) +{ + std::unique_ptr problem(MPSolver::CreateSolver("GLOP")); + for (auto i: std::ranges::iota_view(1, n + 1)) // From 1 to n included + { + std::stringstream name; + name << "BC-name-" << i << "::hourly::hour<" << 5 * i << ">"; + // Make a constraint that can never be satisfied, of type : var > A, + // where : bound_inf(var) = 0, bound_sup(var) = 1 and A > 1. + addOneVarConstraintToProblem(problem.get(), name.str(), 0., 1., double(i + 2)); + } + return problem; +} + +BOOST_AUTO_TEST_SUITE(general_unfeasible_problem_analyzer) BOOST_AUTO_TEST_CASE(analyzer_should_call_analysis_and_print_detected_issues) { @@ -116,6 +162,9 @@ BOOST_AUTO_TEST_CASE(analyzer_should_call_analysis_and_print_detected_issues) BOOST_CHECK(hasRun2); BOOST_CHECK(hasPrinted2); } +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(variable_bounds_consistency_analyzer) BOOST_AUTO_TEST_CASE(analysis_should_detect_inconsistent_variable_bounds) { @@ -131,47 +180,9 @@ BOOST_AUTO_TEST_CASE(analysis_should_detect_inconsistent_variable_bounds) auto expected = VariableBounds("not-ok-var", 1, -1); BOOST_CHECK(variableEquals(incorrectVars[0], expected)); } +BOOST_AUTO_TEST_SUITE_END() -/*! - * Creates a problem with 2 variables linked by 1 constraint: - * - Variable 1 must be greater than 1 - * - Variable 2 must be smaller than -1 - * - but if feasible is false, constraint enforces that variable 2 is greater than variable 1 --> - * infeasible - */ - -std::unique_ptr createProblem(const std::string& constraintName) -{ - std::unique_ptr problem(MPSolver::CreateSolver("GLOP")); - const double infinity = problem->infinity(); - problem->MakeNumVar(1, infinity, "var1"); - problem->MakeNumVar(-infinity, -1, "var2"); - auto constraint = problem->MakeRowConstraint(constraintName); - constraint->SetBounds(0, infinity); - return problem; -} - -std::unique_ptr createFeasibleProblem(const std::string& constraintName) -{ - auto problem = createProblem(constraintName); - auto constraint = problem->LookupConstraintOrNull(constraintName); - auto var1 = problem->LookupVariableOrNull("var1"); - auto var2 = problem->LookupVariableOrNull("var2"); - constraint->SetCoefficient(var1, 1); - constraint->SetCoefficient(var2, -1); - return problem; -} - -std::unique_ptr createUnfeasibleProblem(const std::string& constraintName) -{ - auto problem = createProblem(constraintName); - auto constraint = problem->LookupConstraintOrNull(constraintName); - auto var1 = problem->LookupVariableOrNull("var1"); - auto var2 = problem->LookupVariableOrNull("var2"); - constraint->SetCoefficient(var1, -1); - constraint->SetCoefficient(var2, 1); - return problem; -} +BOOST_AUTO_TEST_SUITE(slack_variables_analyzer) static const std::string validConstraintNames[] = {"BC-name-1::hourly::hour<36>", "BC-name-2::daily::day<67>", @@ -203,16 +214,109 @@ BOOST_AUTO_TEST_CASE(analysis_should_ignore_ill_named_constraint) BOOST_CHECK(!analysis.hasDetectedInfeasibilityCause()); } -// TODO: this test should be improved by changing the API, the current interface does not allow -// to check that no constraint was identified... BOOST_AUTO_TEST_CASE(analysis_should_ignore_feasible_constraints) { - std::unique_ptr feasibleProblem = createFeasibleProblem("BC::hourly::hour<36>"); + std::unique_ptr feasibleProblem = createFeasibleProblem("BC-name::hourly::hour<36>"); BOOST_CHECK(feasibleProblem->Solve() == MPSolver::OPTIMAL); ConstraintSlackAnalysis analysis; analysis.run(feasibleProblem.get()); - BOOST_CHECK(analysis.hasDetectedInfeasibilityCause()); // Would expect false here instead? + BOOST_CHECK(!analysis.hasDetectedInfeasibilityCause()); +} + +BOOST_AUTO_TEST_CASE(analysis_slack_variables_are_ordered) +{ + std::unique_ptr problem = createProblemWith_n_violatedConstraints(3); + BOOST_CHECK(problem->Solve() == MPSolver::INFEASIBLE); + + ConstraintSlackAnalysis analysis; + analysis.run(problem.get()); + BOOST_CHECK(analysis.hasDetectedInfeasibilityCause()); + + auto& violatedConstraints = analysis.largestSlackVariables(); + BOOST_CHECK_EQUAL(violatedConstraints.size(), 3); + BOOST_CHECK_EQUAL(violatedConstraints[0]->name(), "BC-name-3::hourly::hour<15>::low"); + BOOST_CHECK_EQUAL(violatedConstraints[1]->name(), "BC-name-2::hourly::hour<10>::low"); + BOOST_CHECK_EQUAL(violatedConstraints[2]->name(), "BC-name-1::hourly::hour<5>::low"); +} + +BOOST_AUTO_TEST_CASE(analysis_slack_variables_are_ordered_and_limited_to_10) +{ + std::unique_ptr problem = createProblemWith_n_violatedConstraints(15); + BOOST_CHECK(problem->Solve() == MPSolver::INFEASIBLE); + + ConstraintSlackAnalysis analysis; + analysis.run(problem.get()); + BOOST_CHECK(analysis.hasDetectedInfeasibilityCause()); + + auto& violatedConstraints = analysis.largestSlackVariables(); + BOOST_CHECK_EQUAL(violatedConstraints.size(), 10); + BOOST_CHECK_EQUAL(violatedConstraints[0]->name(), "BC-name-15::hourly::hour<75>::low"); + BOOST_CHECK_EQUAL(violatedConstraints[9]->name(), "BC-name-6::hourly::hour<30>::low"); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(slack_variables_report) + +BOOST_AUTO_TEST_CASE(constraints_associated_to_all_incoming_slack_vars_are_reported) +{ + // The problem is needed only to create variables, impossible otherwise. + std::unique_ptr problem(MPSolver::CreateSolver("GLOP")); + + std::vector slackVariables; + slackVariables.push_back(problem->MakeNumVar(0, 1, "BC-1::hourly::hour<36>::low")); + slackVariables.push_back(problem->MakeNumVar(0, 1, "BC-2::hourly::hour<65>::up")); + slackVariables.push_back( + problem->MakeNumVar(0, 1, "FictiveLoads::area::hour<25>::low")); + slackVariables.push_back( + problem->MakeNumVar(0, 1, "HydroPower::area::week<45>::up")); + + InfeasibleProblemReport report(slackVariables); + report.storeSuspiciousConstraints(); + auto reportLogs = report.getLogs(); + + BOOST_CHECK_EQUAL(reportLogs.size(), 5); // Expecting 5 lines in the report + BOOST_CHECK_EQUAL(reportLogs[1], "Hourly BC 'BC-1' at hour 36"); + BOOST_CHECK_EQUAL(reportLogs[2], "Hourly BC 'BC-2' at hour 65"); + BOOST_CHECK_EQUAL(reportLogs[3], "Last resort shedding status at area 'some-area' at hour 25"); + BOOST_CHECK_EQUAL(reportLogs[4], "Hydro weekly production at area 'some-area'"); +} + +BOOST_AUTO_TEST_CASE(Infeasibility_causes_are_unique_and_sorted_by_slack_value) +{ + // The problem is needed only to create variables, impossible otherwise. + std::unique_ptr problem(MPSolver::CreateSolver("GLOP")); + + addOneVarConstraintToProblem(problem.get(), "HydroPower::area::week<0>", 0., 1., 2.); + addOneVarConstraintToProblem(problem.get(), "BC-1::hourly::hour<36>", 0., 1., 3.); + addOneVarConstraintToProblem(problem.get(), + "FictiveLoads::area::hour<25>", + 0., + 1., + 4.); + addOneVarConstraintToProblem(problem.get(), "BC-2::hourly::hour<65>", 0., 1., 5.); + addOneVarConstraintToProblem(problem.get(), + "FictiveLoads::area::hour<56>", + 0., + 1., + 6.); + + BOOST_CHECK(problem->Solve() == MPSolver::INFEASIBLE); + + ConstraintSlackAnalysis analysis; + analysis.run(problem.get()); + BOOST_CHECK(analysis.hasDetectedInfeasibilityCause()); + + InfeasibleProblemReport report(analysis.largestSlackVariables()); + report.storeInfeasibilityCauses(); + auto reportLogs = report.getLogs(); + + BOOST_CHECK_EQUAL(reportLogs.size(), 4); // Expecting 4 lines in the report + BOOST_CHECK_EQUAL(reportLogs[0], "Possible causes of infeasibility:"); + BOOST_CHECK_EQUAL(reportLogs[1], "* Last resort shedding status."); + BOOST_CHECK_EQUAL(reportLogs[2], "* Hourly binding constraints."); + BOOST_CHECK_EQUAL(reportLogs[3], "* impossible to generate exactly the weekly hydro target"); } BOOST_AUTO_TEST_SUITE_END() From af43670ae79518ec3b0b0a5927466b659149833f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 22 Jul 2024 15:36:42 +0200 Subject: [PATCH 082/127] Remove useless forward declaration (#2268) --- src/libs/antares/logs/include/antares/logs/logs.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/libs/antares/logs/include/antares/logs/logs.h b/src/libs/antares/logs/include/antares/logs/logs.h index 9bf0181cf4..3aca2ba167 100644 --- a/src/libs/antares/logs/include/antares/logs/logs.h +++ b/src/libs/antares/logs/include/antares/logs/logs.h @@ -63,16 +63,6 @@ #include #include -namespace Antares -{ -namespace Data -{ -// Forward declaration -class Study; - -} // namespace Data -} // namespace Antares - namespace Antares { //! Handlers for logging From d9b944e5b721e6b7c374396bdf43e59adc3af599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 23 Jul 2024 09:38:57 +0200 Subject: [PATCH 083/127] Use OR-Tools v9.10 (#2277) 9.8-rte1.0 -> 9.10-rte1.0 --- .github/workflows/centos7.yml | 2 +- .github/workflows/oracle8.yml | 2 +- .github/workflows/sonarcloud.yml | 2 +- .github/workflows/ubuntu.yml | 2 +- .github/workflows/windows-vcpkg.yml | 2 +- ortools_tag | 2 +- src/CMakeLists.txt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index 5ba13ec5c6..23eb7e8ce7 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -75,7 +75,7 @@ jobs: - name: Config OR-Tools URL run: | - echo "URL_ORTOOLS=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_centos7_static_sirius.zip" >> $GITHUB_ENV + echo "URL_ORTOOLS=https://github.com/rte-france/or-tools-rte/releases/download/$(cat ortools_tag)/ortools_cxx_centos7_static_sirius.zip" >> $GITHUB_ENV - name: Download OR-Tools id: ortools diff --git a/.github/workflows/oracle8.yml b/.github/workflows/oracle8.yml index 01f040c5ac..93485068c9 100644 --- a/.github/workflows/oracle8.yml +++ b/.github/workflows/oracle8.yml @@ -74,7 +74,7 @@ jobs: - name: Config OR-Tools URL run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_oraclelinux-8_static_sirius.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/$(cat ortools_tag)/ortools_cxx_oraclelinux-8_static_sirius.zip" >> $GITHUB_ENV - name: Download & extract OR-Tools run: | diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 8dbf991635..18955f692e 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -40,7 +40,7 @@ jobs: - name: Config OR-Tools URL run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/$(cat ortools_tag)/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV - name: Install sonar-scanner and build-wrapper uses: SonarSource/sonarcloud-github-c-cpp@v3 diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 9f129f04f9..24c53f00f0 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -75,7 +75,7 @@ jobs: - name: Config OR-Tools URL run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/$(cat ortools_tag)/ortools_cxx_ubuntu-20.04_static_sirius.zip" >> $GITHUB_ENV - name: Download pre-compiled librairies uses: ./.github/workflows/download-extract-precompiled-libraries-tgz diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index bcd2ef9e5a..da3ee37acb 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -53,7 +53,7 @@ jobs: - name: Config OR-Tools URL run: | - echo "ORTOOLS_URL=https://github.com/rte-france/or-tools/releases/download/$(cat ortools_tag)/ortools_cxx_windows-latest_static_sirius.zip" >> $GITHUB_ENV + echo "ORTOOLS_URL=https://github.com/rte-france/or-tools-rte/releases/download/$(cat ortools_tag)/ortools_cxx_windows-latest_static_sirius.zip" >> $GITHUB_ENV shell: bash - name: Pre-requisites diff --git a/ortools_tag b/ortools_tag index fdaa0174f8..ef2956ed2d 100644 --- a/ortools_tag +++ b/ortools_tag @@ -1 +1 @@ -v9.8-rte1.0 \ No newline at end of file +v9.10-rte1.0 \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78adeffde1..ae280dcc01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -208,7 +208,7 @@ find_package(ortools) if(NOT ortools_FOUND OR BUILD_ORTOOLS) message(STATUS "OR-Tools tag ${ORTOOLS_TAG}") FetchContent_Declare(ortools - GIT_REPOSITORY "https://github.com/rte-france/or-tools" + GIT_REPOSITORY "https://github.com/rte-france/or-tools-rte" GIT_TAG ${ORTOOLS_TAG} GIT_SHALLOW TRUE ) From ea71166611685a0cbcf4b14a702f93f3e27786d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 23 Jul 2024 10:41:38 +0200 Subject: [PATCH 084/127] Use devtoolset-11 on CentOS7 to fix build (#2282) OR-Tools 9.10-rte1.0 was built with devtoolset-11, so we use the same toolchain to avoid compatibility issues. --- .github/workflows/centos7.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index 23eb7e8ce7..4d7700e203 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -44,7 +44,7 @@ jobs: - name: Install gcc 10 run: | yum install -y centos-release-scl - yum install -y devtoolset-10-gcc* + yum install -y devtoolset-11-gcc* - name: Install cmake 3.28 run: pip3 install cmake==3.28.4 @@ -94,7 +94,7 @@ jobs: - name: Configure run: | - source /opt/rh/devtoolset-10/enable + source /opt/rh/devtoolset-11/enable source /opt/rh/rh-git227/enable cmake -B _build -S src \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ @@ -110,7 +110,7 @@ jobs: - name: Build run: | - source /opt/rh/devtoolset-10/enable + source /opt/rh/devtoolset-11/enable source /opt/rh/rh-git227/enable cmake --build _build --config Release -j$(nproc) ccache -s From 68a388d4fdae227a29f5089641947a6087c31e6a Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:49:17 +0200 Subject: [PATCH 085/127] Fix Sonar warning: use compile_commands.json (#2281) --- .github/workflows/sonarcloud.yml | 6 ++++-- sonar-project.properties | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 18955f692e..2b3ca8137a 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -20,6 +20,7 @@ jobs: ORTOOLS_DIR: ${{ github.workspace }}/or-tools # Caching strategy of VCPKG dependencies VCPKG_BINARY_SOURCES: "clear;files,${{ github.workspace }}/vcpkg_cache,readwrite" + BUILD_WRAPPER_OUT_DIR: ${{ github.workspace }}/_build/output # Directory where build-wrapper output will be placed steps: - uses: actions/checkout@v4 @@ -96,11 +97,12 @@ jobs: -DCMAKE_PREFIX_PATH="../install;${{ env.ORTOOLS_DIR }}/install" \ -DBUILD_TESTING=ON \ -DMZ_CODE_COVERAGE=ON \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DPython3_EXECUTABLE='${{ steps.setup-python.outputs.python-path }}' - name: Build run: | - build-wrapper-linux-x86-64 --out-dir $GITHUB_WORKSPACE/_build/output cmake --build _build --config release -j$(nproc) + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build _build --config release -j$(nproc) - name: Test and generate coverage continue-on-error: true @@ -116,7 +118,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" + run: sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" - name: Cache vcpkg binary dir if: always() diff --git a/sonar-project.properties b/sonar-project.properties index bf90dbda19..2a76f458da 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -15,6 +15,5 @@ sonar.sourceEncoding=UTF-8 sonar.exclusions=src/ext/**,src/tests/**,src/ui/** sonar.coverage.exclusions=src/ext/**,src/tests/**,src/analyzer/**,src/distrib/**,src/tools/**,src/ui/** -sonar.cfamily.build-wrapper-output=_build/output sonar.coverageReportPaths=coverage.xml sonar.cfamily.threads=4 From 2587876a524b29a8346feddb1988e20ded6c29f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 23 Jul 2024 15:55:44 +0200 Subject: [PATCH 086/127] Add short-term storage doc for optim model (#2283) Preview https://antares-simulator--2283.org.readthedocs.build/en/2283/user-guide/solver/05-model/#short-term-storage - Notations (variables, parameters) - Added level equation - Contribution to the existing balance equation --- docs/user-guide/solver/05-model.md | 50 +++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/docs/user-guide/solver/05-model.md b/docs/user-guide/solver/05-model.md index 29816befd2..9f37c2ac9a 100644 --- a/docs/user-guide/solver/05-model.md +++ b/docs/user-guide/solver/05-model.md @@ -178,6 +178,21 @@ Note: Almost all variables of the system are defined twice (one value per state) | $R\_\lambda \in \mathbb{R}^T_+$ | stored energy level in reservoir $\lambda$ | | $\mathfrak{R}\_{\lambda_q} \in \mathbb{R}_+$ | filling level of reservoir layer $q$ at time $T$ (end of the week) | +### Short-term storages +| Notation | Explanation | +|---------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| $s\in \mathcal{S}$ | A single short-term storge reservoir. There is one set of short-term storage per area. | +| $L_s \in \mathbb{R}_+^T$ | Level for storage $s$ | +| $\underline{L}_s \in \mathbb{R}^T$, $\overline{L}_s \in \mathbb{R}^T$ | Minimum (resp. maximum) level for storage $s$ also known as "rule-curves" | +| $L_s^0 \in \mathbb{R}_+$ | Initial level for storage $s$ (optional) | +| $P^w_s \in \mathbb{R}_+^T$ | Withdrawal for storage $s$. Note that this is from the storage's perspective : the amount of power withdrawn from the storage | +| $\underline{P}^i_s \in \mathbb{R}^T$, $\overline{P}^i_s \in \mathbb{R}^T$ | Minimum (resp. maximum) injection for storage $s$ | +| $\eta^i_s \in [0, 1]$ | Injection efficiency for storage $s$ | +| $P^i_s \in \mathbb{R}_+^T$ | Injection for storage $s$. Note that this is from the storage's perspective : the amount of power injected into the storage | +| $\underline{P}^w_s \in \mathbb{R}^T$, $\overline{P}^w_s \in \mathbb{R}^T$ | Minimum (resp. maximum) withdrawal for storage $s$ | +| $\eta^w_s \in [0, 1]$ | Withdrawal efficiency for storage $s$ | +| $I_s \in \mathbb{R}^T$ | Inflows for storage $s$. Energy that is injected into the storage over time | + ### Binding constraints In problems $\mathcal{P}^k$, the need for a versatile modelling of the power system calls for the introduction of an arbitrary number of linear binding constraints between system's variables throughout the grid, expressed either in terms of hourly power, daily energies or weekly energies. @@ -261,12 +276,45 @@ $\Omega\_{\mathrm{unit com}}$ is the expression derived from $\Omega\_{\mathrm{d ## Constraints related to the nominal system state +### Short-term storage +Level equation. For each short-term storage $s\in\mathcal{S}$, + +$$ +L_s(t) - L_s(t-1) = \eta^i_s * P^i_s(t) - \eta^w_s * P^w_s(t) + I_s(t) +$$ + +Note that in this equation, time-steps are cycled. From now on, time indices are omitted for simplicity. + +Bounded level + +$$ +0 \leq \underline{L}_s \leq L_s \leq \overline{L}_s +$$ + +Bounded injection + +$$ +\underline{P}^i_s \leq P^i_s \leq \overline{P^i}_s +$$ + +Bounded withdrawal + +$$ +\underline{P}^w_s \leq P^w_s \leq \overline{P^w}_s +$$ + +Initial level (optional) + +$$ +L_s(0) = L_s^0 +$$ + ### Balance between load and generation: First Kirchhoff's law: $$ -\forall n \in N, \sum\_{l \in L\_n^+} F_l - \sum\_{l \in L\_n^-} F_l = \left( G\_n^+ + \sum\_{\lambda \in \Lambda\_n}(H\_\lambda - \Pi\_\lambda) + \sum\_{\theta \ \in \Theta\_n} P\_\theta\right)-(G\_n^-+D\_n) +\forall n \in N, \sum\_{l \in L\_n^+} F_l - \sum\_{l \in L\_n^-} F_l = \left( G\_n^+ + \sum\_{\lambda \in \Lambda\_n}(H\_\lambda - \Pi\_\lambda) + \sum\_{\theta \ \in \Theta\_n} P\_\theta + \sum_{s \in \mathcal{S}} \left(P^w_s - P^i_s\right)\right)-(G\_n^-+D\_n) $$ From cb270ed87fbd783beb76c539267ace6057a104b9 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 24 Jul 2024 09:39:33 +0200 Subject: [PATCH 087/127] Remove dynamic manually allocated memory (#2273) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jason Marechal Co-authored-by: Jason Maréchal <45510813+JasonMarechal25@users.noreply.github.com> --- src/analyzer/atsp/correlations.cpp | 14 +- src/libs/antares/correlation/correlation.cpp | 180 ++++++------------ .../include/antares/correlation/correlation.h | 49 +++-- .../antares/study/parts/thermal/cluster.h | 42 ++-- .../study/include/antares/study/sets.h | 8 +- .../study/include/antares/study/sets.hxx | 36 +--- .../study/include/antares/study/study.h | 46 ++--- .../study/include/antares/study/study.hxx | 3 - .../antares/study/parts/thermal/cluster.cpp | 47 ++--- .../study/parts/thermal/cluster_list.cpp | 40 ++-- src/libs/antares/study/study.cpp | 14 +- src/libs/antares/study/study.extra.cpp | 62 +++--- src/solver/constraints-builder/cbuilder.cpp | 55 +++--- .../solver/constraints-builder/cbuilder.h | 52 ++--- src/solver/constraints-builder/load.cpp | 48 ++--- src/solver/ts-generator/availability.cpp | 2 +- src/solver/ts-generator/hydro.cpp | 42 ++-- src/solver/ts-generator/xcast/studydata.cpp | 40 ++-- src/tests/inmemory-study/in-memory-study.cpp | 2 +- .../test-sc-builder-file-save.cpp | 2 +- src/ui/simulator/application/main/main.cpp | 2 +- .../datagrid/renderer/area/thermalprepro.cpp | 2 +- .../windows/correlation/correlation.cpp | 93 +++++---- 23 files changed, 376 insertions(+), 505 deletions(-) diff --git a/src/analyzer/atsp/correlations.cpp b/src/analyzer/atsp/correlations.cpp index af3c800d5c..120d9d8465 100644 --- a/src/analyzer/atsp/correlations.cpp +++ b/src/analyzer/atsp/correlations.cpp @@ -71,7 +71,7 @@ bool ATSP::computeMonthlyCorrelations() Matrix<> tmpNDP; tmpNDP.reset(realAreaCount, realAreaCount); - double* tmpArray = new double[realAreaCount + 1]; + std::vector tmpArray(realAreaCount + 1); // Initialize mapping, to skip areas which has been disabled // the real number of items is `realAreaCount` @@ -342,7 +342,7 @@ bool ATSP::computeMonthlyCorrelations() resultNDP.entry, ID.entry, ID.width, - tmpArray); + tmpArray.data()); if (shrink < 1.) { if (shrink <= -1.) @@ -381,7 +381,7 @@ bool ATSP::computeMonthlyCorrelations() resultNDP.entry, CORR_MNPZ.entry, CORR_MNPZ.width, - tmpArray); + tmpArray.data()); if (shrink < 1.) { if (shrink <= -1.) // CORR_MNPZ is too close to sdp boundary, shrink CORR_MNP instead @@ -393,7 +393,7 @@ bool ATSP::computeMonthlyCorrelations() resultNDP.entry, ID.entry, ID.width, - tmpArray); + tmpArray.data()); if (shrink <= -1.) { logs.error() << "invalid data, can not be processed"; @@ -505,7 +505,7 @@ bool ATSP::computeMonthlyCorrelations() resultNDP.entry, ID.entry, ID.width, - tmpArray); + tmpArray.data()); if (shrink < 1.) { if (shrink <= -1.) @@ -542,7 +542,7 @@ bool ATSP::computeMonthlyCorrelations() resultNDP.entry, CORR_YNPZ.entry, CORR_YNPZ.width, - tmpArray); + tmpArray.data()); if (shrink < 1.) { if (shrink <= -1.) // CORR_YNP is too close to sdp boundary, shrink CORR_YNP instead @@ -554,7 +554,7 @@ bool ATSP::computeMonthlyCorrelations() resultNDP.entry, ID.entry, ID.width, - tmpArray); + tmpArray.data()); if (shrink <= -1.) { logs.error() << "invalid data, can not be processed"; diff --git a/src/libs/antares/correlation/correlation.cpp b/src/libs/antares/correlation/correlation.cpp index 50b4084bf1..efdf3b3769 100644 --- a/src/libs/antares/correlation/correlation.cpp +++ b/src/libs/antares/correlation/correlation.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/correlation/correlation.h" @@ -327,18 +327,10 @@ int InterAreaCorrelationSaveToFile(const Matrix<>* m, const AreaList* l, const c } Correlation::Correlation(): - annual(nullptr), - monthly(nullptr), pMode(modeNone) { } -Correlation::~Correlation() -{ - delete annual; - delete[] monthly; -} - bool Correlation::loadFromFile(Study& study, const AnyString& filename, bool warnings) { #ifndef NDEBUG @@ -397,16 +389,16 @@ void Correlation::internalSaveToINI(Study& study, IO::File::Stream& file) const // mode file << "[general]\nmode = " << ModeToCString(pMode) << "\n\n"; - if (annual) + if (!annual.empty()) { - ExportCorrelationCoefficients(study, *annual, file, "annual"); + ExportCorrelationCoefficients(study, annual, file, "annual"); } else { logs.error() << correlationName << ": the annual correlation coefficients are missing"; } - if (monthly) + if (!monthly.empty()) { for (int month = 0; month < 12; month++) { @@ -428,20 +420,20 @@ bool Correlation::internalLoadFromINITry(Study& study, const IniFile& ini, bool if (JIT::usedFromGUI or pMode == modeAnnual) { - annual = new Matrix<>(); - annual->resize(study.areas.size(), study.areas.size()); - annual->fillUnit(); + annual.clear(); + annual.resize(study.areas.size(), study.areas.size()); + annual.fillUnit(); auto* section = ini.find("annual"); if (section) // the section might be missing { - ReadCorrelationCoefficients(*this, study, *annual, ini, *section, warnings); + ReadCorrelationCoefficients(*this, study, annual, ini, *section, warnings); } } if (JIT::usedFromGUI or pMode == modeMonthly) { - monthly = new Matrix<>[12]; + monthly.resize(12); for (uint i = 0; i < 12; ++i) { monthly[i].resize(study.areas.size(), study.areas.size()); @@ -475,28 +467,18 @@ bool Correlation::internalLoadFromINITry(Study& study, const IniFile& ini, bool void Correlation::reset(Study& study) { - // Clean - if (annual) - { - delete annual; - annual = nullptr; - } - if (monthly) - { - delete[] monthly; - monthly = nullptr; - } + clear(); pMode = modeAnnual; if (JIT::usedFromGUI) { // Reset - annual = new Matrix<>(); - annual->resize(study.areas.size(), study.areas.size()); - annual->fillUnit(); + annual.clear(); + annual.resize(study.areas.size(), study.areas.size()); + annual.fillUnit(); // Preparing the monthly correlation matrices - monthly = new Matrix<>[12]; + monthly.resize(12); for (int i = 0; i < 12; ++i) { monthly[i].resize(study.areas.size(), study.areas.size()); @@ -505,40 +487,21 @@ void Correlation::reset(Study& study) } else { - annual = new Matrix<>(); - annual->resize(study.areas.size(), study.areas.size()); - annual->fillUnit(); + annual.clear(); + annual.resize(study.areas.size(), study.areas.size()); + annual.fillUnit(); } } void Correlation::clear() { - // Clean - if (annual) - { - delete annual; - annual = nullptr; - } - if (monthly) - { - delete[] monthly; - monthly = nullptr; - } + annual.reset(); + monthly.clear(); } bool Correlation::internalLoadFromINI(Study& study, const IniFile& ini, bool warnings) { - // Clean - if (annual) - { - delete annual; - annual = nullptr; - } - if (monthly) - { - delete[] monthly; - monthly = nullptr; - } + clear(); if (!internalLoadFromINITry(study, ini, warnings)) { @@ -546,28 +509,22 @@ bool Correlation::internalLoadFromINI(Study& study, const IniFile& ini, bool war pMode = modeAnnual; if (JIT::usedFromGUI) { - // Reset - annual = new Matrix<>(); - annual->resize(study.areas.size(), study.areas.size()); - annual->fillUnit(); - // Preparing the monthly correlation matrices - monthly = new Matrix<>[12]; + monthly.resize(12); for (int i = 0; i < 12; ++i) { monthly[i].resize(study.areas.size(), study.areas.size()); monthly[i].fillUnit(); } } - else - { - annual = new Matrix<>(); - annual->resize(study.areas.size(), study.areas.size()); - annual->fillUnit(); - } + + annual.clear(); + annual.resize(study.areas.size(), study.areas.size()); + annual.fillUnit(); return false; } + return true; } @@ -600,45 +557,14 @@ void Correlation::set(Matrix<>& m, const Area& from, const Area& to, double v) m[to.index][from.index] = v; } -void Correlation::retrieveMontlyMatrixArray(const Matrix<>* array[12]) const -{ - switch (pMode) - { - case modeAnnual: - { - for (uint i = 0; i != 12; ++i) - { - array[i] = annual; - } - break; - } - case modeMonthly: - { - for (uint i = 0; i != 12; ++i) - { - array[i] = &(monthly[i]); - } - break; - } - default: - { - for (uint i = 0; i != 12; ++i) - { - array[i] = nullptr; - } - return; - } - } -} - uint64_t Correlation::memoryUsage() const { uint64_t r = sizeof(Correlation); - if (annual) + if (!annual.empty()) { - r += annual->memoryUsage(); + r += annual.memoryUsage(); } - if (monthly) + if (!monthly.empty()) { for (uint i = 0; i != 12; ++i) { @@ -651,9 +577,9 @@ uint64_t Correlation::memoryUsage() const bool Correlation::forceReload(bool reload) const { bool ret = true; - if (annual) + if (!annual.empty()) { - ret = annual->forceReload(reload) and ret; + ret = annual.forceReload(reload) and ret; } for (uint i = 0; i != 12; ++i) { @@ -665,9 +591,9 @@ bool Correlation::forceReload(bool reload) const void Correlation::markAsModified() const { - if (annual) + if (!annual.empty()) { - annual->markAsModified(); + annual.markAsModified(); } for (uint i = 0; i != 12; ++i) { @@ -762,8 +688,8 @@ void Correlation::copyFrom(const Correlation& source, // copying the annual correlation matrix std::cout << "ANNUAL\n"; - CopyFromSingleMatrix(*source.annual, - *annual, + CopyFromSingleMatrix(source.annual, + annual, studySource, areaSourceIndex, areaTargetIndex, diff --git a/src/libs/antares/correlation/include/antares/correlation/correlation.h b/src/libs/antares/correlation/include/antares/correlation/correlation.h index 9dc48c5a76..c0ffebe4a0 100644 --- a/src/libs/antares/correlation/include/antares/correlation/correlation.h +++ b/src/libs/antares/correlation/include/antares/correlation/correlation.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #ifndef __ANTARES_LIBS_ARRAY_CORRELATION_H__ #define __ANTARES_LIBS_ARRAY_CORRELATION_H__ @@ -62,7 +62,7 @@ class Correlation final /*! ** \brief Destructor */ - ~Correlation(); + ~Correlation() = default; //@} //! \name Mode @@ -123,11 +123,6 @@ class Correlation final const AreaNameMapping& mapping, const Study& study); - /*! - ** \brief - */ - void retrieveMontlyMatrixArray(const Matrix<>* array[12]) const; - /*! ** \brief Get the amount of memory used the correlation matrices */ @@ -145,9 +140,9 @@ class Correlation final public: //! The correlation matrix for the whole year - Matrix<>* annual; + Matrix<> annual; //! All correlation matrices per month (12) - Matrix<>* monthly; // [12] + std::vector> monthly; // [12] //! The name to displays in logs Yuni::CString<30, false> correlationName; diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h index 7d1ce30bac..9216ac88aa 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h +++ b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #ifndef __ANTARES_LIBS_STUDY_PARTS_THERMAL_CLUSTER_H__ #define __ANTARES_LIBS_STUDY_PARTS_THERMAL_CLUSTER_H__ @@ -115,7 +115,7 @@ class ThermalCluster final: public Cluster, public std::enable_shared_from_this< explicit ThermalCluster(Data::Area* parent); ThermalCluster() = delete; - ~ThermalCluster(); + ~ThermalCluster() = default; /*! ** \brief Invalidate all data associated to the thermal cluster @@ -353,7 +353,7 @@ class ThermalCluster final: public Cluster, public std::enable_shared_from_this< std::vector PthetaInf; //! Data for the preprocessor - PreproAvailability* prepro = nullptr; + std::unique_ptr prepro; /*! ** \brief Production Cost, Market Bid Cost and Marginal Cost Matrixes - Per Hour and per Time diff --git a/src/libs/antares/study/include/antares/study/sets.h b/src/libs/antares/study/include/antares/study/sets.h index 0309916749..414847af2f 100644 --- a/src/libs/antares/study/include/antares/study/sets.h +++ b/src/libs/antares/study/include/antares/study/sets.h @@ -134,7 +134,7 @@ class Sets final */ Sets(const Sets& rhs); //! Destructor - ~Sets(); + ~Sets() = default; //@} //! \name Iterators @@ -155,7 +155,7 @@ class Sets final */ TypePtr add(const IDType& name) { - TypePtr p = new T(); + TypePtr p = std::make_shared(); pMap[name] = p; pOptions[name].reset(name); return p; @@ -269,8 +269,8 @@ class Sets final MapType pMap; MapOptions pOptions; //! - TypePtr* pByIndex; - IDType* pNameByIndex; + std::vector pByIndex; + std::vector pNameByIndex; mutable bool pModified; }; // class Sets diff --git a/src/libs/antares/study/include/antares/study/sets.hxx b/src/libs/antares/study/include/antares/study/sets.hxx index 931e044ba0..2a1b777995 100644 --- a/src/libs/antares/study/include/antares/study/sets.hxx +++ b/src/libs/antares/study/include/antares/study/sets.hxx @@ -27,8 +27,6 @@ namespace Data { template inline Sets::Sets(): - pByIndex(NULL), - pNameByIndex(NULL), pModified(false) { } @@ -37,8 +35,6 @@ template inline Sets::Sets(const Sets& rhs): pMap(rhs.pMap), pOptions(rhs.pOptions), - pByIndex(NULL), - pNameByIndex(NULL), pModified(false) { if (rhs.pByIndex) @@ -47,12 +43,6 @@ inline Sets::Sets(const Sets& rhs): } } -template -inline Sets::~Sets() -{ - delete[] pByIndex; -} - template typename Sets::iterator Sets::begin() { @@ -80,17 +70,8 @@ typename Sets::const_iterator Sets::end() const template void Sets::clear() { - if (pByIndex) - { - delete[] pByIndex; - pByIndex = NULL; - } - if (pNameByIndex) - { - delete[] pNameByIndex; - pNameByIndex = NULL; - } - + pByIndex.clear(); + pNameByIndex.clear(); pMap.clear(); pOptions.clear(); } @@ -401,13 +382,13 @@ void Sets::rebuildFromRules(const IDType& id, HandlerT& handler) template void Sets::rebuildIndexes() { - delete[] pByIndex; - delete[] pNameByIndex; + pNameByIndex.clear(); + pByIndex.clear(); if (!pMap.empty()) { - pByIndex = new TypePtr[pMap.size()]; - pNameByIndex = new IDType[pMap.size()]; + pByIndex.resize(pMap.size()); + pNameByIndex.resize(pMap.size()); const typename MapType::iterator end = pMap.end(); uint index = 0; for (typename MapType::iterator i = pMap.begin(); i != end; ++i) @@ -417,11 +398,6 @@ void Sets::rebuildIndexes() ++index; } } - else - { - pByIndex = NULL; - pNameByIndex = NULL; - } } template diff --git a/src/libs/antares/study/include/antares/study/study.h b/src/libs/antares/study/include/antares/study/study.h index 65f8f531fd..d8a187f9f9 100644 --- a/src/libs/antares/study/include/antares/study/study.h +++ b/src/libs/antares/study/include/antares/study/study.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #ifndef __ANTARES_LIBS_STUDY_STUDY_H__ #define __ANTARES_LIBS_STUDY_STUDY_H__ @@ -363,8 +363,6 @@ class Study: public Yuni::NonCopyable, public LayerData void destroyAllWindTSGeneratorData(); //! Destroy all data of the hydro TS generator void destroyAllHydroTSGeneratorData(); - //! Destroy all data of the thermal TS generator - void destroyAllThermalTSGeneratorData(); /*! ** \brief Import all time-series into the input folder @@ -391,10 +389,6 @@ class Study: public Yuni::NonCopyable, public LayerData ** \brief Re-Initialize/Re-Load the scenario builder data */ void scenarioRulesCreate(); - /*! - ** \brief Re-Initialize/Re-Load the scenario builder data but consider a single ruleset only - */ - void scenarioRulesCreate(const RulesScenarioName& thisoneonly); /*! ** \brief Release the scenario builder @@ -586,7 +580,7 @@ class Study: public Yuni::NonCopyable, public LayerData //! \name Scenario Builder //@{ //! Rules for building scenarios (can be null) - ScenarioBuilder::Sets* scenarioRules = nullptr; + std::unique_ptr scenarioRules; //@} TimeSeries::TS scenarioInitialHydroLevels; diff --git a/src/libs/antares/study/include/antares/study/study.hxx b/src/libs/antares/study/include/antares/study/study.hxx index 9f0053d0a4..5c1ad58282 100644 --- a/src/libs/antares/study/include/antares/study/study.hxx +++ b/src/libs/antares/study/include/antares/study/study.hxx @@ -53,9 +53,6 @@ inline void Study::destroyTSGeneratorData() case TimeSeriesType::timeSeriesHydro: destroyAllHydroTSGeneratorData(); break; - case TimeSeriesType::timeSeriesThermal: - destroyAllThermalTSGeneratorData(); - break; default: break; } diff --git a/src/libs/antares/study/parts/thermal/cluster.cpp b/src/libs/antares/study/parts/thermal/cluster.cpp index da502ac29e..9198bc1ec6 100644 --- a/src/libs/antares/study/parts/thermal/cluster.cpp +++ b/src/libs/antares/study/parts/thermal/cluster.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/study/parts/thermal/cluster.h" @@ -129,11 +129,6 @@ Data::ThermalCluster::ThermalCluster(Area* parent): assert(parent && "A parent for a thermal dispatchable cluster can not be null"); } -Data::ThermalCluster::~ThermalCluster() -{ - delete prepro; -} - uint ThermalCluster::groupId() const { return groupID; @@ -202,7 +197,7 @@ void Data::ThermalCluster::copyFrom(const ThermalCluster& cluster) // prepro if (!prepro) { - prepro = new PreproAvailability(id(), unitCount); + prepro = std::make_unique(id(), unitCount); } prepro->copyFrom(*cluster.prepro); @@ -477,7 +472,7 @@ void Data::ThermalCluster::reset() // we must simply reset their content. if (!prepro) { - prepro = new PreproAvailability(id(), unitCount); + prepro = std::make_unique(id(), unitCount); } prepro->reset(); diff --git a/src/libs/antares/study/parts/thermal/cluster_list.cpp b/src/libs/antares/study/parts/thermal/cluster_list.cpp index 8435870d0a..1b46282504 100644 --- a/src/libs/antares/study/parts/thermal/cluster_list.cpp +++ b/src/libs/antares/study/parts/thermal/cluster_list.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/study/parts/thermal/cluster_list.h" @@ -388,7 +388,7 @@ void ThermalClusterList::ensureDataPrepro() { if (!c->prepro) { - c->prepro = new PreproAvailability(c->id(), c->unitCount); + c->prepro = std::make_unique(c->id(), c->unitCount); } } } diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 01d91b3abb..2ef5ccc5dd 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -104,7 +104,7 @@ Study::~Study() void Study::clear() { - FreeAndNil(scenarioRules); + scenarioRules.reset(); FreeAndNil(uiinfo); // areas @@ -1104,18 +1104,6 @@ void Study::destroyAllWindTSGeneratorData() areas.each([](Data::Area& area) { FreeAndNil(area.wind.prepro); }); } -void Study::destroyAllThermalTSGeneratorData() -{ - areas.each( - [](const Data::Area& area) - { - for (const auto& cluster: area.thermal.list.each_enabled_and_not_mustrun()) - { - FreeAndNil(cluster->prepro); - } - }); -} - void Study::ensureDataAreLoadedForAllBindingConstraints() { for (const auto& constraint: bindingConstraints) diff --git a/src/libs/antares/study/study.extra.cpp b/src/libs/antares/study/study.extra.cpp index 1ec628c321..fdfb6eb2d3 100644 --- a/src/libs/antares/study/study.extra.cpp +++ b/src/libs/antares/study/study.extra.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/study/study.h" @@ -35,32 +35,16 @@ String StudyIconFile; void Study::scenarioRulesCreate() { // releasing the previous instance of the scenario builder - delete scenarioRules; + scenarioRules.reset(); // When ran from the solver, the scenario builder must be present - scenarioRules = new ScenarioBuilder::Sets(); - scenarioRules->loadFromStudy(*this); -} - -void Study::scenarioRulesCreate(const RulesScenarioName& /*thisoneonly*/) -{ - // releasing the previous instance of the scenario builder - delete scenarioRules; - // When ran from the solver, the scenario builder must be present - scenarioRules = new ScenarioBuilder::Sets(); + scenarioRules = std::make_unique(); scenarioRules->loadFromStudy(*this); } void Study::scenarioRulesDestroy() { - if (scenarioRules) - { - // releasing the previous instance of the scenario builder - // safety dereferencing for the interface if running - ScenarioBuilder::Sets* sb = scenarioRules; - scenarioRules = nullptr; - delete sb; - } + scenarioRules.reset(); } void Study::scenarioRulesLoadIfNotAvailable() @@ -68,7 +52,7 @@ void Study::scenarioRulesLoadIfNotAvailable() if (!scenarioRules) { // When ran from the solver, the scenario builder must be present - scenarioRules = new ScenarioBuilder::Sets(); + scenarioRules = std::make_unique(); scenarioRules->loadFromStudy(*this); } } diff --git a/src/solver/constraints-builder/cbuilder.cpp b/src/solver/constraints-builder/cbuilder.cpp index 2a1e1b8dce..5c02947a6f 100644 --- a/src/solver/constraints-builder/cbuilder.cpp +++ b/src/solver/constraints-builder/cbuilder.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/constraints-builder/cbuilder.h" @@ -54,15 +54,6 @@ CBuilder::CBuilder(Antares::Data::Study& study): { } -CBuilder::~CBuilder() -{ - // delete all the elements of pLink - for (auto i = pLink.begin(); i != pLink.end(); i++) - { - delete *i; - } -} - bool Antares::CBuilder::isCycleDriver(linkInfo* lnkI) { std::string s1(lnkI->ptr->from->name.to()); @@ -180,7 +171,7 @@ bool CBuilder::updateLinks() } // check validity of loopflow against NTC - if (includeLoopFlow && !checkValidityOfNodalLoopFlow(linkInfo, hour)) + if (includeLoopFlow && !checkValidityOfNodalLoopFlow(linkInfo.get(), hour)) { return false; } @@ -190,8 +181,8 @@ bool CBuilder::updateLinks() continue; } - updateLinkPhaseShift(linkInfo, hour); - if (!checkLinkPhaseShift(linkInfo, hour)) + updateLinkPhaseShift(linkInfo.get(), hour); + if (!checkLinkPhaseShift(linkInfo.get(), hour)) { return false; } @@ -239,7 +230,7 @@ bool CBuilder::update() && ((*linkInfoIt)->type == Antares::Data::atAC /*|| (*linkInfoIt)->type == linkInfo::tyACPST*/)) { - enabledACLines.push_back(*linkInfoIt); + enabledACLines.push_back((*linkInfoIt).get()); } } diff --git a/src/solver/constraints-builder/include/antares/solver/constraints-builder/cbuilder.h b/src/solver/constraints-builder/include/antares/solver/constraints-builder/cbuilder.h index 833f9e82e6..29ddd2b4c5 100644 --- a/src/solver/constraints-builder/include/antares/solver/constraints-builder/cbuilder.h +++ b/src/solver/constraints-builder/include/antares/solver/constraints-builder/cbuilder.h @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #ifndef __ANTARES_CONSTRAINTSBUILDER_BUILDER_CBUILDER_H__ #define __ANTARES_CONSTRAINTSBUILDER_BUILDER_CBUILDER_H__ @@ -231,7 +231,7 @@ class CBuilder final */ CBuilder(Antares::Data::Study&); //! Destructor - ~CBuilder(); + ~CBuilder() = default; //@} /*! @@ -262,7 +262,7 @@ class CBuilder final { auto linkIT = std::find_if(pLink.begin(), pLink.end(), - [&u, &v](const linkInfo* edgeP) -> bool + [&u, &v](std::shared_ptr edgeP) -> bool { if (edgeP->ptr->from->id == u && edgeP->ptr->with->id == v) { @@ -279,7 +279,7 @@ class CBuilder final }); if (linkIT != pLink.end()) { - return *linkIT; + return linkIT->get(); } return nullptr; @@ -294,11 +294,11 @@ class CBuilder final auto a = area.second; std::for_each(pLink.begin(), pLink.end(), - [&a, this](linkInfo* edgeP) + [&a, this](std::shared_ptr edgeP) { if (edgeP->ptr->from == a || edgeP->ptr->with == a) { - this->areaToLinks[a].insert(edgeP); + this->areaToLinks[a].insert(edgeP.get()); } }); } @@ -308,7 +308,7 @@ class CBuilder final { if (i < pLink.size()) { - return pLink[i]; + return pLink[i].get(); } return nullptr; } @@ -418,7 +418,7 @@ class CBuilder final const double& secondMember); public: - Vector pLink; + std::vector> pLink; private: std::string pPrefix; diff --git a/src/solver/constraints-builder/load.cpp b/src/solver/constraints-builder/load.cpp index 22d8632cda..73beec49c1 100644 --- a/src/solver/constraints-builder/load.cpp +++ b/src/solver/constraints-builder/load.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include #include @@ -43,18 +43,18 @@ bool CBuilder::completeFromStudy() { // for all links of the study // check if it has been enabled in the INI File - linkInfo* k = findLinkInfoFromNodeNames(j->second->from->id, j->second->with->id); + auto k = findLinkInfoFromNodeNames(j->second->from->id, j->second->with->id); if (!k) { - k = new linkInfo(); + auto infos = std::make_shared(); logs.info() << "Read data (link " << nCount++ << ")"; // if Yes, complete the linkInfo // load the pointer - k->ptr = j->second; - k->type = k->ptr->assetType; + infos->ptr = j->second; + infos->type = infos->ptr->assetType; - pLink.push_back(k); + pLink.push_back(infos); } } } diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index a94fd99e46..1ac5e7675b 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -38,7 +38,7 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* c plannedVolatility(cluster->plannedVolatility), forcedLaw(cluster->forcedLaw), plannedLaw(cluster->plannedLaw), - prepro(cluster->prepro), + prepro(cluster->prepro.get()), modulationCapacity(cluster->modulation[Data::thermalModulationCapacity]), name(cluster->name()) { diff --git a/src/solver/ts-generator/hydro.cpp b/src/solver/ts-generator/hydro.cpp index 168b290dfb..c5c2601bed 100644 --- a/src/solver/ts-generator/hydro.cpp +++ b/src/solver/ts-generator/hydro.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include @@ -80,7 +80,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu double** nullmatrx = nullptr; if (1. > Solver::MatrixDPMake(CHSKY.entry, - study.preproHydroCorrelation.annual->entry, + study.preproHydroCorrelation.annual.entry, B.entry, nullmatrx, study.areas.size(), @@ -100,7 +100,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu auto& corre = CORRE[i]; - auto& annualCorrAreaI = (*study.preproHydroCorrelation.annual)[areaIndexI]; + auto& annualCorrAreaI = study.preproHydroCorrelation.annual[areaIndexI]; for (uint j = 0; j < DIM; j++) { diff --git a/src/solver/ts-generator/xcast/studydata.cpp b/src/solver/ts-generator/xcast/studydata.cpp index 217f61fe14..c6bbd15b4e 100644 --- a/src/solver/ts-generator/xcast/studydata.cpp +++ b/src/solver/ts-generator/xcast/studydata.cpp @@ -1,23 +1,23 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "antares/solver/ts-generator/xcast/studydata.h" @@ -93,7 +93,7 @@ void StudyData::reloadDataFromAreaList(const Data::Correlation& originalCorrelat case Data::Correlation::modeAnnual: { auto* m = new Matrix(); - prepareMatrix(*m, *(originalCorrelation.annual)); + prepareMatrix(*m, originalCorrelation.annual); for (uint realmonth = 0; realmonth != 12; ++realmonth) { diff --git a/src/tests/inmemory-study/in-memory-study.cpp b/src/tests/inmemory-study/in-memory-study.cpp index 1f3f78c194..cfe1c1d130 100644 --- a/src/tests/inmemory-study/in-memory-study.cpp +++ b/src/tests/inmemory-study/in-memory-study.cpp @@ -172,7 +172,7 @@ averageResults OutputRetriever::thermalNbUnitsON(ThermalCluster* cluster) ScenarioBuilderRule::ScenarioBuilderRule(Study& study) { study.scenarioRulesCreate(); - ScenarioBuilder::Sets* sets = study.scenarioRules; + auto sets = study.scenarioRules.get(); if (sets && !sets->empty()) { rules_ = sets->createNew("Custom"); diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp index 64813637fc..e9a410b983 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp @@ -188,7 +188,7 @@ struct commonFixture study->bindingConstraintsGroups.add("group3"); // Scenario builder initialization - study->scenarioRules = new ScenarioBuilder::Sets(); + study->scenarioRules = std::make_unique(); study->scenarioRules->setStudy(*study); my_rule = study->scenarioRules->createNew("my rule name"); BOOST_CHECK(my_rule->reset()); diff --git a/src/ui/simulator/application/main/main.cpp b/src/ui/simulator/application/main/main.cpp index 3b321e6c12..31865edc53 100644 --- a/src/ui/simulator/application/main/main.cpp +++ b/src/ui/simulator/application/main/main.cpp @@ -702,7 +702,7 @@ void ApplWnd::onSectionNotebookPageChanging(Component::Notebook::Page& page) auto* job = new JobLoadScenarioBuilder(*study); wxTheApp->Yield(); job->run(); - study->scenarioRules = job->scenarioBuilder(); + study->scenarioRules.reset(job->scenarioBuilder()); job->Destroy(); } diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.cpp index 4c39002613..d169a59f91 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.cpp @@ -183,7 +183,7 @@ bool ThermalClusterPrepro::cellValue(int x, int y, const String& value) void ThermalClusterPrepro::internalThermalClusterChanged(Antares::Data::ThermalCluster* cluster) { pCluster = cluster; - pPreproAvailability = (cluster) ? cluster->prepro : nullptr; + pPreproAvailability = (cluster) ? cluster->prepro.get() : nullptr; MatrixAncestorType::matrix((pPreproAvailability) ? &pPreproAvailability->data : nullptr); onRefresh(); } diff --git a/src/ui/simulator/windows/correlation/correlation.cpp b/src/ui/simulator/windows/correlation/correlation.cpp index 762479f64e..110182bbde 100644 --- a/src/ui/simulator/windows/correlation/correlation.cpp +++ b/src/ui/simulator/windows/correlation/correlation.cpp @@ -1,36 +1,37 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ #include "correlation.h" + +#include +#include + +#include + #include "../../application/study.h" -#include "../../toolbox/components/notebook/notebook.h" #include "../../toolbox/components/datagrid/component.h" #include "../../toolbox/components/datagrid/renderer/correlation.h" +#include "../../toolbox/components/notebook/notebook.h" #include "../../toolbox/components/refresh.h" -#include #include "../../toolbox/resources.h" - -#include -#include - #include "datasources.hxx" using namespace Yuni; @@ -45,12 +46,17 @@ class CorrelationPanelData final using CorrelationMatrixType = Component::Datagrid::Renderer::CorrelationMatrix; public: - CorrelationPanelData() : pCorrelation(nullptr) + CorrelationPanelData(): + pCorrelation(nullptr) { for (uint i = 0; i != 12; ++i) + { pGridMonthly[i] = nullptr; + } for (uint i = 0; i != 12 + 1; ++i) + { renderer[i] = nullptr; + } } public: @@ -62,7 +68,8 @@ class CorrelationPanelData final CorrelationMatrixType::IDatasource::Ptr datasource; }; -CorrelationPanel::CorrelationPanel(wxWindow* parent, int timeseries) : wxPanel(parent, wxID_ANY) +CorrelationPanel::CorrelationPanel(wxWindow* parent, int timeseries): + wxPanel(parent, wxID_ANY) { // Init pData = new CorrelationPanelData(); @@ -113,8 +120,9 @@ CorrelationPanel::CorrelationPanel(wxWindow* parent, int timeseries) : wxPanel(p }; #endif - btn - = Resources::BitmapButtonLoadFromFile(panel, wxID_ANY, "images/16x16/sort_alphabet.png"); + btn = Resources::BitmapButtonLoadFromFile(panel, + wxID_ANY, + "images/16x16/sort_alphabet.png"); btn->Connect(btn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CorrelationPanel::onSortAlpha), @@ -123,8 +131,9 @@ CorrelationPanel::CorrelationPanel(wxWindow* parent, int timeseries) : wxPanel(p panel->GetSizer()->Add(btn, 0, wxALL | wxEXPAND, margin); // Sort - reverse - btn = Resources::BitmapButtonLoadFromFile( - panel, wxID_ANY, "images/16x16/sort_alphabet_descending.png"); + btn = Resources::BitmapButtonLoadFromFile(panel, + wxID_ANY, + "images/16x16/sort_alphabet_descending.png"); btn->Connect(btn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CorrelationPanel::onSortAlphaReverse), @@ -145,8 +154,8 @@ CorrelationPanel::CorrelationPanel(wxWindow* parent, int timeseries) : wxPanel(p { for (uint i = 0; i != 12; ++i) { - pData->pGridMonthly[i] - = new Component::Datagrid::Component(notebook, pData->renderer[i]); + pData->pGridMonthly[i] = new Component::Datagrid::Component(notebook, + pData->renderer[i]); pData->renderer[i]->control(pData->pGridMonthly[i]); notebook->add(pData->pGridMonthly[i], months[i]); } @@ -192,7 +201,9 @@ CorrelationPanel::~CorrelationPanel() // we should destroy all children as soon as possible. wxSizer* sizer = GetSizer(); if (sizer) + { sizer->Clear(true); + } } void CorrelationPanel::onStudyLoaded() @@ -226,7 +237,9 @@ void CorrelationPanel::reload() { assignMatrices(nullptr); if (not pData) + { return; + } pData->datasource->reload(); @@ -256,12 +269,16 @@ void CorrelationPanel::reload() // It is useless to reassign matrices since they are already // assigned to null if (pData->pCorrelation) + { assignMatrices(pData->pCorrelation); + } // Force refresh RefreshAllControls(pData->pGridAnnual); for (uint i = 0; i != 12; ++i) + { RefreshAllControls(pData->pGridMonthly[i]); + } } void CorrelationPanel::updateAllDatasources() @@ -270,13 +287,17 @@ void CorrelationPanel::updateAllDatasources() for (uint i = 0; i != 12 + 1; ++i) { if (pData->renderer[i]) + { pData->renderer[i]->datasource(pData->datasource); + } } for (uint i = 0; i != 12; ++i) { if (pData->pGridMonthly[i]) + { pData->pGridMonthly[i]->forceRefresh(); + } } pData->pGridAnnual->forceRefresh(); } @@ -308,7 +329,9 @@ void CorrelationPanel::assignMatrices(Data::Correlation* corr) for (uint i = 0; i < 12 + 1; ++i) { if (pData->renderer) + { pData->renderer[i]->matrix(nullptr); + } } } else @@ -316,9 +339,11 @@ void CorrelationPanel::assignMatrices(Data::Correlation* corr) for (uint i = 0; i < 12; ++i) { if (pData->renderer[i]) + { pData->renderer[i]->matrix(&(corr->monthly[i])); + } } - pData->renderer[12]->matrix(corr->annual); + pData->renderer[12]->matrix(&corr->annual); } } } From b8c828585e000431d2e3aef51ae4a311e9e3433e Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Thu, 25 Jul 2024 11:41:14 +0200 Subject: [PATCH 088/127] Add short test to coverage analysis (#2280) - Add "short-tests" study batch to coverage analysis - Use Release build type for SonarCloud CI (previously Debug) to avoid saturating the RAM on GH runners (Debug + Coverage instrumentation is a bit too much) - (minor) Display error code in case of failure for study tests --------- Co-authored-by: Florian OMNES --- .github/workflows/sonarcloud.yml | 22 +++++++++++++++++-- .../actions_on_study/study_run.py | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 2b3ca8137a..c5bbc5a473 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -79,6 +79,16 @@ jobs: python -m pip install --upgrade pip pip3 install -r src/tests/examples/requirements.txt + - name: Read simtest version + run: | + echo 'SIMTEST_JSON<> $GITHUB_ENV + cat ./simtest.json >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV + + - name: Export simtest version + run: | + echo "SIMTEST=${{ fromJson(env.SIMTEST_JSON).version }}" >> $GITHUB_ENV + - name: Init submodule run: | git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests @@ -93,7 +103,7 @@ jobs: -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ -DVCPKG_TARGET_TRIPLET=x64-linux-release \ -DCODE_COVERAGE=ON \ - -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_PREFIX_PATH="../install;${{ env.ORTOOLS_DIR }}/install" \ -DBUILD_TESTING=ON \ -DMZ_CODE_COVERAGE=ON \ @@ -102,7 +112,7 @@ jobs: - name: Build run: | - build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build _build --config release -j$(nproc) + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build _build --config Release -j$(nproc) - name: Test and generate coverage continue-on-error: true @@ -110,6 +120,14 @@ jobs: cd $GITHUB_WORKSPACE/_build ctest -C Release --output-on-failure -L "unit" + - name: Run short-tests + continue-on-error: true + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{ env.SIMTEST }} + batch-name: short-tests + os: ${{ matrix.os }} + - name: Collect coverage into one XML report run: | gcovr --sonarqube --output coverage.xml diff --git a/src/tests/run-study-tests/actions_on_study/study_run.py b/src/tests/run-study-tests/actions_on_study/study_run.py index 9abafdb066..8867aafda5 100644 --- a/src/tests/run-study-tests/actions_on_study/study_run.py +++ b/src/tests/run-study-tests/actions_on_study/study_run.py @@ -39,7 +39,7 @@ def run(self): if not self.raise_exception_on_failure: return - check(self.return_code == 0, "Solver returned error") + check(self.success(), f"Solver returned error {self.return_code}") def get_return_code(self): From 0359290635737189ff74e74e2c87a4949743b18f Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:22:59 +0200 Subject: [PATCH 089/127] Add unit tests to see coverage increase (#2267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Florian Omnès --- src/libs/antares/study/study.cpp | 1 + .../src/libs/antares/study/test_study.cpp | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 2ef5ccc5dd..faafdcde31 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -1309,6 +1309,7 @@ void Study::resizeAllTimeseriesNumbers(uint n) bindingConstraintsGroups.resizeAllTimeseriesNumbers(n); } +// TODO VP: Could be removed with the GUI bool Study::checkForFilenameLimits(bool output, const String& chfolder) const { enum diff --git a/src/tests/src/libs/antares/study/test_study.cpp b/src/tests/src/libs/antares/study/test_study.cpp index 0ecb082cd1..e2d2714037 100644 --- a/src/tests/src/libs/antares/study/test_study.cpp +++ b/src/tests/src/libs/antares/study/test_study.cpp @@ -291,4 +291,24 @@ BOOST_AUTO_TEST_CASE(version_parsing) BOOST_CHECK(!v.fromString("4.5")); BOOST_CHECK(v == StudyVersion::unknown()); } + +BOOST_FIXTURE_TEST_CASE(check_filename_limit, OneAreaStudy) +{ + auto s = std::make_unique(); + BOOST_CHECK(s->checkForFilenameLimits(true)); // empty areas should return true + + BOOST_CHECK(study->checkForFilenameLimits(true)); + BOOST_CHECK(study->checkForFilenameLimits(false)); + BOOST_CHECK(study->checkForFilenameLimits(true, "abc")); + +#ifdef YUNI_OS_WINDOWS + std::string area1name(128, 'a'); + std::string area2name(128, 'b'); + auto areaB = study->areaAdd(area1name); + auto areaC = study->areaAdd(area2name); + AreaAddLinkBetweenAreas(areaB, areaC); + BOOST_CHECK(!study->checkForFilenameLimits(true)); +#endif +} + BOOST_AUTO_TEST_SUITE_END() // version From abc0c85f765ca2a2e91b2fe41a75fa7209698283 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Thu, 25 Jul 2024 16:45:28 +0200 Subject: [PATCH 090/127] Feature/test name translator (#2285) --- .../src/solver/optimisation/CMakeLists.txt | 3 +- .../name-translator/CMakeLists.txt | 20 ++++ .../name-translator/test_name_translator.cpp | 103 ++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/tests/src/solver/optimisation/name-translator/CMakeLists.txt create mode 100644 src/tests/src/solver/optimisation/name-translator/test_name_translator.cpp diff --git a/src/tests/src/solver/optimisation/CMakeLists.txt b/src/tests/src/solver/optimisation/CMakeLists.txt index d3b9a9a82e..90e70d52b7 100644 --- a/src/tests/src/solver/optimisation/CMakeLists.txt +++ b/src/tests/src/solver/optimisation/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(adequacy_patch) -add_subdirectory(translator) \ No newline at end of file +add_subdirectory(translator) +add_subdirectory(name-translator) \ No newline at end of file diff --git a/src/tests/src/solver/optimisation/name-translator/CMakeLists.txt b/src/tests/src/solver/optimisation/name-translator/CMakeLists.txt new file mode 100644 index 0000000000..f5e1f0619d --- /dev/null +++ b/src/tests/src/solver/optimisation/name-translator/CMakeLists.txt @@ -0,0 +1,20 @@ +set(EXECUTABLE_NAME test-name-translator) +add_executable(${EXECUTABLE_NAME}) + +target_sources(${EXECUTABLE_NAME} + PRIVATE + test_name_translator.cpp +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + model_antares +) + +# Storing tests-ts-numbers under the folder Unit-tests in the IDE +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) + +add_test(NAME test-name-translator COMMAND ${EXECUTABLE_NAME}) + +set_property(TEST test-name-translator PROPERTY LABELS unit) diff --git a/src/tests/src/solver/optimisation/name-translator/test_name_translator.cpp b/src/tests/src/solver/optimisation/name-translator/test_name_translator.cpp new file mode 100644 index 0000000000..7819f7f3e1 --- /dev/null +++ b/src/tests/src/solver/optimisation/name-translator/test_name_translator.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define BOOST_TEST_MODULE test_name_translator +#define WIN32_LEAN_AND_MEAN + +#include + +#include + +#include "antares/solver/utils/name_translator.h" + +BOOST_AUTO_TEST_SUITE(translations) + +BOOST_AUTO_TEST_CASE(ReturnedNullName) +{ + auto nul_names = NameTranslator::create(false); + auto* base_ptr = nul_names.get(); + const auto& expected_type_info = typeid(NullName); + BOOST_CHECK(expected_type_info == typeid(*base_ptr)); +} + +BOOST_AUTO_TEST_CASE(ReturnedRealName) +{ + auto real_names = NameTranslator::create(true); + auto* base_ptr = real_names.get(); + const auto& expected_type_info = typeid(RealName); + + BOOST_CHECK(expected_type_info == typeid(*base_ptr)); +} + +BOOST_AUTO_TEST_CASE(NullNameIsNotRealName) +{ + auto real_names = NameTranslator::create(true); + auto* base_ptr = real_names.get(); + const auto& expected_type_info = typeid(NullName); + + BOOST_CHECK(expected_type_info != typeid(*base_ptr)); +} + +BOOST_AUTO_TEST_CASE(NullNameWithEmptyInput) +{ + auto nul_names = NameTranslator::create(false); + std::vector names; + std::vector names_ptr; + BOOST_CHECK(nul_names->translate(names, names_ptr) == names_ptr.data()); + // size of names_ptr has not changed + BOOST_CHECK(0 == names_ptr.size()); +} + +BOOST_AUTO_TEST_CASE(NullNameWith2Names) +{ + auto nul_names = NameTranslator::create(false); + std::vector names{"name1", "name2"}; + std::vector names_ptr; + BOOST_CHECK(nul_names->translate(names, names_ptr) == names_ptr.data()); + // size of names_ptr should be updated to names.size() + BOOST_CHECK(names.size() == names_ptr.size()); + BOOST_CHECK(names_ptr[0] == nullptr); + BOOST_CHECK(names_ptr[1] == nullptr); +} + +BOOST_AUTO_TEST_CASE(RealNameWithEmptyInput) +{ + auto nul_names = NameTranslator::create(true); + std::vector names; + std::vector names_ptr; + BOOST_CHECK(nul_names->translate(names, names_ptr) == names_ptr.data()); + // size of names_ptr has not changed + BOOST_CHECK(0 == names_ptr.size()); +} + +BOOST_AUTO_TEST_CASE(RealNameWith2Names) +{ + auto nul_names = NameTranslator::create(true); + std::vector names{"name1", "name2"}; + std::vector names_ptr; + BOOST_CHECK(nul_names->translate(names, names_ptr) == names_ptr.data()); + // size of names_ptr should be updated to names.size() + BOOST_CHECK(names.size() == names_ptr.size()); + BOOST_CHECK(names_ptr[0] == names[0]); + BOOST_CHECK(names_ptr[1] == names[1]); +} + +BOOST_AUTO_TEST_SUITE_END() From 6f412e7a704e5de58823c767d546f70f813e280e Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 25 Jul 2024 16:53:05 +0200 Subject: [PATCH 091/127] Use a formula for the number of cores used (#2284) close #2266 --- docs/developer-guide/CHANGELOG.md | 6 + .../optional-features/multi-threading.md | 57 +++++-- .../study/include/antares/study/study.h | 2 +- src/libs/antares/study/study.cpp | 140 +++--------------- .../src/libs/antares/study/test_study.cpp | 13 ++ 5 files changed, 80 insertions(+), 138 deletions(-) diff --git a/docs/developer-guide/CHANGELOG.md b/docs/developer-guide/CHANGELOG.md index 7309cad241..cc4ffbd741 100644 --- a/docs/developer-guide/CHANGELOG.md +++ b/docs/developer-guide/CHANGELOG.md @@ -3,6 +3,12 @@ toc_depth: 2 --- # Antares Changelog + +## Branch 9.2.x +### 9.2.0 + +* Changed the formula for the number of cores [details](../user-guide/solver/optional-features/multi-threading.md) + ## Branch 9.1.x ### 9.1.0 (06/2024) diff --git a/docs/user-guide/solver/optional-features/multi-threading.md b/docs/user-guide/solver/optional-features/multi-threading.md index c2c13bee46..5d126a6672 100644 --- a/docs/user-guide/solver/optional-features/multi-threading.md +++ b/docs/user-guide/solver/optional-features/multi-threading.md @@ -24,21 +24,9 @@ This parameter can take five different values (Minimum, Low, Medium, High, Maxim The number of independent processes resulting from the combination (local hardware + study settings) is given in the following table, which shows the CPU allowances granted in the different configurations. -| _Available CPU Cores_ | _Minimum_ | _Low_ | _Medium_ | _Large_ | _Maximum_ | -|:---------------------:|:---------:|:---------:|:---------:|:----------:|:---------:| -| _1_ | 1 | 1 | 1 | 1 | 1 | -| _2_ | 1 | 1 | 1 | 2 | 2 | -| _3_ | 1 | 2 | 2 | 2 | 3 | -| _4_ | 1 | 2 | 2 | 3 | 4 | -| _5_ | 1 | 2 | 3 | 4 | 5 | -| _6_ | 1 | 2 | 3 | 4 | 6 | -| _7_ | 1 | 2 | 3 | 5 | 7 | -| _8_ | 1 | 2 | 4 | 6 | 8 | -| _9_ | 1 | 3 | 5 | 7 | 8 | -| _10_ | 1 | 3 | 5 | 8 | 9 | -| _11_ | 1 | 3 | 6 | 8 | 10 | -| _12_ | 1 | 3 | 6 | 9 | 11 | -| _S > 12_ | 1 | Ceil(S/4) | Ceil(S/2) | Ceil(3S/4) | S-1 | +| _Minimum_ | _Low_ | _Medium_ | _High_ | _Maximum_ | +|:---------:|:---------:|:---------:|:----------:|:---------:| +| 1 | Ceil(S/4) | Ceil(S/2) | Ceil(3S/4) | S | **Note**: The number of independent threads actually launched by Antares in parallel mode may appear smaller than that shown in the table above. In this case, the resources monitor menu and the dashboard displayed on starting the simulation indicates: @@ -54,6 +42,45 @@ Examples of reduction from an initial allowance of 12 cores are given hereafter. The Table indicates either the refresh status (No) or the refresh span (the associated refresh status "yes" is implicit). +## Formula for CPU cores + +Starting from 9.2 we changed the formula for the number of cores to simplify. Here's the old values and the new ones. + +### Starting from 9.2 + +-| _Available CPU Cores_ | _Minimum_ | _Low_ | _Medium_ | _High_ | _Maximum_ | +-|:---------------------:|:---------:|:---------:|:---------:|:----------:|:---------:| +-| _1_ | 1 | 1 | 1 | 1 | 1 | +-| _2_ | 1 | 1 | 1 | 2 | 2 | +-| _3_ | 1 | 1 | 2 | 3 | 3 | +-| _4_ | 1 | 1 | 2 | 3 | 4 | +-| _5_ | 1 | 2 | 3 | 4 | 5 | +-| _6_ | 1 | 2 | 3 | 5 | 6 | +-| _7_ | 1 | 2 | 4 | 6 | 7 | +-| _8_ | 1 | 2 | 4 | 6 | 8 | +-| _9_ | 1 | 3 | 5 | 7 | 9 | +-| _10_ | 1 | 3 | 5 | 8 | 10 | +-| _11_ | 1 | 3 | 6 | 9 | 11 | +-| _12_ | 1 | 3 | 6 | 9 | 12 | +-| _S > 12_ | 1 | Ceil(S/4) | Ceil(S/2) | Ceil(3S/4) | S | + +### Before 9.2 + +-| _Available CPU Cores_ | _Minimum_ | _Low_ | _Medium_ | _High_ | _Maximum_ | +-|:---------------------:|:---------:|:---------:|:---------:|:----------:|:---------:| +-| _1_ | 1 | 1 | 1 | 1 | 1 | +-| _2_ | 1 | 1 | 1 | 2 | 2 | +-| _3_ | 1 | 2 | 2 | 2 | 3 | +-| _4_ | 1 | 2 | 2 | 3 | 4 | +-| _5_ | 1 | 2 | 3 | 4 | 5 | +-| _6_ | 1 | 2 | 3 | 4 | 6 | +-| _7_ | 1 | 2 | 3 | 5 | 7 | +-| _8_ | 1 | 2 | 4 | 6 | 8 | +-| _9_ | 1 | 3 | 5 | 7 | 8 | +-| _10_ | 1 | 3 | 5 | 8 | 9 | +-| _11_ | 1 | 3 | 6 | 8 | 10 | +-| _12_ | 1 | 3 | 6 | 9 | 11 | +-| _S > 12_ | 1 | Ceil(S/4) | Ceil(S/2) | Ceil(3S/4) | S-1 | [^23]: When the number of MC years to run is smaller than the allowance, the parallel run includes all of these years in a single bundle and there is no "reduced allowance" message diff --git a/src/libs/antares/study/include/antares/study/study.h b/src/libs/antares/study/include/antares/study/study.h index d8a187f9f9..d558a89213 100644 --- a/src/libs/antares/study/include/antares/study/study.h +++ b/src/libs/antares/study/include/antares/study/study.h @@ -406,7 +406,7 @@ class Study: public Yuni::NonCopyable, public LayerData *"max"). ** */ - std::map getRawNumberCoresPerLevel(); + unsigned getNumberOfCoresPerMode(unsigned nbLogicalCores, int ncMode); /*! ** \brief Computes number of cores diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index faafdcde31..111330e07b 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -26,6 +26,7 @@ #include // For use of floor(...) and ceil(...) #include #include // std::ostringstream +#include #include #include @@ -209,112 +210,32 @@ uint64_t Study::memoryUsage() const + (uiinfo ? uiinfo->memoryUsage() : 0); } -std::map Study::getRawNumberCoresPerLevel() +unsigned Study::getNumberOfCoresPerMode(unsigned nbLogicalCores, int ncMode) { - std::map table; - - uint nbLogicalCores = Yuni::System::CPU::Count(); if (!nbLogicalCores) { logs.fatal() << "Number of logical cores available is 0."; + return 0; } - switch (nbLogicalCores) + switch (ncMode) { - case 1: - table["min"] = 1; - table["low"] = 1; - table["med"] = 1; - table["high"] = 1; - table["max"] = 1; - break; - case 2: - table["min"] = 1; - table["low"] = 1; - table["med"] = 1; - table["high"] = 2; - table["max"] = 2; - break; - case 3: - table["min"] = 1; - table["low"] = 2; - table["med"] = 2; - table["high"] = 2; - table["max"] = 3; - break; - case 4: - table["min"] = 1; - table["low"] = 2; - table["med"] = 2; - table["high"] = 3; - table["max"] = 4; - break; - case 5: - table["min"] = 1; - table["low"] = 2; - table["med"] = 3; - table["high"] = 4; - table["max"] = 5; - break; - case 6: - table["min"] = 1; - table["low"] = 2; - table["med"] = 3; - table["high"] = 4; - table["max"] = 6; - break; - case 7: - table["min"] = 1; - table["low"] = 2; - table["med"] = 3; - table["high"] = 5; - table["max"] = 7; - break; - case 8: - table["min"] = 1; - table["low"] = 2; - table["med"] = 4; - table["high"] = 6; - table["max"] = 8; - break; - case 9: - table["min"] = 1; - table["low"] = 3; - table["med"] = 5; - table["high"] = 7; - table["max"] = 8; - break; - case 10: - table["min"] = 1; - table["low"] = 3; - table["med"] = 5; - table["high"] = 8; - table["max"] = 9; - break; - case 11: - table["min"] = 1; - table["low"] = 3; - table["med"] = 6; - table["high"] = 8; - table["max"] = 10; - break; - case 12: - table["min"] = 1; - table["low"] = 3; - table["med"] = 6; - table["high"] = 9; - table["max"] = 11; - break; + case ncMin: + return 1; + case ncLow: + return std::ceil(nbLogicalCores / 4.); + case ncAvg: + return std::ceil(nbLogicalCores / 2.); + case ncHigh: + return std::ceil(3 * nbLogicalCores / 4.); + case ncMax: + return nbLogicalCores; default: - table["min"] = 1; - table["low"] = (uint)std::ceil(nbLogicalCores / 4.); - table["med"] = (uint)std::ceil(nbLogicalCores / 2.); - table["high"] = (uint)std::ceil(3 * nbLogicalCores / 4.); - table["max"] = nbLogicalCores - 1; + logs.fatal() << "Simulation cores level not correct : " << ncMode; break; } - return table; + return 0; } void Study::getNumberOfCores(const bool forceParallel, const uint nbYearsParallelForced) @@ -325,33 +246,8 @@ void Study::getNumberOfCores(const bool forceParallel, const uint nbYearsParalle This number is limited by the smallest refresh span (if at least one type of time series is generated) */ - - std::map table = getRawNumberCoresPerLevel(); - - // Getting the number of parallel years based on the number of cores level. - switch (parameters.nbCores.ncMode) - { - case ncMin: - nbYearsParallelRaw = table["min"]; - break; - case ncLow: - nbYearsParallelRaw = table["low"]; - break; - case ncAvg: - nbYearsParallelRaw = table["med"]; - break; - case ncHigh: - nbYearsParallelRaw = table["high"]; - break; - case ncMax: - nbYearsParallelRaw = table["max"]; - break; - default: - logs.fatal() << "Simulation cores level not correct : " << (int)parameters.nbCores.ncMode; - break; - } - - maxNbYearsInParallel = nbYearsParallelRaw; + unsigned nbLogicalCores = std::thread::hardware_concurrency(); + maxNbYearsInParallel = getNumberOfCoresPerMode(nbLogicalCores, parameters.nbCores.ncMode); // In case solver option '--force-parallel n' is used, previous computation is overridden. if (forceParallel) diff --git a/src/tests/src/libs/antares/study/test_study.cpp b/src/tests/src/libs/antares/study/test_study.cpp index e2d2714037..fa0348467d 100644 --- a/src/tests/src/libs/antares/study/test_study.cpp +++ b/src/tests/src/libs/antares/study/test_study.cpp @@ -311,4 +311,17 @@ BOOST_FIXTURE_TEST_CASE(check_filename_limit, OneAreaStudy) #endif } +BOOST_FIXTURE_TEST_CASE(cpu_count, OneAreaStudy) +{ + BOOST_CHECK_EQUAL(study->getNumberOfCoresPerMode(75, ncMin), 1); + BOOST_CHECK_EQUAL(study->getNumberOfCoresPerMode(10, ncLow), 3); + BOOST_CHECK_EQUAL(study->getNumberOfCoresPerMode(6, ncAvg), 3); + BOOST_CHECK_EQUAL(study->getNumberOfCoresPerMode(16, ncHigh), 12); + BOOST_CHECK_EQUAL(study->getNumberOfCoresPerMode(128, ncMax), 128); + + // error cases + BOOST_CHECK_EQUAL(study->getNumberOfCoresPerMode(0, ncMax), 0); + BOOST_CHECK_EQUAL(study->getNumberOfCoresPerMode(10, 120), 0); +} + BOOST_AUTO_TEST_SUITE_END() // version From d7c5442e431cf709e723f8751bfab3db7a441112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 26 Jul 2024 09:43:47 +0200 Subject: [PATCH 092/127] Run all tests even if one of them fails (#2265) https://stackoverflow.com/questions/58858429/how-to-run-a-github-actions-step-even-if-the-previous-step-fails-while-still-f --- .github/workflows/ubuntu.yml | 40 ++++++++++++++++------------- .github/workflows/windows-vcpkg.yml | 40 ++++++++++++++++------------- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 24c53f00f0..01d2b3a10e 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -147,7 +147,7 @@ jobs: git submodule update --init --remote --recursive src/tests/resources/Antares_Simulator_Tests - name: Run named mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -156,13 +156,13 @@ jobs: variant: "named-mps" - name: Run unfeasibility-related tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} run: | cd _build ctest -C Release --output-on-failure -R "^unfeasible$" - name: Run unit and end-to-end tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} run: | cd _build ctest -C Release --output-on-failure -L "unit|end-to-end" @@ -175,7 +175,7 @@ jobs: path: ${{ github.workspace }}/_build/Testing/Temporary/LastTest.log - name: Run tests about infinity on BCs RHS - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -183,7 +183,7 @@ jobs: os: ${{ env.os }} - name: Run MILP with CBC - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -192,7 +192,7 @@ jobs: os: ${{ env.os }} - name: Run tests introduced in 8.6.0 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -200,7 +200,7 @@ jobs: os: ${{ env.os }} - name: Run tests introduced in 8.7.0 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -208,7 +208,7 @@ jobs: os: ${{ env.os }} - name: Run tests introduced in 9.1.0 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -216,7 +216,7 @@ jobs: os: ${{ env.os }} - name: Run tests introduced in 9.2.0 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -224,7 +224,7 @@ jobs: os: ${{ env.os }} - name: Run short-tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -232,7 +232,7 @@ jobs: os: ${{ env.os }} - name: Run mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -240,7 +240,7 @@ jobs: os: ${{ env.os }} - name: Run tests for adequacy patch (CSR) - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -248,7 +248,7 @@ jobs: os: ${{ env.os }} - name: Run parallel tests - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -257,7 +257,7 @@ jobs: variant: "parallel" - name: Run tests for time series generator tool - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -266,7 +266,7 @@ jobs: variant: "tsgenerator" - name: Run medium-tests - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -274,7 +274,7 @@ jobs: os: ${{ env.os }} - name: Run long-tests-1 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -282,7 +282,7 @@ jobs: os: ${{ env.os }} - name: Run long-tests-2 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -290,13 +290,17 @@ jobs: os: ${{ env.os }} - name: Run long-tests-3 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-3 os: ${{ env.os }} + - name: Barrier + if: ${{ !success() }} + run: exit 1 + - name: Installer .deb creation run: | cd _build diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index da3ee37acb..eadd043a69 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -149,7 +149,7 @@ jobs: echo "SIMTEST=${{ fromJson(env.SIMTEST_JSON).version }}" >> $GITHUB_ENV - name: Run named mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && ! cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -158,13 +158,13 @@ jobs: variant: "named-mps" - name: Run unfeasibility-related tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && ! cancelled() }} run: | cd _build ctest -C Release --output-on-failure -R "^unfeasible$" - name: Run unit and end-to-end tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && ! cancelled() }} run: | cd _build ctest -C Release --output-on-failure -L "unit|end-to-end" -LE ortools @@ -177,7 +177,7 @@ jobs: path: ${{ github.workspace }}/src/tests/mps - name: Run tests for adequacy patch (CSR) - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && ! cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -185,7 +185,7 @@ jobs: os: ${{ env.os }} - name: Run tests about infinity on BCs RHS - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -193,7 +193,7 @@ jobs: os: ${{ env.os }} - name: Run MILP with CBC - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -202,7 +202,7 @@ jobs: os: ${{ env.os }} - name: Run tests introduced in 8.6.0 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -210,7 +210,7 @@ jobs: os: ${{ env.os }} - name: Run tests introduced in 8.7.0 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -218,7 +218,7 @@ jobs: os: ${{ env.os }} - name: Run tests introduced in 9.1.0 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -226,7 +226,7 @@ jobs: os: ${{ env.os }} - name: Run tests introduced in 9.2.0 - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -234,7 +234,7 @@ jobs: os: ${{ env.os }} - name: Run short-tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -242,7 +242,7 @@ jobs: os: ${{ env.os }} - name: Run mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -250,7 +250,7 @@ jobs: os: ${{ env.os }} - name: Run parallel tests - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -259,7 +259,7 @@ jobs: variant: "parallel" - name: Run tests for time series generator tool - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -268,7 +268,7 @@ jobs: variant: "tsgenerator" - name: Run medium-tests - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -276,7 +276,7 @@ jobs: os: ${{ env.os }} - name: Run long-tests-1 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -284,7 +284,7 @@ jobs: os: ${{ env.os }} - name: Run long-tests-2 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -292,13 +292,17 @@ jobs: os: ${{ env.os }} - name: Run long-tests-3 - if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} batch-name: long-tests-3 os: ${{ env.os }} + - name: Barrier + if: ${{ !success() }} + run: exit 1 + - name: Solver archive creation shell: bash run: | From 724e85d3a8097d8dd67e987f81f3d11f4f94a8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 29 Jul 2024 16:15:02 +0200 Subject: [PATCH 093/127] Add missing changelog for v8.8.7 (#2287) --- docs/developer-guide/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/developer-guide/CHANGELOG.md b/docs/developer-guide/CHANGELOG.md index cc4ffbd741..880f5dc220 100644 --- a/docs/developer-guide/CHANGELOG.md +++ b/docs/developer-guide/CHANGELOG.md @@ -89,6 +89,13 @@ toc_depth: 2 * Fix invalid index causing segfault in `test-study` test (#1902) ## Branch 8.8.x (end of support 12/2025) +### 8.8.7 (07/2024) +#### Improvements +- Add OR-Tools solver option for batchrun tool (#1981) + +#### Bugfix +- Adequacy Patch regression [ANT-1845] #2235 + ### 8.8.6 (07/2024) #### Bugfix - Fix missing synthesis results for links (#2115) From bca91fc26338ff16f7ec24c285a4abd0ffdc3e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 5 Aug 2024 10:14:04 +0200 Subject: [PATCH 094/127] Remove spurious assert(false), fix debug binaries (#2291) --- src/solver/variable/include/antares/solver/variable/endoflist.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/solver/variable/include/antares/solver/variable/endoflist.h b/src/solver/variable/include/antares/solver/variable/endoflist.h index 7c32c32ecb..d8cb5dd69d 100644 --- a/src/solver/variable/include/antares/solver/variable/endoflist.h +++ b/src/solver/variable/include/antares/solver/variable/endoflist.h @@ -254,7 +254,6 @@ class EndOfList static void computeSpatialAggregateWith(O&, const Data::Area*, uint numSpace) { UNUSED_VARIABLE(numSpace); - assert(false); } template From c2c6afcb32f67ce56818a72b0b9464ad34d7a61f Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:17:31 +0200 Subject: [PATCH 095/127] Fix reset order (#2304) #2295 --- .../include/antares/solver/simulation/solver_utils.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver_utils.h b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h index d0d8748034..1e7ee2ffb8 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver_utils.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h @@ -135,15 +135,15 @@ class yearRandomNumbers void reset() { - // General - pNbClustersByArea.assign(pNbAreas, 0); - // Thermal noises for (uint a = 0; a != pNbAreas; a++) { pThermalNoisesByArea[a].assign(pNbClustersByArea[a], 0); } + // General + pNbClustersByArea.assign(pNbAreas, 0); + // Reservoir levels, spilled and unsupplied energy costs pReservoirLevels.assign(pNbAreas, 0); pUnsuppliedEnergy.assign(pNbAreas, 0); From 9cc20fb3b7352419e705d0d434b0730723f87729 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Wed, 7 Aug 2024 10:53:45 +0200 Subject: [PATCH 096/127] fix links (#2310) --- README.md | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index df15f52b86..bc31a675f0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Antares Simulator + [![Status][ubuntu_ci_svg]][ubuntu_ci_link] [![Status][windows_ci_svg]][windows_ci_link] [![Status][centos_ci_svg]][centos_ci_link] @@ -42,43 +43,47 @@ The GUI is deprecated in favor of [Antares Web](https://antares-web.readthedocs. This software suite has been tested under: -* Ubuntu 20.04 [![Status][ubuntu_ci_svg]][ubuntu_ci_link] -* Microsoft Windows with Visual Studio 2022 (64-bit) [![Status][windows_ci_svg]][windows_ci_link] -* Centos7 [![Status][centos_ci_svg]][centos_ci_link] -* Oracle Linux [![Status][oraclelinux_ci_svg]][oraclelinux_ci_link] +* Ubuntu 20.04 [![Status][ubuntu_ci_svg]][ubuntu_ci_link] +* Microsoft Windows with Visual Studio 2022 (64-bit) [![Status][windows_ci_svg]][windows_ci_link] +* Centos7 [![Status][centos_ci_svg]][centos_ci_link] +* Oracle Linux [![Status][oraclelinux_ci_svg]][oraclelinux_ci_link] Antares Simulator is built using CMake. -For installation instructions, please visit the [documentation website](https://antares-simulator.readthedocs.io/) +For installation instructions, please visit the [documentation website](https://antares-simulator.readthedocs.io/) or [its sources](docs/developer-guide/0-Introduction.md). # Source Code Content -* [AUTHORS](AUTHORS.txt) - Antares Simulator authors -* [CERTIFICATE](CERTIFICATE.txt) - A standard DCO that has to be signed by every contributor -* [CONTRIBUTING](CONTRIBUTING.md) - How to submit patches and discuss code evolutions +* [AUTHORS](AUTHORS.txt) - Antares Simulator authors +* [CERTIFICATE](CERTIFICATE.txt) - A standard DCO that has to be signed by every contributor +* [CONTRIBUTING](CONTRIBUTING.md) - How to submit patches and discuss code evolutions * [COPYING](COPYING.txt) - The MPL v2 license. * [NEWS](NEWS.md) - Important modifications between the releases. * [README](README.md) - This file. * [ROADMAP](ROADMAP.txt) - Main orientations for further developments * [THANKS](THANKS.txt) - Attribution notices for external libraries and contributors. -* [resources/](resources) - Free sample data sets. +* [resources/](resources) - Free sample data sets. * [src/analyzer/](src/analyzer) - source code for the statistical analysis of historical time-series. * [src/cmake/](src/cmake) - files for initializing a solution ready for compilation. -* [src/distrib/](src/distrib) - system redistributable libraries Win(x64,x86),unix. -* [src/ext/](src/ext) - third party libraries used by Antares_Simulator: libYuni, Sirius_Solver. -* [src/libs/](src/libs) - miscellaneous Antares_Simulator libraries. +* [src/distrib/](src/distrib) - system redistributable libraries Win(x64,x86),unix. +* [src/ext/](src/ext) - third party libraries used by Antares_Simulator: libYuni, Sirius_Solver. +* [src/libs/](src/libs) - miscellaneous Antares_Simulator libraries. * [src/solver/](src/solver) - simulation and optimization part. * [src/tools/](src/tools) - miscellaneous tools for dataset management. * [src/ui/](src/ui) - Graphic user interface. [ubuntu_ci_svg]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/workflows/Ubuntu%20CI%20(push%20and/or%20release)/badge.svg -[ubuntu_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions?query=workflow%3A"Ubuntu%20CI%20(push%20and/or%20release)" + +[ubuntu_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions/workflows/ubuntu.yml [windows_ci_svg]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/workflows/Windows%20CI%20(VCPKG%20and%20pre-compiled)/badge.svg -[windows_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions?query=workflow%3A"Windows%20CI%20(VCPKG%20and%20pre-compiled)" + +[windows_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions/workflows/windows-vcpkg.yml [centos_ci_svg]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/workflows/Centos7%20CI%20(push%20and/or%20release)/badge.svg -[centos_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions?query=workflow%3A"Centos7%20CI%20(push%20and/or%20release)" + +[centos_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions/workflows/centos7.yml [oraclelinux_ci_svg]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/workflows/Oracle%208%20CI%20(push%20and/or%20release)/badge.svg -[oraclelinux_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions?query=workflow%3A"Oracle%208%20CI%20(push%20and/or%20release)" + +[oraclelinux_ci_link]: https://github.com/AntaresSimulatorTeam/Antares_Simulator/actions/workflows/oracle8.yml From 05117e02116fca5b37041c7a113e250d8a532a5c Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Wed, 7 Aug 2024 11:20:31 +0200 Subject: [PATCH 097/127] update AUTHORS.txt (#2312) --- AUTHORS.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 6c7df3d9cb..d7681f43e1 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -7,16 +7,20 @@ Michael Boulade V4-V6 Michel Doquet V1-V7 Damien Gerard V2-V5 Robert Gonzalez V2-V5 -Jean-Marie Kerloch V7-V8 +Jean-Marie Kerloch V7-V8 Sylvain Marandon V6-V7 Eric Momot V1-V2 Papa Ndiaye V5-V7 -Florian Omnes V7-V8 -Guillaume Pierre V5-V8 +Florian Omnes V7-* +Guillaume Pierre V5-* Andrea Sgattoni V6-V8 Frederique Verrier V1-V2 Li Wu V5 - +Vincent Payet V8-* +Jason Marechal V8-* +Abdoulbari Zakir V8-* +Sylvain Leclerc V8-* + Artwork ======= From 50e28d256611082ee44dea6e711f449de443c03e Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 8 Aug 2024 16:47:19 +0200 Subject: [PATCH 098/127] Force color output in cmake (#2320) --- src/cmake/common-settings.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmake/common-settings.cmake b/src/cmake/common-settings.cmake index b659a5f46c..69d52bc3ad 100644 --- a/src/cmake/common-settings.cmake +++ b/src/cmake/common-settings.cmake @@ -14,6 +14,7 @@ set(COMMON_MSVC_FLAGS "/W3 /MP4") set(COMMON_MSVC_FLAGS "${COMMON_MSVC_FLAGS} /we4715 /we4716") #adding no return or no return for all code paths as errors set(ADDITIONAL_C_FLAGS " -Wconversion -Wmissing-prototypes -Wstrict-prototypes") set(ADDITIONAL_C_FLAGS "${ADDITIONAL_C_FLAGS} -Wmissing-noreturn -Wpacked -Wredundant-decls -Wbad-function-cast -W -Wcast-align -Wcast-qual -Wsign-compare -fno-exceptions -Wdeclaration-after-statement") +set(CMAKE_COLOR_DIAGNOSTICS on) Set(ANTARES_VERSION_TARGET "unknown") From 07d1dab8dbc4b627ba418ef6acdfb2d17d1a41a3 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:15:02 +0200 Subject: [PATCH 099/127] Fix Windows Debug version crash (#2322) reset not resize --- .../simulation/include/antares/solver/simulation/solver_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver_utils.h b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h index 1e7ee2ffb8..f7129c6a35 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver_utils.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h @@ -138,7 +138,7 @@ class yearRandomNumbers // Thermal noises for (uint a = 0; a != pNbAreas; a++) { - pThermalNoisesByArea[a].assign(pNbClustersByArea[a], 0); + pThermalNoisesByArea[a].assign(pThermalNoisesByArea[a].size(), 0); } // General From c02af5deef60f88fc875d7c1e05fc274062bcea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 12 Aug 2024 10:13:47 +0200 Subject: [PATCH 100/127] Free up space for SonarCloud job (#2315) https://github.com/marketplace/actions/maximize-build-disk-space ``` Run df -h Filesystem Size Used Avail Use% Mounted on ... /dev/mapper/buildvg-buildlv 85G 24K 85G 1% /home/runner/work/Antares_Simulator/Antares_Simulator ``` Nice --- .github/workflows/sonarcloud.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index c5bbc5a473..e6f1cf608f 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -23,6 +23,18 @@ jobs: BUILD_WRAPPER_OUT_DIR: ${{ github.workspace }}/_build/output # Directory where build-wrapper output will be placed steps: + # Disk space on / is insufficient, leading to errors + # We use this 'hack' to remove unused stuff (android, dotnet, etc.) and change partition layout + - name: Maximize build space + uses: easimon/maximize-build-space@v10 + with: + root-reserve-mb: 5120 + swap-size-mb: 1024 + remove-dotnet: true + remove-android: true + remove-haskell: true + remove-codeql: true + - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis From 2508646134138fbd50e4e5644e8fa933550e2fdf Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:40:41 +0200 Subject: [PATCH 101/127] Short term storage costs [ANT-1854] (#2302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Florian Omnès --- .../study/parts/short-term-storage/series.h | 18 +++-- .../parts/short-term-storage/cluster.cpp | 2 +- .../study/parts/short-term-storage/series.cpp | 75 +++++++++++++------ .../opt_gestion_des_couts_cas_lineaire.cpp | 9 +-- src/solver/simulation/CMakeLists.txt | 2 - .../solver/simulation/sim_spread_generator.h | 41 ---------- .../simulation/sim_spread_generator.cpp | 40 ---------- .../short-term-storage-input-output.cpp | 16 ++++ 8 files changed, 84 insertions(+), 119 deletions(-) delete mode 100644 src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h delete mode 100644 src/solver/simulation/sim_spread_generator.cpp diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h index e6302680f8..238a25d425 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h @@ -28,7 +28,7 @@ class Series { public: // check if series values are valid - bool validate() const; + bool validate(const std::string& id = "") const; // load all series files with folder path bool loadFromFolder(const std::string& folder); @@ -42,13 +42,17 @@ class Series std::vector lowerRuleCurve; std::vector upperRuleCurve; + std::vector costInjection; + std::vector costWithdrawal; + std::vector costLevel; + private: - bool validateSizes() const; - bool validateMaxInjection() const; - bool validateMaxWithdrawal() const; - bool validateRuleCurves() const; - bool validateUpperRuleCurve() const; - bool validateLowerRuleCurve() const; + bool validateSizes(const std::string&) const; + bool validateMaxInjection(const std::string&) const; + bool validateMaxWithdrawal(const std::string&) const; + bool validateRuleCurves(const std::string&) const; + bool validateUpperRuleCurve(const std::string&) const; + bool validateLowerRuleCurve(const std::string&) const; }; bool loadFile(const std::string& folder, std::vector& vect); diff --git a/src/libs/antares/study/parts/short-term-storage/cluster.cpp b/src/libs/antares/study/parts/short-term-storage/cluster.cpp index fe06ace18e..fc2ee8c263 100644 --- a/src/libs/antares/study/parts/short-term-storage/cluster.cpp +++ b/src/libs/antares/study/parts/short-term-storage/cluster.cpp @@ -73,7 +73,7 @@ bool STStorageCluster::validate() const } logs.debug() << "Validating properties and series for st storage: " << id; - return properties.validate() && series->validate(); + return properties.validate() && series->validate(id); } bool STStorageCluster::loadSeries(const std::string& folder) const diff --git a/src/libs/antares/study/parts/short-term-storage/series.cpp b/src/libs/antares/study/parts/short-term-storage/series.cpp index bda3bc0ed2..43354fff88 100644 --- a/src/libs/antares/study/parts/short-term-storage/series.cpp +++ b/src/libs/antares/study/parts/short-term-storage/series.cpp @@ -43,6 +43,10 @@ bool Series::loadFromFolder(const std::string& folder) ret = loadFile(folder + SEP + "lower-rule-curve.txt", lowerRuleCurve) && ret; ret = loadFile(folder + SEP + "upper-rule-curve.txt", upperRuleCurve) && ret; + ret = loadFile(folder + SEP + "cost-injection.txt", costInjection) && ret; + ret = loadFile(folder + SEP + "cost-withdrawal.txt", costWithdrawal) && ret; + ret = loadFile(folder + SEP + "cost-level.txt", costLevel) && ret; + return ret; } @@ -55,7 +59,7 @@ bool loadFile(const std::string& path, std::vector& vect) std::ifstream file; file.open(path); - if (!file) + if (!file.is_open()) { logs.debug() << "File not found: " << path; return true; @@ -112,6 +116,10 @@ void Series::fillDefaultSeriesIfEmpty() fillIfEmpty(inflows, 0.0); fillIfEmpty(lowerRuleCurve, 0.0); fillIfEmpty(upperRuleCurve, 1.0); + + fillIfEmpty(costInjection, 0.0); + fillIfEmpty(costWithdrawal, 0.0); + fillIfEmpty(costLevel, 0.0); } bool Series::saveToFolder(const std::string& folder) const @@ -134,6 +142,10 @@ bool Series::saveToFolder(const std::string& folder) const checkWrite("lower-rule-curve.txt", lowerRuleCurve); checkWrite("upper-rule-curve.txt", upperRuleCurve); + checkWrite("cost-injection.txt", costInjection); + checkWrite("cost-withdrawal.txt", costWithdrawal); + checkWrite("cost-level.txt", costLevel); + return ret; } @@ -158,47 +170,65 @@ bool writeVectorToFile(const std::string& path, const std::vector& vect) return true; } -bool Series::validate() const +bool Series::validate(const std::string& id) const { - return validateSizes() && validateMaxInjection() && validateMaxWithdrawal() - && validateRuleCurves(); + return validateSizes(id) && validateMaxInjection(id) && validateMaxWithdrawal(id) + && validateRuleCurves(id); } -static bool checkVectBetweenZeroOne(const std::vector& v, const std::string& name) +static bool checkVectBetweenZeroOne(const std::string& name, + const std::string& id, + const std::vector& v) { if (!std::all_of(v.begin(), v.end(), [](double d) { return (d >= 0.0 && d <= 1.0); })) { - logs.warning() << "Values for " << name << " series should be between 0 and 1"; + logs.warning() << "Short-term storage " << id << " Values for " << name + << " values should be between 0 and 1"; return false; } return true; } -bool Series::validateSizes() const +static bool checkSize(const std::string& seriesFilename, + const std::string& id, + const std::vector& v) { - if (maxInjectionModulation.size() != HOURS_PER_YEAR - || maxWithdrawalModulation.size() != HOURS_PER_YEAR || inflows.size() != HOURS_PER_YEAR - || lowerRuleCurve.size() != HOURS_PER_YEAR || upperRuleCurve.size() != HOURS_PER_YEAR) + if (v.size() != HOURS_PER_YEAR) { - logs.warning() << "Size of series for short term storage is wrong"; + logs.warning() << "Short-term storage " << id + << " Invalid size for file: " << seriesFilename << ". Got " << v.size() + << " lines, expected " << HOURS_PER_YEAR; return false; } + return true; } -bool Series::validateMaxInjection() const +bool Series::validateSizes(const std::string& id) const +{ + return checkSize("PMAX-injection.txt", id, maxInjectionModulation) + && checkSize("PMAX-withdrawal.txt", id, maxWithdrawalModulation) + && checkSize("inflows.txt", id, inflows) + && checkSize("lower-rule-curve.txt", id, lowerRuleCurve) + && checkSize("upper-rule-curve.txt", id, upperRuleCurve) + && checkSize("cost-injection.txt", id, costInjection) + && checkSize("cost-withdrawal.txt", id, costWithdrawal) + && checkSize("cost-level.txt", id, costLevel); +} + +bool Series::validateMaxInjection(const std::string& id) const { - return checkVectBetweenZeroOne(maxInjectionModulation, "PMAX injection"); + return checkVectBetweenZeroOne("PMAX injection", id, maxInjectionModulation); } -bool Series::validateMaxWithdrawal() const +bool Series::validateMaxWithdrawal(const std::string& id) const { - return checkVectBetweenZeroOne(maxWithdrawalModulation, "PMAX withdrawal"); + return checkVectBetweenZeroOne("PMAX withdrawal", id, maxWithdrawalModulation); } -bool Series::validateRuleCurves() const +bool Series::validateRuleCurves(const std::string& id) const { - if (!validateUpperRuleCurve() || !validateLowerRuleCurve()) + if (!validateUpperRuleCurve(id) || !validateLowerRuleCurve(id)) { return false; } @@ -207,21 +237,22 @@ bool Series::validateRuleCurves() const { if (lowerRuleCurve[i] > upperRuleCurve[i]) { - logs.warning() << "Lower rule curve greater than upper at line: " << i + 1; + logs.warning() << "Short-term storage " << id + << " Lower rule curve greater than upper at line: " << i + 1; return false; } } return true; } -bool Series::validateUpperRuleCurve() const +bool Series::validateUpperRuleCurve(const std::string& id) const { - return checkVectBetweenZeroOne(upperRuleCurve, "upper rule curve"); + return checkVectBetweenZeroOne("upper rule curve", id, upperRuleCurve); } -bool Series::validateLowerRuleCurve() const +bool Series::validateLowerRuleCurve(const std::string& id) const { - return checkVectBetweenZeroOne(maxInjectionModulation, "lower rule curve"); + return checkVectBetweenZeroOne("lower rule curve", id, maxInjectionModulation); } } // namespace Antares::Data::ShortTermStorage diff --git a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp index 857561f616..9831750143 100644 --- a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp @@ -24,7 +24,6 @@ #include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" #include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/sim_spread_generator.h" #include "antares/solver/simulation/sim_structure_donnees.h" #include "antares/solver/simulation/simulation.h" @@ -38,7 +37,6 @@ static void shortTermStorageCost( VariableManagement::VariableManager& variableManager, std::vector& linearCost) { - SIM::SpreadGenerator spreadGenerator; for (int pays = 0; pays < NombreDePays; ++pays) { for (const auto& storage: shortTermStorageInput[pays]) @@ -52,16 +50,15 @@ static void shortTermStorageCost( pdtJour); varLevel >= 0) { - linearCost[varLevel] = 0; + linearCost[varLevel] = storage.series->costLevel[pdtHebdo]; } - const double cost = spreadGenerator.generate(); if (const int varInjection = variableManager.ShortTermStorageInjection( clusterGlobalIndex, pdtJour); varInjection >= 0) { - linearCost[varInjection] = storage.withdrawalEfficiency * cost; + linearCost[varInjection] = storage.series->costInjection[pdtHebdo]; } if (const int varWithdrawal = variableManager.ShortTermStorageWithdrawal( @@ -69,7 +66,7 @@ static void shortTermStorageCost( pdtJour); varWithdrawal >= 0) { - linearCost[varWithdrawal] = storage.injectionEfficiency * cost; + linearCost[varWithdrawal] = storage.series->costWithdrawal[pdtHebdo]; } } } diff --git a/src/solver/simulation/CMakeLists.txt b/src/solver/simulation/CMakeLists.txt index fbfeb17f6a..d31ea04dfe 100644 --- a/src/solver/simulation/CMakeLists.txt +++ b/src/solver/simulation/CMakeLists.txt @@ -11,8 +11,6 @@ set(SRC_SIMULATION include/antares/solver/simulation/sim_structure_probleme_economique.h sim_variables_globales.cpp include/antares/solver/simulation/sim_constants.h - include/antares/solver/simulation/sim_spread_generator.h - sim_spread_generator.cpp include/antares/solver/simulation/simulation.h include/antares/solver/simulation/solver.h include/antares/solver/simulation/solver.hxx diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h b/src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h deleted file mode 100644 index c28ec9a75a..0000000000 --- a/src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ - -#pragma once - -#include - -namespace SIM -{ -class SpreadGenerator -{ - static constexpr double rangeDefault = 1.e-3; - -public: - explicit SpreadGenerator(double range = rangeDefault); - void reset(unsigned int seed); - double generate(); - -private: - Antares::MersenneTwister mt_; - const double range_; -}; -} // namespace SIM diff --git a/src/solver/simulation/sim_spread_generator.cpp b/src/solver/simulation/sim_spread_generator.cpp deleted file mode 100644 index 734cb92da6..0000000000 --- a/src/solver/simulation/sim_spread_generator.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ - -#include "antares/solver/simulation/sim_spread_generator.h" - -namespace SIM -{ -SpreadGenerator::SpreadGenerator(double range): - range_(range) -{ -} - -void SpreadGenerator::reset(unsigned int seed) -{ - mt_.reset(seed); -} - -double SpreadGenerator::generate() -{ - return mt_.next() * range_; -} -} // namespace SIM diff --git a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp index 99152e42d0..d7de940912 100644 --- a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp +++ b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp @@ -51,6 +51,10 @@ void resizeFillVectors(ShortTermStorage::Series& series, double value, unsigned series.inflows.resize(size, value); series.lowerRuleCurve.resize(size, value); series.upperRuleCurve.resize(size, value); + + series.costInjection.resize(size, value); + series.costWithdrawal.resize(size, value); + series.costLevel.resize(size, value); } void createIndividualFileSeries(const std::string& path, double value, unsigned int size) @@ -88,6 +92,10 @@ void createFileSeries(double value, unsigned int size) createIndividualFileSeries(folder + SEP + "inflows.txt", value, size); createIndividualFileSeries(folder + SEP + "lower-rule-curve.txt", value, size); createIndividualFileSeries(folder + SEP + "upper-rule-curve.txt", value, size); + + createIndividualFileSeries(folder + SEP + "cost-injection.txt", value, size); + createIndividualFileSeries(folder + SEP + "cost-withdrawal.txt", value, size); + createIndividualFileSeries(folder + SEP + "cost-level.txt", value, size); } void createFileSeries(unsigned int size) @@ -99,6 +107,10 @@ void createFileSeries(unsigned int size) createIndividualFileSeries(folder + SEP + "inflows.txt", size); createIndividualFileSeries(folder + SEP + "lower-rule-curve.txt", size); createIndividualFileSeries(folder + SEP + "upper-rule-curve.txt", size); + + createIndividualFileSeries(folder + SEP + "cost-injection.txt", size); + createIndividualFileSeries(folder + SEP + "cost-withdrawal.txt", size); + createIndividualFileSeries(folder + SEP + "cost-level.txt", size); } void createIniFile(bool enabled) @@ -176,6 +188,10 @@ struct Fixture std::filesystem::remove(folder + SEP + "inflows.txt"); std::filesystem::remove(folder + SEP + "lower-rule-curve.txt"); std::filesystem::remove(folder + SEP + "upper-rule-curve.txt"); + + std::filesystem::remove(folder + SEP + "cost-injection.txt"); + std::filesystem::remove(folder + SEP + "cost-withdrawal.txt"); + std::filesystem::remove(folder + SEP + "cost-level.txt"); } std::string folder = getFolder(); From 9d6d809f0ab4d35e6066d68381974fb385cdc60b Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 19 Aug 2024 10:40:19 +0200 Subject: [PATCH 102/127] Update simtest version, 9.2.0c (#2336) --- simtest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simtest.json b/simtest.json index f5912ade9e..d27fde74c1 100644 --- a/simtest.json +++ b/simtest.json @@ -1,3 +1,3 @@ { - "version": "v9.2.0b" + "version": "v9.2.0c" } From 1d166e8e31a5edd57818685f51286a3e7dd52e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 19 Aug 2024 13:27:53 +0200 Subject: [PATCH 103/127] Fix/rhs hydro power constraint (#2034) - Take overflows into account for hydro ventilation results - Update documentation (typos, etc.) --------- Co-authored-by: Juliette-Gerbaux --- docs/user-guide/solver/06-hydro-heuristics.md | 46 ++++++++++--------- src/solver/hydro/management/daily.cpp | 8 ++-- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/docs/user-guide/solver/06-hydro-heuristics.md b/docs/user-guide/solver/06-hydro-heuristics.md index 78ff065933..eb5567ffe8 100644 --- a/docs/user-guide/solver/06-hydro-heuristics.md +++ b/docs/user-guide/solver/06-hydro-heuristics.md @@ -33,7 +33,7 @@ not be confused with those of the document "optimization problem formulation" The hydro storage energy monthly and weekly profiles of each zone $z$ do not depend at all on the local demand and must-run generation in $z$ - $L_{z.}^+$ Time-series of "net" load for zone $z$, defined as: $L{z.}^+ = L{z.} - M{z.}$ -- $L_{z.}$ Time-series of "weighted" load for zone $z$, defined as:_ $L_{z.} = A^t L_{z.}^+$ +- $L_{z.}$ Time-series of "weighted" load for zone $z$, defined as: $L_{z.} = A^t L_{z.}^+$ All following parameters are related to the generic zone $z$: @@ -47,9 +47,9 @@ not be confused with those of the document "optimization problem formulation" - $S$ Reservoir size -- $\overline{S_d}$ Reservoir maximum level at the end of day d, expressed as a fraction of $S$ (rule curve) +- $\overline{S_d}$ Reservoir maximum level at the end of day d (rule curve) -- $\underline{S_d}$ Reservoir minimum level at the end of day d, expressed as a fraction of $S$ (rule curve) +- $\underline{S_d}$ Reservoir minimum level at the end of day d (rule curve) - $S_0$ Reservoir initial level at the beginning of the first day of the "hydro-year" @@ -72,18 +72,18 @@ not be confused with those of the document "optimization problem formulation" - $W_m^k$ Energy to generate on month m, at the end of stage k of pre-allocation -Following variables and parameters are local to linear optimization problems $M$ & $D(Tm)$ +Following variables and parameters are local to linear optimization problems $M$ & $D(m)$ solved within the heuristic. For the sake of clarity, the same generic index is used for all time steps, -knowing that in $M$ there are 12 monthly time-steps, while in $D(m)t$ there are from 28 to 31 daily +knowing that in $M$ there are 12 monthly time-steps, while in $D(m)$ there are from 28 to 31 daily time-steps. Costs $\gamma_{Var}$ given to these variables are chosen to enforce a logical hierarchy of penalties (letting the reservoir overflow is worse than violating rule curves, which is worse than deviating from the generation objective assessed in stage 1, etc.) -- $Y$ Generation deficit at the end of the period, as compared to the objective aimed at +- $W$ Generation deficit at the end of the period, as compared to the objective aimed at (positive varaible) -- $O_t$ Overflow from the reservoir on time step $t$ +- $O_t$ Overflow from the reservoir on time step $t$ (positive varaible) -- $G_t, \overline{G_t}$ Optimal generation and maximum generation on time step $t$ +- $G_t, \overline{G_t}, \underline{G_t}$ Optimal generation, maximum and minimum generation on time step $t$ - $T_t$ Generation objective assessed in the first stage, for time step t ( $W_m^1$ or $W_d^1$) @@ -95,9 +95,9 @@ from the generation objective assessed in stage 1, etc.) - $\Delta$ Maximum deviation throughout the period -- $V_t^+$ Amplitude of the violation of the upper rule curve at time step $t$ +- $V_t^+$ Amplitude of the violation of the upper rule curve at time step $t$ (positive variable) -- $V_t^-$ Amplitude of the violation of the lower rule curve at time step $t$ +- $V_t^-$ Amplitude of the violation of the lower rule curve at time step $t$ (positive variable) - $Y$ Maximum violation of lower rule curve throughout the period @@ -117,17 +117,20 @@ $$else: \text{for } m\in [1, 12]: \{W_m^1 \leftarrow I_m\}$$ _M2:_ -$$\text{for } m\in [1, 12]: W_m^2 \leftarrow \text{Solution of linear problem M}$$ +$$if (\mu) : \text{for } m\in [1, 12]: W_m^2 \leftarrow \text{Solution of linear problem M}$$ + +$$else : W_m^2 \leftarrow W_m^1$$ _D1:_ $$if (j): \text{for } d\in [1, 31]: W_d^1 \leftarrow \frac{L_d^{\beta}. (W_m^2)}{(\sum_{d\in m}{L_d^{\beta}})}$$ -$$else: \text{for } d\in [1, 31]: W_d^1 \leftarrow \frac{I_d . (W_m^2)} {(\sum_{d\in m}{I_d})}$$ +$$else: \text{for } d\in [1, 31]: W_d^1 \leftarrow I_d $$ _D2:_ -$$\text{for } m \in [1, 12]: W_{d\in m}^2 \leftarrow \text{Solution of linear problem D(m)}$$ +$$if(\mu) : \text{for } m \in [1, 12]: W_{d\in m}^2 \leftarrow \text{Solution of linear problem D(m)}$$ +$ else : \text{for } m \in [1, 12]: W_{d\in m}^2 \leftarrow$ Solution of a simplified version of linear problem $D(m)$ without reservoir levels _End_ @@ -146,9 +149,9 @@ $$S_t \geq 0$$ $$S_t \leq S$$ -$S_t + G_t - S_{t-1} = I_t$ (see note [^monthly_allocation]) +$G_t \geq \underline{G_t} $ and $G_t \leq \overline{G_t} $ -$$\sum_{t}{G_t} = \sum_{t}{T_t}$$ +For $t\in [1,12], S_{t} + G_{t} - S_{t-1} = I_{t}$ (see note [^monthly_allocation]) and $S_{12} = S_{0}.$ $$G_t - D_t \leq T_t$$ @@ -160,27 +163,28 @@ $$V_t^+ - S_t \geq -\overline{S_t}$$ $$Y - V_t^- \geq 0$$ +$$\Delta - D_t \geq 0$$ **Optimization problems $D(m)$** -$$\min_{G_t, S_t, ...}{\gamma_{\Delta}\Delta + \gamma_Y Y + \sum_{t}{(\gamma_D D_t + \gamma_{V-} V_t^- + \gamma_{O} O_t + \gamma_S S_t)}}$$ +$$\min_{G_t, S_t, ...}{\gamma_{\Delta}\Delta + \gamma_Y Y + \gamma_{W}W+ \sum_{t}{(\gamma_D D_t + \gamma_{V-} V_t^- + \gamma_{O} O_t + \gamma_S S_t)}}$$ s.t $$S_t \geq 0$$ $$S_t \leq S$$ -$$G_t \geq 0$$ +$$G_t \geq \underline{G_t}$$ $$G_t \leq \overline{G_t}$$ -$S_t + G_t + O_t - S_{t-1} = I_t$ (see note [^daily_allocation]) +$S_t + G_t + O_t - S_{t-1} = I_t$ (see note [^daily_allocation]) (initial level of the period is either $S_0$ if $m=1$ or the final level found in solving $D(m-1)$) -$\sum_{t}{G_t + Y} = \sum_{t}{T_t} + Y_{m-1}$ (value of Y previously found in solving **$D(m-1)$**) +$\sum_{t}{G_t + W} = \sum_{t}{T_t} + W_{m-1}$ (0 if $m=1$ else value of $W$ previously found in solving **$D(m-1)$**) -$$G_t - D_t \leq T_t$$ +$$G_t - D_t \leq T_t + \frac{W_{m-1}}{|d \in m|}$$ -$$G_t + D_t \geq T_t$$ +$$G_t + D_t \geq T_t + \frac{W_{m-1}}{|d \in m|}$$ $$\Delta - D_t \geq 0$$ diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index 254ab2b1b2..2f0f672acd 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -513,9 +513,11 @@ inline void HydroManagement::prepareDailyOptimalGenerations( for (uint day = firstDay; day != endDay; ++day) { ventilationResults.HydrauliqueModulableQuotidien[day] = problem - .Turbine[dayMonth] - * reservoirCapacity; - + .Turbine[dayMonth] + * reservoirCapacity + + problem.overflows + [dayMonth] + * reservoirCapacity; ventilationResults.NiveauxReservoirsFinJours[day] = problem.niveauxFinJours [dayMonth]; From c79cbb9e69f8cf141285071d92a01ffac6b46974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 19 Aug 2024 17:21:11 +0200 Subject: [PATCH 104/127] Use const char** for argv, remove function `prepareArgs` (#2338) Co-authored-by: Jason Marechal --- src/analyzer/main.cpp | 2 +- src/ext/yuni/src/yuni/core/getopt/parser.cpp | 65 +++++++++++++++---- src/ext/yuni/src/yuni/core/getopt/parser.h | 9 +-- src/libs/antares/args/args_to_utf8.cpp | 20 +++--- .../args/include/antares/args/args_to_utf8.h | 6 +- .../FileTreeStudyLoader.cpp | 27 +------- .../include/antares/resources/resources.h | 2 +- src/libs/antares/resources/resources.cpp | 2 +- src/solver/application/application.cpp | 2 +- .../include/antares/application/application.h | 4 +- src/solver/main.cpp | 2 +- .../antares/solver/misc/write-command-line.h | 2 +- src/solver/misc/write-command-line.cpp | 2 +- src/tools/batchrun/main.cpp | 2 +- src/tools/config/main.cpp | 2 +- src/tools/finder/main.cpp | 2 +- .../kirchhoff-cbuilder/kirchhoff-cbuilder.h | 2 +- src/tools/kirchhoff-cbuilder/main.cpp | 4 +- .../tools/ts-generator/tsGenerationOptions.h | 2 +- src/tools/ts-generator/main.cpp | 2 +- .../ts-generator/tsGenerationOptions.cpp | 2 +- src/tools/updater/main.cpp | 2 +- src/tools/vacuum/main.cpp | 2 +- src/tools/yby-aggregator/main.cpp | 4 +- src/ui/simulator/application/application.cpp | 2 +- src/ui/simulator/main.cpp | 55 +++++++++------- 26 files changed, 127 insertions(+), 101 deletions(-) diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index 65d9a81e95..201a61f9b2 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -101,7 +101,7 @@ static void NotEnoughMemory() exit(42); } -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { // Dealing with the lack of memory std::set_new_handler(&NotEnoughMemory); diff --git a/src/ext/yuni/src/yuni/core/getopt/parser.cpp b/src/ext/yuni/src/yuni/core/getopt/parser.cpp index c3e31f7d72..909b00a5da 100644 --- a/src/ext/yuni/src/yuni/core/getopt/parser.cpp +++ b/src/ext/yuni/src/yuni/core/getopt/parser.cpp @@ -9,8 +9,9 @@ ** gitlab: https://gitlab.com/libyuni/libyuni/ (mirror) */ #include "parser.h" -#include + #include +#include // The standard error output is not displayed on Windows #ifndef YUNI_OS_WINDOWS @@ -75,7 +76,7 @@ class Context final /*! ** \brief parse the command line */ - GetOpt::ReturnCode operator()(int argc, char* argv[]); + GetOpt::ReturnCode operator()(int argc, const char* argv[]); private: //! An option has not been found @@ -83,7 +84,7 @@ class Context final //! A additional parameter is missing for an option void parameterIsMissing(const char* name); //! Find the additional parameter and add it to the option - bool findNextParameter(IOption* option, int argc, char* argv[]); + bool findNextParameter(IOption* option, int argc, const char* argv[]); private: //! The public class for the parser, where all options are stored @@ -111,12 +112,15 @@ inline Context::TokenType Context::GetTokenType(const char* argv) #endif } -inline Context::Context(Parser& parser) : pParser(parser), pTokenIndex(1), pParameterIndex(1) +inline Context::Context(Parser& parser): + pParser(parser), + pTokenIndex(1), + pParameterIndex(1) { pParser.pErrors = 0; } -bool Context::findNextParameter(IOption* option, int argc, char* argv[]) +bool Context::findNextParameter(IOption* option, int argc, const char* argv[]) { assert(option); @@ -160,7 +164,7 @@ void Context::parameterIsMissing(const char* name) STD_CERR << "Error: The parameter for `" << name << "` is missing" << std::endl; } -GetOpt::ReturnCode Context::operator()(int argc, char* argv[]) +GetOpt::ReturnCode Context::operator()(int argc, const char* argv[]) { using namespace GetOpt; while (pTokenIndex < argc) @@ -178,8 +182,10 @@ GetOpt::ReturnCode Context::operator()(int argc, char* argv[]) if (i != pParser.pShortNames.end()) { if (not findNextParameter(i->second, argc, argv)) + { std::cerr << "Error: The parameter is missing for `" << arg << "`" << std::endl; + } } else { @@ -200,7 +206,9 @@ GetOpt::ReturnCode Context::operator()(int argc, char* argv[]) ++arg; ++arg; if ('\0' == *arg) // End of options + { return (0 == pParser.pErrors) ? ReturnCode::ok : ReturnCode::error; + } if ((sub = strchr(arg, '='))) { @@ -239,7 +247,9 @@ GetOpt::ReturnCode Context::operator()(int argc, char* argv[]) if (i != pParser.pLongNames.end()) { if (not findNextParameter(i->second, argc, argv)) + { parameterIsMissing(arg); + } } else { @@ -261,7 +271,9 @@ GetOpt::ReturnCode Context::operator()(int argc, char* argv[]) { pParameterIndex = pTokenIndex; if (pParser.pRemains) + { pParser.pRemains->addValue(arg, static_cast(::strlen(arg))); + } } break; } @@ -295,7 +307,10 @@ static const char* ExtractFilenameOnly(const char* argv) return result; } -Parser::Parser() : pRemains(nullptr), pErrors(0), pIgnoreUnknownArgs(false) +Parser::Parser(): + pRemains(nullptr), + pErrors(0), + pIgnoreUnknownArgs(false) { } @@ -305,7 +320,9 @@ Parser::~Parser() { OptionList::iterator end = pAllOptions.end(); for (OptionList::iterator i = pAllOptions.begin(); i != end; ++i) + { delete *i; + } } delete pRemains; @@ -317,7 +334,9 @@ void Parser::clear() { OptionList::iterator end = pAllOptions.end(); for (OptionList::iterator i = pAllOptions.begin(); i != end; ++i) + { delete *i; + } // clear-and-minimize idiom OptionsOrderedByShortName emptyShort; @@ -335,7 +354,7 @@ void Parser::clear() pRemains = nullptr; } -GetOpt::ReturnCode Parser::operator()(int argc, char* argv[]) +GetOpt::ReturnCode Parser::operator()(int argc, const char* argv[]) { Private::GetOptImpl::Context context(*this); return context(argc, argv); @@ -350,9 +369,13 @@ void Parser::helpUsage(const char* argv0) std::cout.write(" [OPTION]...", 12); if (pRemains) + { std::cout.write(" [FILE]...\n", 11); + } else + { std::cout << '\n'; + } if (not pAllOptions.empty()) { @@ -362,21 +385,33 @@ void Parser::helpUsage(const char* argv0) // Add a space if the first option is not a paragraph // In this case the user would do what he wants if (not dynamic_cast(*i)) + { std::cout << '\n'; + } for (; i != end; ++i) + { (*i)->helpUsage(std::cout); + } } // Help if (pLongNames.end() == pLongNames.find("help")) { if (pShortNames.end() == pShortNames.find('h')) - Private::GetOptImpl::DisplayHelpForOption( - std::cout, 'h', "help", "Display this help and exit"); + { + Private::GetOptImpl::DisplayHelpForOption(std::cout, + 'h', + "help", + "Display this help and exit"); + } else - Private::GetOptImpl::DisplayHelpForOption( - std::cout, ' ', "help", "Display this help and exit"); + { + Private::GetOptImpl::DisplayHelpForOption(std::cout, + ' ', + "help", + "Display this help and exit"); + } } std::cout << std::endl; // flush @@ -388,7 +423,9 @@ void Parser::appendShortOption(IOption* option, char shortname) pAllOptions.push_back(option); // The short name if (shortname != ' ' and shortname != '\0') + { pShortNames[shortname] = option; + } } void Parser::appendOption(IOption* option, char shortname) @@ -403,7 +440,9 @@ void Parser::appendOption(IOption* option, char shortname) and "The long name of an option must be igreater than 1 (ambigous on Windows)"); #else if (longname.size() == 1) // ambigous on Windows, must not continue + { return; + } #endif pLongNames[longname.c_str()] = option; @@ -414,7 +453,9 @@ void Parser::appendOption(IOption* option, char shortname) // The short name if (shortname != ' ' and shortname != '\0') + { pShortNames[shortname] = option; + } } } // namespace GetOpt diff --git a/src/ext/yuni/src/yuni/core/getopt/parser.h b/src/ext/yuni/src/yuni/core/getopt/parser.h index e025909c4b..90c490089d 100644 --- a/src/ext/yuni/src/yuni/core/getopt/parser.h +++ b/src/ext/yuni/src/yuni/core/getopt/parser.h @@ -9,12 +9,13 @@ ** gitlab: https://gitlab.com/libyuni/libyuni/ (mirror) */ #pragma once -#include "../validator/text/default.h" -#include "option.h" -#include "../../yuni.h" #include #include +#include "../../yuni.h" +#include "../validator/text/default.h" +#include "option.h" + namespace Yuni { namespace GetOpt @@ -167,7 +168,7 @@ class YUNI_DECL Parser final ** \param argv The list of arguments ** \return False if the program should abort */ - ReturnCode operator()(int argc, char* argv[]); + ReturnCode operator()(int argc, const char* argv[]); //@} //! \name Help usage diff --git a/src/libs/antares/args/args_to_utf8.cpp b/src/libs/antares/args/args_to_utf8.cpp index 55a09f00ff..eb14932f42 100644 --- a/src/libs/antares/args/args_to_utf8.cpp +++ b/src/libs/antares/args/args_to_utf8.cpp @@ -39,17 +39,18 @@ // clang-format on #endif // YUNI_OS_WINDOWS -IntoUTF8ArgsTranslator::IntoUTF8ArgsTranslator(int argc, char** argv): +IntoUTF8ArgsTranslator::IntoUTF8ArgsTranslator(int argc, const char** argv): argc_(argc), argv_(argv) { } -std::pair IntoUTF8ArgsTranslator::convert() +std::pair IntoUTF8ArgsTranslator::convert() { #ifdef YUNI_OS_WINDOWS wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc_); - argv_ = (char**)malloc(argc_ * sizeof(char*)); + auto& argv = const_cast(argv_); + argv = (char**)malloc(argc_ * sizeof(char*)); for (int i = 0; i != argc_; ++i) { const uint len = (uint)wcslen(wargv[i]); @@ -61,10 +62,10 @@ std::pair IntoUTF8ArgsTranslator::convert() 0, nullptr, nullptr); - argv_[i] = (char*)malloc((newLen + 1) * sizeof(char)); - memset(argv_[i], 0, (newLen + 1) * sizeof(char)); - WideCharToMultiByte(CP_UTF8, 0, wargv[i], len, argv_[i], newLen, nullptr, nullptr); - argv_[i][newLen] = '\0'; + argv[i] = (char*)malloc((newLen + 1) * sizeof(char)); + memset(argv[i], 0, (newLen + 1) * sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wargv[i], len, argv[i], newLen, nullptr, nullptr); + argv[i][newLen] = '\0'; } #endif return {argc_, argv_}; @@ -73,10 +74,11 @@ std::pair IntoUTF8ArgsTranslator::convert() IntoUTF8ArgsTranslator::~IntoUTF8ArgsTranslator() { #ifdef YUNI_OS_WINDOWS + auto& argv = const_cast(argv_); for (int i = 0; i != argc_; ++i) { - free(argv_[i]); + free(argv[i]); } - free(argv_); + free(argv); #endif } diff --git a/src/libs/antares/args/include/antares/args/args_to_utf8.h b/src/libs/antares/args/include/antares/args/args_to_utf8.h index 8ca9a2e962..9174253fec 100644 --- a/src/libs/antares/args/include/antares/args/args_to_utf8.h +++ b/src/libs/antares/args/include/antares/args/args_to_utf8.h @@ -25,11 +25,11 @@ class IntoUTF8ArgsTranslator { public: - IntoUTF8ArgsTranslator(int argc, char** argv); - std::pair convert(); + IntoUTF8ArgsTranslator(int argc, const char** argv); + std::pair convert(); ~IntoUTF8ArgsTranslator(); private: int argc_; - char** argv_; + const char** argv_; }; diff --git a/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp b/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp index 8ff1c2730d..b512bbf038 100644 --- a/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp +++ b/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp @@ -34,36 +34,13 @@ FileTreeStudyLoader::FileTreeStudyLoader(std::filesystem::path study_path): { } -namespace -{ -/** - * @brief Prepares arguments for the Antares Solver application. - * - * This function prepares the arguments required by the Antares Solver application. - * It takes a span of char pointers and a string_view representing the study path. - * The function creates copies of the required arguments and stores them in a vector. - * The original char pointers in the span are updated to point to the newly created copies. - * Lifetime of values inside argv is determined be the content of the returned vector - * - * @param argv A span of char pointers to be filled with the prepared arguments. - * @param study_path A string_view representing the study path. - * @return std::vector A vector of strings containing the prepared arguments. - */ -void prepareArgs(std::array& argv, std::span data) -{ - argv[0] = data[0].data(); - argv[1] = data[1].data(); -} -} // namespace - std::unique_ptr FileTreeStudyLoader::load() const { using namespace std::literals::string_literals; Antares::Solver::Application application; constexpr unsigned int argc = 2; - std::array keep_alive{""s, study_path_.string()}; - std::array argv; - prepareArgs(argv, keep_alive); + // On Windows, std::filesystem::path::value_type is wchar_t + std::array argv{"", reinterpret_cast(study_path_.c_str())}; application.prepare(argc, argv.data()); return application.acquireStudy(); diff --git a/src/libs/antares/resources/include/antares/resources/resources.h b/src/libs/antares/resources/include/antares/resources/resources.h index d7a905cc45..f6aaabeceb 100644 --- a/src/libs/antares/resources/include/antares/resources/resources.h +++ b/src/libs/antares/resources/include/antares/resources/resources.h @@ -52,7 +52,7 @@ bool FindExampleFolder(YString& folder); /*! ** \brief Initialize variables about resource handling */ -void Initialize(int argc, char* argv[], bool initializeSearchPath = false); +void Initialize(int argc, const char* argv[], bool initializeSearchPath = false); /*! ** \brief Copy the root folder diff --git a/src/libs/antares/resources/resources.cpp b/src/libs/antares/resources/resources.cpp index 650d10e99a..b16dafdf29 100644 --- a/src/libs/antares/resources/resources.cpp +++ b/src/libs/antares/resources/resources.cpp @@ -134,7 +134,7 @@ bool FindExampleFolder(Yuni::String& folder) return false; } -void Initialize(int argc, char** argv, bool initializeSearchPath) +void Initialize(int argc, const char** argv, bool initializeSearchPath) { if (argc < 1 or !argv[0]) { diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index 334e8f86d7..92e380fa17 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -313,7 +313,7 @@ void Application::postParametersChecks() const checkCO2CostColumnNumber(pStudy->areas); } -void Application::prepare(int argc, char* argv[]) +void Application::prepare(int argc, const char* argv[]) { pArgc = argc; pArgv = argv; diff --git a/src/solver/application/include/antares/application/application.h b/src/solver/application/include/antares/application/application.h index be114f2d88..8041677be7 100644 --- a/src/solver/application/include/antares/application/application.h +++ b/src/solver/application/include/antares/application/application.h @@ -56,7 +56,7 @@ class Application final: public Yuni::IEventObserver study, const std::string& studyPath); bool runKirchhoffConstraints(std::shared_ptr study, const std::string& studyPath, diff --git a/src/tools/kirchhoff-cbuilder/main.cpp b/src/tools/kirchhoff-cbuilder/main.cpp index 7097917137..1f4abde58e 100644 --- a/src/tools/kirchhoff-cbuilder/main.cpp +++ b/src/tools/kirchhoff-cbuilder/main.cpp @@ -33,7 +33,7 @@ using namespace Yuni; using namespace Antares; -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { logs.applicationName("k-cbuild"); if (argc < 2) @@ -121,7 +121,7 @@ static void NotEnoughMemory() logs.fatal() << "Not enough memory. aborting."; } -bool initResources(int argc, char* argv[]) +bool initResources(int argc, const char* argv[]) { std::set_new_handler(&NotEnoughMemory); diff --git a/src/tools/ts-generator/include/antares/tools/ts-generator/tsGenerationOptions.h b/src/tools/ts-generator/include/antares/tools/ts-generator/tsGenerationOptions.h index 1d83cce593..e12ed09fd2 100644 --- a/src/tools/ts-generator/include/antares/tools/ts-generator/tsGenerationOptions.h +++ b/src/tools/ts-generator/include/antares/tools/ts-generator/tsGenerationOptions.h @@ -22,7 +22,7 @@ struct Settings std::string linksListToGen; }; -bool parseOptions(int, char*[], Settings&); +bool parseOptions(int, const char*[], Settings&); std::unique_ptr createTsGeneratorParser(Settings&); bool checkOptions(Settings& options); diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index d923d26a6c..3c883a078b 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -64,7 +64,7 @@ std::vector getClustersToGen(Data::AreaList& areas, return clusters; } -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { logs.applicationName("ts-generator"); diff --git a/src/tools/ts-generator/tsGenerationOptions.cpp b/src/tools/ts-generator/tsGenerationOptions.cpp index 29fa64b6ad..468e3c941a 100644 --- a/src/tools/ts-generator/tsGenerationOptions.cpp +++ b/src/tools/ts-generator/tsGenerationOptions.cpp @@ -32,7 +32,7 @@ std::unique_ptr createTsGeneratorParser(Settings& settings return parser; } -bool parseOptions(int argc, char* argv[], Settings& options) +bool parseOptions(int argc, const char* argv[], Settings& options) { auto parser = createTsGeneratorParser(options); switch (auto ret = parser->operator()(argc, argv); ret) diff --git a/src/tools/updater/main.cpp b/src/tools/updater/main.cpp index e1cc84944d..c32007cce3 100644 --- a/src/tools/updater/main.cpp +++ b/src/tools/updater/main.cpp @@ -166,7 +166,7 @@ std::string getMargin(int size) return margin; } -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { // locale InitializeDefaultLocale(); diff --git a/src/tools/vacuum/main.cpp b/src/tools/vacuum/main.cpp index 8f78afd038..a89ac2532c 100644 --- a/src/tools/vacuum/main.cpp +++ b/src/tools/vacuum/main.cpp @@ -240,7 +240,7 @@ class DirectoryCleanerJob: public Job::IJob } // anonymous namespace -int main(int argc, char** argv) +int main(int argc, const char** argv) { // locale InitializeDefaultLocale(); diff --git a/src/tools/yby-aggregator/main.cpp b/src/tools/yby-aggregator/main.cpp index 31dd7c0cc3..3aa10b8788 100644 --- a/src/tools/yby-aggregator/main.cpp +++ b/src/tools/yby-aggregator/main.cpp @@ -295,7 +295,7 @@ static void PrepareTheWork(const String::Vector& outputs, Progress::Total = nbJobs; } -static void ReadCommandLineOptions(int argc, char** argv) +static void ReadCommandLineOptions(int argc, const char** argv) { String::Vector optOutputs; uint optJobs = FindNbProcessors(); @@ -642,7 +642,7 @@ static bool WriteAggregates() return true; } -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { // locale InitializeDefaultLocale(); diff --git a/src/ui/simulator/application/application.cpp b/src/ui/simulator/application/application.cpp index e05505fc49..932a5dc3b5 100644 --- a/src/ui/simulator/application/application.cpp +++ b/src/ui/simulator/application/application.cpp @@ -246,7 +246,7 @@ bool Application::OnInit() { String s; wxStringToString(wxString(argv[0]), s); - char* c_argv[] = {s.data(), nullptr}; + const char* c_argv[] = {s.data(), nullptr}; // Load the local policy settings LocalPolicy::Open(); diff --git a/src/ui/simulator/main.cpp b/src/ui/simulator/main.cpp index 7fc62536dc..1a88811fee 100644 --- a/src/ui/simulator/main.cpp +++ b/src/ui/simulator/main.cpp @@ -1,33 +1,36 @@ /* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ -#include -#include "application/application.h" #include "application/main.h" + +#include #include + #include +#include +#include #include #include -#include -#include + +#include "application/application.h" #ifdef YUNI_OS_MSVC // WxWidgets Stuff @@ -42,10 +45,12 @@ IMPLEMENT_APP_NO_MAIN(Antares::Application) using namespace Yuni; using namespace Antares; -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { if (not memory.initializeTemporaryFolder()) + { return EXIT_FAILURE; + } // We have one or several arguments IntoUTF8ArgsTranslator toUTF8ArgsTranslator(argc, argv); @@ -94,7 +99,7 @@ int main(int argc, char* argv[]) Resources::Initialize(argc, argv, true); // Running the GUI - const int ret = wxEntry(argc, argv); + const int ret = wxEntry(argc, const_cast(argv)); LocalPolicy::Close(); return ret; From 8a929e5eeddc05f74e800b1e1d0ecd41fd1d328c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jason=20Mar=C3=A9chal?= <45510813+JasonMarechal25@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:47:07 +0200 Subject: [PATCH 105/127] Enable parallel run for API (#2337) Enable parallel by default --- .../antares/file-tree-study-loader/FileTreeStudyLoader.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp b/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp index b512bbf038..92b8691d83 100644 --- a/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp +++ b/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2007-2024, RTE (https://www.rte-france.com) * See AUTHORS.txt @@ -38,9 +37,11 @@ std::unique_ptr FileTreeStudyLoader::load() const { using namespace std::literals::string_literals; Antares::Solver::Application application; - constexpr unsigned int argc = 2; + constexpr unsigned int argc = 3; // On Windows, std::filesystem::path::value_type is wchar_t - std::array argv{"", reinterpret_cast(study_path_.c_str())}; + std::array argv{"", + reinterpret_cast(study_path_.c_str()), + "--parallel"}; application.prepare(argc, argv.data()); return application.acquireStudy(); From ffec921a00684a1a32c1d93d2fc396b78d50b662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 21 Aug 2024 12:58:10 +0200 Subject: [PATCH 106/127] Remove useless ;, macro definition (#2348) So that clang-format==18.3.7 does not change the format (from current 18.3.1) --- .../infoCollection/StudyInfoCollector.h | 4 +++- src/libs/antares/locator/locator.cpp | 4 ---- src/tests/src/api_internal/test_api.cpp | 4 +++- .../libs/antares/array/matrix-bypass-load.h | 24 ++++++++++++++----- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/libs/antares/InfoCollection/include/antares/infoCollection/StudyInfoCollector.h b/src/libs/antares/InfoCollection/include/antares/infoCollection/StudyInfoCollector.h index 6aca93a605..96f83b38af 100644 --- a/src/libs/antares/InfoCollection/include/antares/infoCollection/StudyInfoCollector.h +++ b/src/libs/antares/InfoCollection/include/antares/infoCollection/StudyInfoCollector.h @@ -69,7 +69,9 @@ class SimulationInfoCollector { public: SimulationInfoCollector(const OptimizationInfo& optInfo): - opt_info_(optInfo){}; + opt_info_(optInfo) + { + } void toFileContent(FileContent& file_content); diff --git a/src/libs/antares/locator/locator.cpp b/src/libs/antares/locator/locator.cpp index fbb4087086..7a3e9436ef 100644 --- a/src/libs/antares/locator/locator.cpp +++ b/src/libs/antares/locator/locator.cpp @@ -31,10 +31,6 @@ using namespace Yuni; -#define SEP \ - Yuni:; \ - IO::Separator - namespace Antares::Solver { bool FindLocation(String& location) diff --git a/src/tests/src/api_internal/test_api.cpp b/src/tests/src/api_internal/test_api.cpp index fe006c9bd6..d8b52d3332 100644 --- a/src/tests/src/api_internal/test_api.cpp +++ b/src/tests/src/api_internal/test_api.cpp @@ -33,7 +33,9 @@ class InMemoryStudyLoader: public Antares::IStudyLoader { public: explicit InMemoryStudyLoader(bool success = true): - success_(success){}; + success_(success) + { + } [[nodiscard]] std::unique_ptr load() const override { diff --git a/src/tests/src/libs/antares/array/matrix-bypass-load.h b/src/tests/src/libs/antares/array/matrix-bypass-load.h index c981a8d199..543c4d848a 100644 --- a/src/tests/src/libs/antares/array/matrix-bypass-load.h +++ b/src/tests/src/libs/antares/array/matrix-bypass-load.h @@ -49,15 +49,21 @@ class Matrix_load_bypass: public Matrix_easy_to_fill public: Matrix_load_bypass(): Matrix_easy_to_fill(), - loadFromCSVFile_called(false){}; + loadFromCSVFile_called(false) + { + } Matrix_load_bypass(uint height, uint width): Matrix_easy_to_fill(height, width), - loadFromCSVFile_called(false){}; + loadFromCSVFile_called(false) + { + } Matrix_load_bypass(uint height, uint width, const vector& vec): Matrix_easy_to_fill(height, width, vec), - loadFromCSVFile_called(false){}; + loadFromCSVFile_called(false) + { + } bool loadFromCSVFile(const AnyString& /* filename */, uint /* minWidth */, @@ -128,15 +134,21 @@ class Matrix_mock_load_to_buffer: public Matrix public: Matrix_mock_load_to_buffer(): Matrix(), - fake_mtx_error_when_loading_(IO::errNone){}; + fake_mtx_error_when_loading_(IO::errNone) + { + } Matrix_mock_load_to_buffer(uint height, uint width): Matrix(height, width), - fake_mtx_error_when_loading_(IO::errNone){}; + fake_mtx_error_when_loading_(IO::errNone) + { + } Matrix_mock_load_to_buffer(uint height, uint width, const vector& vec): Matrix(height, width, vec), - fake_mtx_error_when_loading_(IO::errNone){}; + fake_mtx_error_when_loading_(IO::errNone) + { + } IO::Error loadFromFileToBuffer(typename Matrix::BufferType& /* buffer */, const AnyString& /* filename */) const override From b40196984987ea904180bf89ae84b375e24468db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jason=20Mar=C3=A9chal?= <45510813+JasonMarechal25@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:39:03 +0200 Subject: [PATCH 107/127] Revert "Fix/rhs hydro power constraint (#2034)" (#2350) This reverts commit 1d166e8e31a5edd57818685f51286a3e7dd52e70. Unfaisibility have been encountered following this commit --- docs/user-guide/solver/06-hydro-heuristics.md | 46 +++++++++---------- src/solver/hydro/management/daily.cpp | 8 ++-- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/docs/user-guide/solver/06-hydro-heuristics.md b/docs/user-guide/solver/06-hydro-heuristics.md index eb5567ffe8..78ff065933 100644 --- a/docs/user-guide/solver/06-hydro-heuristics.md +++ b/docs/user-guide/solver/06-hydro-heuristics.md @@ -33,7 +33,7 @@ not be confused with those of the document "optimization problem formulation" The hydro storage energy monthly and weekly profiles of each zone $z$ do not depend at all on the local demand and must-run generation in $z$ - $L_{z.}^+$ Time-series of "net" load for zone $z$, defined as: $L{z.}^+ = L{z.} - M{z.}$ -- $L_{z.}$ Time-series of "weighted" load for zone $z$, defined as: $L_{z.} = A^t L_{z.}^+$ +- $L_{z.}$ Time-series of "weighted" load for zone $z$, defined as:_ $L_{z.} = A^t L_{z.}^+$ All following parameters are related to the generic zone $z$: @@ -47,9 +47,9 @@ not be confused with those of the document "optimization problem formulation" - $S$ Reservoir size -- $\overline{S_d}$ Reservoir maximum level at the end of day d (rule curve) +- $\overline{S_d}$ Reservoir maximum level at the end of day d, expressed as a fraction of $S$ (rule curve) -- $\underline{S_d}$ Reservoir minimum level at the end of day d (rule curve) +- $\underline{S_d}$ Reservoir minimum level at the end of day d, expressed as a fraction of $S$ (rule curve) - $S_0$ Reservoir initial level at the beginning of the first day of the "hydro-year" @@ -72,18 +72,18 @@ not be confused with those of the document "optimization problem formulation" - $W_m^k$ Energy to generate on month m, at the end of stage k of pre-allocation -Following variables and parameters are local to linear optimization problems $M$ & $D(m)$ +Following variables and parameters are local to linear optimization problems $M$ & $D(Tm)$ solved within the heuristic. For the sake of clarity, the same generic index is used for all time steps, -knowing that in $M$ there are 12 monthly time-steps, while in $D(m)$ there are from 28 to 31 daily +knowing that in $M$ there are 12 monthly time-steps, while in $D(m)t$ there are from 28 to 31 daily time-steps. Costs $\gamma_{Var}$ given to these variables are chosen to enforce a logical hierarchy of penalties (letting the reservoir overflow is worse than violating rule curves, which is worse than deviating from the generation objective assessed in stage 1, etc.) -- $W$ Generation deficit at the end of the period, as compared to the objective aimed at (positive varaible) +- $Y$ Generation deficit at the end of the period, as compared to the objective aimed at -- $O_t$ Overflow from the reservoir on time step $t$ (positive varaible) +- $O_t$ Overflow from the reservoir on time step $t$ -- $G_t, \overline{G_t}, \underline{G_t}$ Optimal generation, maximum and minimum generation on time step $t$ +- $G_t, \overline{G_t}$ Optimal generation and maximum generation on time step $t$ - $T_t$ Generation objective assessed in the first stage, for time step t ( $W_m^1$ or $W_d^1$) @@ -95,9 +95,9 @@ from the generation objective assessed in stage 1, etc.) - $\Delta$ Maximum deviation throughout the period -- $V_t^+$ Amplitude of the violation of the upper rule curve at time step $t$ (positive variable) +- $V_t^+$ Amplitude of the violation of the upper rule curve at time step $t$ -- $V_t^-$ Amplitude of the violation of the lower rule curve at time step $t$ (positive variable) +- $V_t^-$ Amplitude of the violation of the lower rule curve at time step $t$ - $Y$ Maximum violation of lower rule curve throughout the period @@ -117,20 +117,17 @@ $$else: \text{for } m\in [1, 12]: \{W_m^1 \leftarrow I_m\}$$ _M2:_ -$$if (\mu) : \text{for } m\in [1, 12]: W_m^2 \leftarrow \text{Solution of linear problem M}$$ - -$$else : W_m^2 \leftarrow W_m^1$$ +$$\text{for } m\in [1, 12]: W_m^2 \leftarrow \text{Solution of linear problem M}$$ _D1:_ $$if (j): \text{for } d\in [1, 31]: W_d^1 \leftarrow \frac{L_d^{\beta}. (W_m^2)}{(\sum_{d\in m}{L_d^{\beta}})}$$ -$$else: \text{for } d\in [1, 31]: W_d^1 \leftarrow I_d $$ +$$else: \text{for } d\in [1, 31]: W_d^1 \leftarrow \frac{I_d . (W_m^2)} {(\sum_{d\in m}{I_d})}$$ _D2:_ -$$if(\mu) : \text{for } m \in [1, 12]: W_{d\in m}^2 \leftarrow \text{Solution of linear problem D(m)}$$ -$ else : \text{for } m \in [1, 12]: W_{d\in m}^2 \leftarrow$ Solution of a simplified version of linear problem $D(m)$ without reservoir levels +$$\text{for } m \in [1, 12]: W_{d\in m}^2 \leftarrow \text{Solution of linear problem D(m)}$$ _End_ @@ -149,9 +146,9 @@ $$S_t \geq 0$$ $$S_t \leq S$$ -$G_t \geq \underline{G_t} $ and $G_t \leq \overline{G_t} $ +$S_t + G_t - S_{t-1} = I_t$ (see note [^monthly_allocation]) -For $t\in [1,12], S_{t} + G_{t} - S_{t-1} = I_{t}$ (see note [^monthly_allocation]) and $S_{12} = S_{0}.$ +$$\sum_{t}{G_t} = \sum_{t}{T_t}$$ $$G_t - D_t \leq T_t$$ @@ -163,28 +160,27 @@ $$V_t^+ - S_t \geq -\overline{S_t}$$ $$Y - V_t^- \geq 0$$ -$$\Delta - D_t \geq 0$$ **Optimization problems $D(m)$** -$$\min_{G_t, S_t, ...}{\gamma_{\Delta}\Delta + \gamma_Y Y + \gamma_{W}W+ \sum_{t}{(\gamma_D D_t + \gamma_{V-} V_t^- + \gamma_{O} O_t + \gamma_S S_t)}}$$ +$$\min_{G_t, S_t, ...}{\gamma_{\Delta}\Delta + \gamma_Y Y + \sum_{t}{(\gamma_D D_t + \gamma_{V-} V_t^- + \gamma_{O} O_t + \gamma_S S_t)}}$$ s.t $$S_t \geq 0$$ $$S_t \leq S$$ -$$G_t \geq \underline{G_t}$$ +$$G_t \geq 0$$ $$G_t \leq \overline{G_t}$$ -$S_t + G_t + O_t - S_{t-1} = I_t$ (see note [^daily_allocation]) (initial level of the period is either $S_0$ if $m=1$ or the final level found in solving $D(m-1)$) +$S_t + G_t + O_t - S_{t-1} = I_t$ (see note [^daily_allocation]) -$\sum_{t}{G_t + W} = \sum_{t}{T_t} + W_{m-1}$ (0 if $m=1$ else value of $W$ previously found in solving **$D(m-1)$**) +$\sum_{t}{G_t + Y} = \sum_{t}{T_t} + Y_{m-1}$ (value of Y previously found in solving **$D(m-1)$**) -$$G_t - D_t \leq T_t + \frac{W_{m-1}}{|d \in m|}$$ +$$G_t - D_t \leq T_t$$ -$$G_t + D_t \geq T_t + \frac{W_{m-1}}{|d \in m|}$$ +$$G_t + D_t \geq T_t$$ $$\Delta - D_t \geq 0$$ diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index 2f0f672acd..254ab2b1b2 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -513,11 +513,9 @@ inline void HydroManagement::prepareDailyOptimalGenerations( for (uint day = firstDay; day != endDay; ++day) { ventilationResults.HydrauliqueModulableQuotidien[day] = problem - .Turbine[dayMonth] - * reservoirCapacity - + problem.overflows - [dayMonth] - * reservoirCapacity; + .Turbine[dayMonth] + * reservoirCapacity; + ventilationResults.NiveauxReservoirsFinJours[day] = problem.niveauxFinJours [dayMonth]; From f157f0be9b01d23e73f3c5b482d2d01b3e54c461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 21 Aug 2024 16:27:38 +0200 Subject: [PATCH 108/127] Fix various compilation warnings (#2346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Comparison of a bool - Loss of integer precision - Conversion of double -> unsigned --------- Co-authored-by: Jason Maréchal <45510813+JasonMarechal25@users.noreply.github.com> --- src/libs/antares/benchmarking/DurationCollector.cpp | 6 ++++-- src/libs/antares/utils/utils.cpp | 2 +- src/libs/antares/writer/zip_writer.cpp | 4 +++- src/solver/simulation/sim_calcul_economique.cpp | 6 +++--- src/tests/src/libs/antares/writer/test_writer.cpp | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/libs/antares/benchmarking/DurationCollector.cpp b/src/libs/antares/benchmarking/DurationCollector.cpp index 9d66166bca..83b50d0f53 100644 --- a/src/libs/antares/benchmarking/DurationCollector.cpp +++ b/src/libs/antares/benchmarking/DurationCollector.cpp @@ -36,7 +36,9 @@ void DurationCollector::toFileContent(FileContent& file_content) { for (const auto& [name, durations]: duration_items_) { - const int64_t duration_sum = accumulate(durations.begin(), durations.end(), 0); + const int64_t duration_sum = accumulate(durations.begin(), + durations.end(), + static_cast(0)); file_content.addDurationItem(name, (unsigned int)duration_sum, (int)durations.size()); } @@ -67,7 +69,7 @@ int64_t DurationCollector::getTime(const std::string& name) const { const auto& v = duration_items_.at(name); - return accumulate(v.begin(), v.end(), 0); + return accumulate(v.begin(), v.end(), static_cast(0)); } } // namespace Benchmarking diff --git a/src/libs/antares/utils/utils.cpp b/src/libs/antares/utils/utils.cpp index e188b2b13a..92be168726 100644 --- a/src/libs/antares/utils/utils.cpp +++ b/src/libs/antares/utils/utils.cpp @@ -147,7 +147,7 @@ bool isZero(double d) double round(double d, unsigned precision) { - unsigned factor = std::pow(10, precision); + auto factor = std::pow(10, precision); return std::round(d * factor) / factor; } diff --git a/src/libs/antares/writer/zip_writer.cpp b/src/libs/antares/writer/zip_writer.cpp index 6359460f8a..ddfee2918e 100644 --- a/src/libs/antares/writer/zip_writer.cpp +++ b/src/libs/antares/writer/zip_writer.cpp @@ -99,7 +99,9 @@ void ZipWriteJob::writeEntry() { logErrorAndThrow("Error opening entry " + pEntryPath + " (" + std::to_string(ret) + ")"); } - int32_t bw = mz_zip_writer_entry_write(pZipHandle, pContent.data(), pContent.size()); + int32_t bw = mz_zip_writer_entry_write(pZipHandle, + pContent.data(), + static_cast(pContent.size())); if (static_cast(bw) != pContent.size()) { logErrorAndThrow("Error writing entry " + pEntryPath + "(written = " + std::to_string(bw) diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 9fd210f1fd..e14f85e945 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -521,7 +521,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, weekFirstDay); } - if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable > 0) + if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable) { if (area.hydro.hardBoundsOnRuleCurves && problem.CaracteristiquesHydrauliques[k].SuiviNiveauHoraire) @@ -648,7 +648,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, = +hourlyLoad - problem.AllMustRunGeneration[hourInWeek].AllMustRunGenerationOfArea[k]; - if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable > 0) + if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable) { problem.CaracteristiquesHydrauliques[k] .ContrainteDePmaxHydrauliqueHoraire[hourInWeek] @@ -673,7 +673,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, { for (uint k = 0; k < nbPays; ++k) { - if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable > 0) + if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable) { auto& area = *study.areas.byIndex[k]; const auto& scratchpad = scratchmap.at(&area); diff --git a/src/tests/src/libs/antares/writer/test_writer.cpp b/src/tests/src/libs/antares/writer/test_writer.cpp index e3af61cc44..4450b4d937 100644 --- a/src/tests/src/libs/antares/writer/test_writer.cpp +++ b/src/tests/src/libs/antares/writer/test_writer.cpp @@ -61,7 +61,7 @@ std::shared_ptr createThreadPool(int size) std::string removeExtension(const std::string& name, const std::string& ext) { - int length = name.size(); + size_t length = name.size(); if (name.size() > ext.size() && name.substr(length - ext.size()) == ext) { return name.substr(0, length - ext.size()); From f206d45f1f8df6c086541a95dd47193c513961a0 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:30:17 +0200 Subject: [PATCH 109/127] Remove duplication in simulation run (#2274) This work just started... **Situation** : There are code duplications : - When running the simulation, functions we use to do it (**runSimulationInEconomicMode()** and **runSimulationInAdequacyMode()**) are very much the same, the only difference is the C++ type of simulation (**economy** vs **adequacy**). - The way simulation is run from **API** or from classic **Application** look pretty close as well : see methods **APIInternal::execute()** and **Application::execute()**. **Problem** : Difficult to remove the first duplication without removing the second one. **Purpose** : Remove them both. --- src/api/API.cpp | 79 +++++++----------- src/solver/application/application.cpp | 53 ++---------- .../include/antares/application/application.h | 5 +- src/solver/simulation/CMakeLists.txt | 6 +- src/solver/simulation/adequacy_mode.cpp | 50 ------------ src/solver/simulation/economy_mode.cpp | 50 ------------ .../antares/solver/simulation/economy_mode.h | 38 --------- .../{adequacy_mode.h => simulation-run.h} | 20 +++-- src/solver/simulation/simulation-run.cpp | 80 +++++++++++++++++++ 9 files changed, 130 insertions(+), 251 deletions(-) delete mode 100644 src/solver/simulation/adequacy_mode.cpp delete mode 100644 src/solver/simulation/economy_mode.cpp delete mode 100644 src/solver/simulation/include/antares/solver/simulation/economy_mode.h rename src/solver/simulation/include/antares/solver/simulation/{adequacy_mode.h => simulation-run.h} (63%) create mode 100644 src/solver/simulation/simulation-run.cpp diff --git a/src/api/API.cpp b/src/api/API.cpp index a76eb934ec..3580f34752 100644 --- a/src/api/API.cpp +++ b/src/api/API.cpp @@ -20,28 +20,28 @@ */ #include "API.h" -#include "antares/solver/simulation/economy_mode.h" -#include "antares/solver/simulation/adequacy_mode.h" -#include "antares/solver/misc/options.h" -#include "antares/infoCollection/StudyInfoCollector.h" + +#include + +#include #include "antares/benchmarking/DurationCollector.h" #include "antares/exception/LoadingError.hpp" -#include -#include +#include "antares/infoCollection/StudyInfoCollector.h" +#include "antares/solver/misc/options.h" +#include "antares/solver/simulation/simulation-run.h" namespace Antares::API { SimulationResults APIInternal::run(const IStudyLoader& study_loader) { - try { + try + { study_ = study_loader.load(); - } catch (const ::Antares::Error::StudyFolderDoesNotExist& e) { + } + catch (const ::Antares::Error::StudyFolderDoesNotExist& e) + { Antares::API::Error err{.reason = e.what()}; - return { - .simulationPath = "", - .antares_problems = {}, - .error = err - }; + return {.simulationPath = "", .antares_problems = {}, .error = err}; } return execute(); } @@ -50,7 +50,8 @@ SimulationResults APIInternal::run(const IStudyLoader& study_loader) * @brief The execute method is used to execute the simulation. * @return SimulationResults object which contains the results of the simulation. * - * This method is initialy a copy of Application::execute with some modifications hence the apparent dupllication + * This method is initialy a copy of Application::execute with some modifications hence the apparent + * dupllication */ SimulationResults APIInternal::execute() const { @@ -62,8 +63,6 @@ SimulationResults APIInternal::execute() const return {.simulationPath{}, .antares_problems{}, .error = err}; } - study_->computePThetaInfForThermalClusters(); - // Only those two fields are used un simulation Settings settings; settings.tsGeneratorsOnly = false; @@ -74,43 +73,23 @@ SimulationResults APIInternal::execute() const auto ioQueueService = std::make_shared(); ioQueueService->maximumThreadCount(1); ioQueueService->start(); - auto resultWriter = Solver::resultWriterFactory( - study_->parameters.resultFormat, study_->folderOutput, ioQueueService, durationCollector); + auto resultWriter = Solver::resultWriterFactory(study_->parameters.resultFormat, + study_->folderOutput, + ioQueueService, + durationCollector); SimulationObserver simulationObserver; - // Run the simulation - switch (study_->runtime.mode) - { - case Data::SimulationMode::Economy: - case Data::SimulationMode::Expansion: - Solver::runSimulationInEconomicMode(*study_, - settings, - durationCollector, - *resultWriter, - optimizationInfo, - simulationObserver); - break; - case Data::SimulationMode::Adequacy: - Solver::runSimulationInAdequacyMode(*study_, - settings, - durationCollector, - *resultWriter, - optimizationInfo, - simulationObserver); - break; - default: - break; - } + + optimizationInfo = simulationRun(*study_, + settings, + durationCollector, + *resultWriter, + simulationObserver); // Importing Time-Series if asked study_->importTimeseriesIntoInput(); - // Stop the display of the progression - study_->progression.stop(); - return - { - .simulationPath = study_->folderOutput.c_str(), - .antares_problems = simulationObserver.acquireLps(), - .error{} - }; + return {.simulationPath = study_->folderOutput.c_str(), + .antares_problems = simulationObserver.acquireLps(), + .error{}}; } -} // namespace Antares::API \ No newline at end of file +} // namespace Antares::API diff --git a/src/solver/application/application.cpp b/src/solver/application/application.cpp index 92e380fa17..837971f279 100644 --- a/src/solver/application/application.cpp +++ b/src/solver/application/application.cpp @@ -20,8 +20,6 @@ */ #include "antares/application/application.h" -#include - #include #include #include @@ -30,7 +28,6 @@ #include #include #include -#include #include #include #include "antares/antares/version.h" @@ -38,11 +35,10 @@ #include "antares/signal-handling/public.h" #include "antares/solver/misc/system-memory.h" #include "antares/solver/misc/write-command-line.h" -#include "antares/solver/simulation/adequacy_mode.h" -#include "antares/solver/simulation/economy_mode.h" +#include "antares/solver/simulation/simulation-run.h" #include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/solver.h" #include "antares/solver/utils/ortools_utils.h" -#include "antares/study/simulation.h" using namespace Antares::Check; @@ -387,23 +383,12 @@ void Application::execute() memoryReport.interval(1000 * 60 * 5); // 5 minutes memoryReport.start(); - pStudy->computePThetaInfForThermalClusters(); - - // Run the simulation - switch (pStudy->runtime.mode) - { - case Data::SimulationMode::Economy: - case Data::SimulationMode::Expansion: - runSimulationInEconomicMode(); - break; - case Data::SimulationMode::Adequacy: - runSimulationInAdequacyMode(); - break; - default: - break; - } - // TODO : make an interface class for ISimulation, check writer & queue before - // runSimulationInMode() + Simulation::NullSimulationObserver observer; + pOptimizationInfo = simulationRun(*pStudy, + pSettings, + pDurationCollector, + *resultWriter, + observer); // Importing Time-Series if asked pStudy->importTimeseriesIntoInput(); @@ -412,28 +397,6 @@ void Application::execute() pStudy->progression.stop(); } -void Application::runSimulationInEconomicMode() -{ - Simulation::NullSimulationObserver observer; - Solver::runSimulationInEconomicMode(*pStudy, - pSettings, - pDurationCollector, - *resultWriter, - pOptimizationInfo, - observer); -} - -void Application::runSimulationInAdequacyMode() -{ - Simulation::NullSimulationObserver observer; - Solver::runSimulationInAdequacyMode(*pStudy, - pSettings, - pDurationCollector, - *resultWriter, - pOptimizationInfo, - observer); -} - void Application::resetLogFilename() const { fs::path logfile = fs::path(pSettings.studyFolder.c_str()) / "logs"; diff --git a/src/solver/application/include/antares/application/application.h b/src/solver/application/include/antares/application/application.h index 8041677be7..9ce49039a1 100644 --- a/src/solver/application/include/antares/application/application.h +++ b/src/solver/application/include/antares/application/application.h @@ -29,6 +29,7 @@ #include #include "antares/infoCollection/StudyInfoCollector.h" #include "antares/solver/misc/options.h" +#include "antares/solver/simulation/ISimulationObserver.h" namespace Antares::Solver { @@ -92,9 +93,6 @@ class Application final: public Yuni::IEventObserver. - */ - -#include "antares/solver/simulation/adequacy_mode.h" - -#include "antares/solver/simulation/adequacy.h" -#include "antares/solver/simulation/solver.h" - -namespace Antares::Solver -{ -void runSimulationInAdequacyMode(Antares::Data::Study& study, - const Settings& settings, - Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info, - Simulation::ISimulationObserver& simulationObserver) -{ - // Type of the simulation - typedef Solver::Simulation::ISimulation SimulationType; - SimulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); - simulation.checkWriter(); - simulation.run(); - - if (!(settings.noOutput || settings.tsGeneratorsOnly)) - { - durationCollector("synthesis_export") - << [&simulation] { simulation.writeResults(/*synthesis:*/ true); }; - - info = simulation.getOptimizationInfo(); - } -} -} // namespace Antares::Solver diff --git a/src/solver/simulation/economy_mode.cpp b/src/solver/simulation/economy_mode.cpp deleted file mode 100644 index 12a1b24297..0000000000 --- a/src/solver/simulation/economy_mode.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ - -#include "antares/solver/simulation/economy_mode.h" - -#include "antares/solver/simulation/economy.h" -#include "antares/solver/simulation/solver.h" - -namespace Antares::Solver -{ -void runSimulationInEconomicMode(Antares::Data::Study& study, - const Settings& settings, - Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info, - Simulation::ISimulationObserver& simulationObserver) -{ - // Type of the simulation - typedef Solver::Simulation::ISimulation SimulationType; - SimulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); - simulation.checkWriter(); - simulation.run(); - - if (!(settings.noOutput || settings.tsGeneratorsOnly)) - { - durationCollector("synthesis_export") - << [&simulation] { simulation.writeResults(/*synthesis:*/ true); }; - - info = simulation.getOptimizationInfo(); - } -} -} // namespace Antares::Solver diff --git a/src/solver/simulation/include/antares/solver/simulation/economy_mode.h b/src/solver/simulation/include/antares/solver/simulation/economy_mode.h deleted file mode 100644 index e26ebbb7e0..0000000000 --- a/src/solver/simulation/include/antares/solver/simulation/economy_mode.h +++ /dev/null @@ -1,38 +0,0 @@ - -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ - -#pragma once - -#include "antares/infoCollection/StudyInfoCollector.h" -#include "antares/solver/misc/options.h" -#include "antares/solver/simulation/ISimulationObserver.h" -#include "antares/writer/i_writer.h" - -namespace Antares::Solver -{ -void runSimulationInEconomicMode(Antares::Data::Study& study, - const Settings& settings, - Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info, - Simulation::ISimulationObserver& simulationObserver); -} diff --git a/src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h b/src/solver/simulation/include/antares/solver/simulation/simulation-run.h similarity index 63% rename from src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h rename to src/solver/simulation/include/antares/solver/simulation/simulation-run.h index 66734027b9..379959af05 100644 --- a/src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h +++ b/src/solver/simulation/include/antares/solver/simulation/simulation-run.h @@ -1,4 +1,3 @@ - /* * Copyright 2007-2024, RTE (https://www.rte-france.com) * See AUTHORS.txt @@ -23,16 +22,15 @@ #pragma once #include "antares/infoCollection/StudyInfoCollector.h" -#include "antares/solver/misc/options.h" -#include "antares/solver/simulation/ISimulationObserver.h" -#include "antares/writer/i_writer.h" +#include "antares/solver/simulation/solver.h" namespace Antares::Solver { -void runSimulationInAdequacyMode(Antares::Data::Study& study, - const Settings& settings, - Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info, - Simulation::ISimulationObserver& simulationObserver); -} + +Benchmarking::OptimizationInfo simulationRun(Antares::Data::Study& study, + const Settings& settings, + Benchmarking::DurationCollector& durationCollector, + IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver); + +} // namespace Antares::Solver diff --git a/src/solver/simulation/simulation-run.cpp b/src/solver/simulation/simulation-run.cpp new file mode 100644 index 0000000000..c227448f81 --- /dev/null +++ b/src/solver/simulation/simulation-run.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include "include/antares/solver/simulation/simulation-run.h" + +#include "antares/solver/simulation/adequacy.h" +#include "antares/solver/simulation/economy.h" + +namespace Antares::Solver +{ + +template +Benchmarking::OptimizationInfo runSimulation(Antares::Data::Study& study, + const Settings& settings, + Benchmarking::DurationCollector& durationCollector, + IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver) +{ + simulationType simulation(study, settings, durationCollector, resultWriter, simulationObserver); + simulation.checkWriter(); + simulation.run(); + + if (!(settings.noOutput || settings.tsGeneratorsOnly)) + { + durationCollector("synthesis_export") + << [&simulation] { simulation.writeResults(/*synthesis:*/ true); }; + + return simulation.getOptimizationInfo(); + } + return {}; +} + +Benchmarking::OptimizationInfo simulationRun(Antares::Data::Study& study, + const Settings& settings, + Benchmarking::DurationCollector& durationCollector, + IResultWriter& resultWriter, + Simulation::ISimulationObserver& simulationObserver) +{ + study.computePThetaInfForThermalClusters(); + + switch (study.runtime.mode) + { + case Data::SimulationMode::Adequacy: + return runSimulation>( + study, + settings, + durationCollector, + resultWriter, + simulationObserver); + case Data::SimulationMode::Economy: + case Data::SimulationMode::Expansion: + default: + return runSimulation>( + study, + settings, + durationCollector, + resultWriter, + simulationObserver); + } +} + +} // namespace Antares::Solver From 6e26d9ca0a0ae374e8d1153cbcc00da14df64a34 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Fri, 23 Aug 2024 18:33:11 +0200 Subject: [PATCH 110/127] Districts : simplifying the code (#2279) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Type **SetsOfAreas** (see **study.h**) is used to print aggregated results for a group of areas. Its friend **SetsOfLinks** is defined but never used. We remove it and make subsequent simplifications : - [x] class **Sets** no longer needs to be a template class, or have template methods (So **sets.hxx** is removed, and **sets.cpp** is created) - [x] class **SetHandlerAreas** (specific operations very much related to sets of areas) needs to be moved from **Study** code area into **sets.h/.cpp** What should be done in the future : - [ ] class **SetHandlerAreas** should be questioned as a class : does it constitute a cohesive code entity ? Should it not be integrated to class **Sets** ? What should we do with its code so that **Sets** are clearer and simpler (next point may give a solution for this point) ? - [ ] class **Sets** should be refactored : indeed, it contains many **private** **std::vector**s / **std::map**s (**pMap**, **pOptions**, **pByIndex**, ...), associating a property to a set of area. We make many loops over these containers. This is chaotic design. Instead, we should define a class **Set** (for a single set), and make existing class **Sets** a collection of **Set**. Properties of a set should be contained in class **Set**. Besides the fact it would be more natural and clear, I suspect it would cause many simplifications and code reductions. --------- Co-authored-by: Vincent Payet Co-authored-by: Jason Marechal Co-authored-by: Jason Maréchal <45510813+JasonMarechal25@users.noreply.github.com> Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- src/libs/antares/study/CMakeLists.txt | 2 +- .../antares/study/sets.hxx => area/sets.cpp} | 277 +++++++++--------- .../study/include/antares/study/sets.h | 145 +++++---- .../study/include/antares/study/study.h | 21 +- src/libs/antares/study/load.cpp | 97 +----- src/libs/antares/study/study.cpp | 5 - .../antares/solver/variable/setofareas.h | 2 +- 7 files changed, 215 insertions(+), 334 deletions(-) rename src/libs/antares/study/{include/antares/study/sets.hxx => area/sets.cpp} (58%) diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index e9a05827ac..bc06a77089 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -249,7 +249,7 @@ set(SRC_STUDY # Sets include/antares/study/sets.h - include/antares/study/sets.hxx + area/sets.cpp # variable selection include/antares/study/variable-print-info.h diff --git a/src/libs/antares/study/include/antares/study/sets.hxx b/src/libs/antares/study/area/sets.cpp similarity index 58% rename from src/libs/antares/study/include/antares/study/sets.hxx rename to src/libs/antares/study/area/sets.cpp index 2a1b777995..f853c21c0c 100644 --- a/src/libs/antares/study/include/antares/study/sets.hxx +++ b/src/libs/antares/study/area/sets.cpp @@ -18,57 +18,41 @@ ** You should have received a copy of the Mozilla Public Licence 2.0 ** along with Antares_Simulator. If not, see . */ -#ifndef __ANTARES_LIBS_STUDY_SETS_HXX__ -#define __ANTARES_LIBS_STUDY_SETS_HXX__ +#include "antares/study/sets.h" -namespace Antares +namespace Antares::Data { -namespace Data -{ -template -inline Sets::Sets(): - pModified(false) -{ -} - -template -inline Sets::Sets(const Sets& rhs): +Sets::Sets(const Sets& rhs): pMap(rhs.pMap), - pOptions(rhs.pOptions), - pModified(false) + pOptions(rhs.pOptions) { - if (rhs.pByIndex) + if (rhs.pByIndex.size()) { rebuildIndexes(); } } -template -typename Sets::iterator Sets::begin() +Sets::iterator Sets::begin() { return pMap.begin(); } -template -typename Sets::const_iterator Sets::begin() const +Sets::const_iterator Sets::begin() const { return pMap.begin(); } -template -typename Sets::iterator Sets::end() +Sets::iterator Sets::end() { return pMap.end(); } -template -typename Sets::const_iterator Sets::end() const +Sets::const_iterator Sets::end() const { return pMap.end(); } -template -void Sets::clear() +void Sets::clear() { pByIndex.clear(); pNameByIndex.clear(); @@ -76,36 +60,30 @@ void Sets::clear() pOptions.clear(); } -template -inline T& Sets::operator[](uint i) +Sets::SetAreasType& Sets::operator[](uint i) { assert(i < pMap.size() && "Sets: operator[] index out of bounds"); return *(pByIndex[i]); } -template -inline const T& Sets::operator[](uint i) const +const Sets::SetAreasType& Sets::operator[](uint i) const { assert(i < pMap.size() && "Sets: operator[] index out of bounds"); return *(pByIndex[i]); } -template -template -void Sets::dumpToLogs(L& log) const +void Sets::dumpToLogs() const { using namespace Yuni; - const typename MapType::const_iterator end = pMap.end(); - for (typename MapType::const_iterator i = pMap.begin(); i != end; ++i) + for (const auto& [setId, set]: pMap) { - log.info() << " found `" << i->first << "` (" << (uint)i->second->size() << ' ' - << (i->second->size() < 2 ? "item" : "items") - << ((!hasOutput(i->first)) ? ", no output" : "") << ')'; + logs.info() << " found `" << setId << "` (" << set->size() << ' ' + << (set->size() < 2 ? "item" : "items") + << ((!hasOutput(setId)) ? ", no output" : "") << ')'; } } -template -void Sets::defaultForAreas() +void Sets::defaultForAreas() { using namespace Yuni; clear(); @@ -113,23 +91,21 @@ void Sets::defaultForAreas() opts.caption = "All areas"; opts.comments = "Spatial aggregates on all areas"; opts.output = false; - opts.rules.push_back(Rule(ruleFilter, new String("add-all"))); - auto item = std::make_shared(); - add("all areas", item, opts); + opts.rules.emplace_back(ruleFilter, "add-all"); + auto district = std::make_shared(); + add("all areas", district, opts); } -template -YString Sets::toString() +YString Sets::toString() { using namespace Yuni; using namespace Antares; static const char* cmds[ruleMax] = {"none", "+", "-", "apply-filter"}; - const auto end = pOptions.cend(); YString ret = ""; - for (auto i = pOptions.cbegin(); i != end; ++i) + for (const auto& [setId, options]: pOptions) { - const Options& opts = i->second; - ret << '[' << i->first << "]\n"; + const Options& opts = options; + ret << '[' << setId << "]\n"; ret << "caption = " << opts.caption << '\n'; if (not opts.comments.empty()) { @@ -150,13 +126,8 @@ YString Sets::toString() return ret; } -template -template -bool Sets::saveToFile(const StringT& filename) const +bool Sets::saveToFile(const Yuni::String& filename) const { - using namespace Yuni; - using namespace Antares; - Yuni::IO::File::Stream file; if (!file.open(filename, Yuni::IO::OpenMode::write | Yuni::IO::OpenMode::truncate)) { @@ -190,8 +161,7 @@ bool Sets::saveToFile(const StringT& filename) const return true; } -template -bool Sets::loadFromFile(const std::filesystem::path& filename) +bool Sets::loadFromFile(const std::filesystem::path& filename) { using namespace Yuni; using namespace Antares; @@ -221,7 +191,7 @@ bool Sets::loadFromFile(const std::filesystem::path& filename) } // Creating a new section - auto item = std::make_shared(); + auto district = std::make_shared(); Options opts; opts.caption = section->name; @@ -239,17 +209,17 @@ bool Sets::loadFromFile(const std::filesystem::path& filename) if (p->key == "+") { - opts.rules.push_back(Rule(ruleAdd, new String(value))); + opts.rules.emplace_back(ruleAdd, value.to()); continue; } if (p->key == "-") { - opts.rules.push_back(Rule(ruleRemove, new String(value))); + opts.rules.emplace_back(ruleRemove, value.to()); continue; } if (p->key == "apply-filter") { - opts.rules.push_back(Rule(ruleFilter, new String(value))); + opts.rules.emplace_back(ruleFilter, value.to()); continue; } if (p->key == "output") @@ -276,7 +246,7 @@ bool Sets::loadFromFile(const std::filesystem::path& filename) // Add the new group IDType newid = section->name; newid.toLower(); - add(newid, item, opts); + add(newid, district, opts); } // Not modified anymore @@ -288,31 +258,28 @@ bool Sets::loadFromFile(const std::filesystem::path& filename) return false; } -template -template -inline void Sets::rebuildAllFromRules(HandlerT& handler) +void Sets::rebuildAllFromRules(SetHandlerAreas& handler) { - for (uint i = 0; i != pMap.size(); ++i) + for (const auto& setId: pNameByIndex) { - rebuildFromRules(pNameByIndex[i], handler); + rebuildFromRules(setId, handler); } } -template -template -void Sets::rebuildFromRules(const IDType& id, HandlerT& handler) +void Sets::rebuildFromRules(const IDType& id, SetHandlerAreas& handler) { using namespace Yuni; using namespace Antares; - typename MapOptions::iterator i = pOptions.find(id); - if (i == pOptions.end()) + const auto pair = pOptions.find(id); + if (pair == pOptions.end()) { return; } + // Options - Options& opts = i->second; - Type& set = *(pMap[id]); + Options& opts = pair->second; + auto& set = *(pMap[id]); // Clear the result first handler.clear(set); @@ -320,23 +287,20 @@ void Sets::rebuildFromRules(const IDType& id, HandlerT& handler) for (uint i = 0; i != opts.rules.size(); ++i) { const Rule& rule = opts.rules[i]; - const Yuni::String& arg = *(rule.second); + const std::string name = rule.second; switch (rule.first) // type { case ruleAdd: { // Trying to add a single item - if (!handler.add(set, arg)) + if (!handler.add(set, name)) { // Failed. Maybe the argument references another group - const IDType other = arg; - typename MapType::iterator i = pMap.find(other); + const IDType other = name; + MapType::iterator i = pMap.find(other); if (i != pMap.end()) { - if (handler.add(set, *(i->second))) - { - break; - } + handler.add(set, *(i->second)); } } break; @@ -344,24 +308,21 @@ void Sets::rebuildFromRules(const IDType& id, HandlerT& handler) case ruleRemove: { // Trying to remove a single item - if (!handler.remove(set, arg)) + if (!handler.remove(set, name)) { // Failed. Maybe the argument references another group - const IDType other = arg; - typename MapType::iterator i = pMap.find(other); + const IDType other = name; + MapType::iterator i = pMap.find(other); if (i != pMap.end()) { - if (handler.remove(set, *(i->second))) - { - break; - } + handler.remove(set, *(i->second)); } } break; } case ruleFilter: { - handler.applyFilter(set, arg); + handler.applyFilter(set, name); break; } case ruleNone: @@ -379,85 +340,125 @@ void Sets::rebuildFromRules(const IDType& id, HandlerT& handler) << " rules, got " << opts.resultSize << " items"; } -template -void Sets::rebuildIndexes() +void Sets::rebuildIndexes() { pNameByIndex.clear(); + pNameByIndex.resize(pMap.size()); + pByIndex.clear(); + pByIndex.resize(pMap.size()); - if (!pMap.empty()) + uint index = 0; + for (const auto& [setId, set]: pMap) { - pByIndex.resize(pMap.size()); - pNameByIndex.resize(pMap.size()); - const typename MapType::iterator end = pMap.end(); - uint index = 0; - for (typename MapType::iterator i = pMap.begin(); i != end; ++i) - { - pByIndex[index] = i->second; - pNameByIndex[index] = i->first; - ++index; - } + pByIndex[index] = set; + pNameByIndex[index] = setId; + ++index; } } -template -template -inline bool Sets::hasOutput(const StringT& s) const +bool Sets::hasOutput(const Yuni::ShortString128& s) const { - // Assert, if a C* container can not be found at compile time - static_assert(Yuni::Traits::CString::valid); - - typename MapOptions::const_iterator i = pOptions.find(s); - return (i != pOptions.end()) ? i->second.output : false; + const auto pair = pOptions.find(s); + return (pair != pOptions.end()) ? pair->second.output : false; } -template -inline bool Sets::hasOutput(const uint index) const +bool Sets::hasOutput(const uint index) const { return hasOutput(IDType(pNameByIndex[index])); } -template -template -inline uint Sets::resultSize(const StringT& s) const +uint Sets::resultSize(const Yuni::ShortString128& s) const { - // Assert, if a C* container can not be found at compile time - static_assert(Yuni::Traits::CString::valid); - - typename MapOptions::const_iterator i = pOptions.find(s); - return (i != pOptions.end()) ? i->second.resultSize : 0; + const auto pair = pOptions.find(s); + return (pair != pOptions.end()) ? pair->second.resultSize : 0; } -template -template -inline typename Sets::IDType Sets::caption(const StringT& s) const +Sets::IDType Sets::caption(const Yuni::ShortString128& s) const { - // Assert, if a C* container can not be found at compile time - static_assert(Yuni::Traits::CString::valid); - - typename MapOptions::const_iterator i = pOptions.find(s); - return (i != pOptions.end()) ? i->second.caption : IDType(); + const auto pair = pOptions.find(s); + return (pair != pOptions.end()) ? pair->second.caption : IDType(); } -template -inline typename Sets::IDType Sets::caption(const uint i) const +Sets::IDType Sets::caption(const uint i) const { return caption(IDType(pNameByIndex[i])); } -template -inline uint Sets::resultSize(const uint index) const +uint Sets::resultSize(const uint index) const { return resultSize(IDType(pNameByIndex[index])); } -template -inline uint Sets::size() const +uint Sets::size() const { return (uint)pMap.size(); } -} // namespace Data -} // namespace Antares +SetHandlerAreas::SetHandlerAreas(AreaList& areas): + areas_(areas) +{ +} + +void SetHandlerAreas::clear(Sets::SetAreasType& set) +{ + set.clear(); +} + +uint SetHandlerAreas::size(Sets::SetAreasType& set) +{ + return (uint)set.size(); +} + +bool SetHandlerAreas::add(Sets::SetAreasType& set, const std::string& value) +{ + Area* area = AreaListLFind(&areas_, value.c_str()); + if (area) + { + set.insert(area); + return true; + } + return false; +} + +void SetHandlerAreas::add(Sets::SetAreasType& set, const Sets::SetAreasType& otherSet) +{ + set.insert(otherSet.begin(), otherSet.end()); +} + +bool SetHandlerAreas::remove(Sets::SetAreasType& set, const std::string& value) +{ + Area* area = AreaListLFind(&areas_, value.c_str()); + if (area) + { + set.erase(area); + return true; + } + return false; +} + +void SetHandlerAreas::remove(Sets::SetAreasType& set, const Sets::SetAreasType& otherSet) +{ + std::ranges::for_each(otherSet, [&set](auto* area) { set.erase(area); }); +} + +bool SetHandlerAreas::applyFilter(Sets::SetAreasType& set, const std::string& value) +{ + if (value == "add-all") + { + for (const auto& [areaName, area]: areas_) + { + set.insert(area); + } + return true; + } + + if (value == "remove-all") + { + set.clear(); + return true; + } + return false; +} -#endif // __ANTARES_LIBS_STUDY_SETS_HXX__ +} // namespace Antares::Data diff --git a/src/libs/antares/study/include/antares/study/sets.h b/src/libs/antares/study/include/antares/study/sets.h index 414847af2f..3932c99372 100644 --- a/src/libs/antares/study/include/antares/study/sets.h +++ b/src/libs/antares/study/include/antares/study/sets.h @@ -18,8 +18,7 @@ ** You should have received a copy of the Mozilla Public Licence 2.0 ** along with Antares_Simulator. If not, see . */ -#ifndef __ANTARES_LIBS_STUDY_SETS_H__ -#define __ANTARES_LIBS_STUDY_SETS_H__ +#pragma once #include #include @@ -31,29 +30,32 @@ #include #include +#include "antares/study/area/area.h" -namespace Antares +namespace Antares::Data { -namespace Data -{ -template +class SetHandlerAreas; + class Sets final { public: - //! Type - using Type = T; - // - using IDType = Yuni::CString<128, false>; + using IDType = Yuni::ShortString128; + + //! A single set of areas + // CompareAreaName : to control the order of areas in a set of areas. This order can have an + // effect, even if tiny, on the results of aggregations. + using SetAreasType = std::set; + //! Value - using TypePtr = std::shared_ptr; + using TypePtr = std::shared_ptr; //! Map of Item using MapType = std::map; //! Standard iterators from the STL - using iterator = typename MapType::iterator; + using iterator = MapType::iterator; //! Standard iterators from the STL (const) - using const_iterator = typename MapType::const_iterator; + using const_iterator = MapType::const_iterator; enum RuleType { @@ -65,7 +67,7 @@ class Sets final }; //! Definition of a single rule - using Rule = std::pair; + using Rule = std::pair; //! Rule Set using RuleSet = std::vector; @@ -128,7 +130,7 @@ class Sets final /*! ** \brief Default constructor */ - Sets(); + Sets() = default; /*! ** \brief Copy constructor */ @@ -150,37 +152,6 @@ class Sets final */ void clear(); - /*! - ** - */ - TypePtr add(const IDType& name) - { - TypePtr p = std::make_shared(); - pMap[name] = p; - pOptions[name].reset(name); - return p; - } - - /*! - ** - */ - TypePtr add(const IDType& name, const TypePtr& data) - { - pMap[name] = data; - pOptions[name].reset(name); - return data; - } - - /*! - ** - */ - TypePtr add(const IDType& name, const TypePtr& data, Options& opts) - { - pMap[name] = data; - pOptions[name] = opts; - return data; - } - bool forceReload(bool /*reload*/) const { pModified = true; @@ -194,13 +165,10 @@ class Sets final uint size() const; - void rebuildIndexes(); - /*! ** \brief Get if the results for a given group should be written to the output */ - template - bool hasOutput(const StringT& s) const; + bool hasOutput(const Yuni::ShortString128& s) const; /*! ** \brief Get if the results for a given group should be written to the output @@ -210,24 +178,21 @@ class Sets final /*! ** \brief Get the size of a result set */ - template - uint resultSize(const StringT& s) const; + uint resultSize(const Yuni::ShortString128& s) const; /*! ** \brief Get the size of a result set */ uint resultSize(const uint index) const; - template - void dumpToLogs(L& log) const; + void dumpToLogs() const; /*! ** \brief Load a rule set from an INI File */ bool loadFromFile(const std::filesystem::path& filename); - template - bool saveToFile(const StringT& filename) const; + bool saveToFile(const Yuni::String& filename) const; /*! ** \brief format the string to match the options */ @@ -238,17 +203,10 @@ class Sets final */ void defaultForAreas(); - /*! - ** \brief Rebuild the lists of a group from the rules - */ - template - void rebuildFromRules(const IDType& id, HandlerT& handler); - /*! ** \brief Rebuild the lists of all group from the rules */ - template - void rebuildAllFromRules(HandlerT& handler); + void rebuildAllFromRules(SetHandlerAreas& handler); const IDType& nameByIndex(const uint i) const { @@ -256,28 +214,65 @@ class Sets final return pNameByIndex[i]; } - template - IDType caption(const StringT& s) const; - + IDType caption(const Yuni::ShortString128& s) const; IDType caption(const uint i) const; - T& operator[](uint i); - const T& operator[](uint i) const; + SetAreasType& operator[](uint i); + const SetAreasType& operator[](uint i) const; private: + TypePtr add(const IDType& name) + { + TypePtr p = std::make_shared(); + pMap[name] = p; + pOptions[name].reset(name); + return p; + } + + TypePtr add(const IDType& name, const TypePtr& data) + { + pMap[name] = data; + pOptions[name].reset(name); + return data; + } + + TypePtr add(const IDType& name, const TypePtr& data, Options& opts) + { + pMap[name] = data; + pOptions[name] = opts; + return data; + } + + /*! + ** \brief Rebuild the lists of a group from the rules + */ + void rebuildFromRules(const IDType& id, SetHandlerAreas& handler); + void rebuildIndexes(); + //! All groups MapType pMap; MapOptions pOptions; //! std::vector pByIndex; std::vector pNameByIndex; - mutable bool pModified; - + mutable bool pModified = false; }; // class Sets -} // namespace Data -} // namespace Antares +class SetHandlerAreas +{ +public: + explicit SetHandlerAreas(AreaList& areas); + void clear(Sets::SetAreasType& set); + uint size(Sets::SetAreasType& set); -#include "sets.hxx" + bool add(Sets::SetAreasType& set, const std::string& value); + void add(Sets::SetAreasType& set, const Sets::SetAreasType& otherSet); + bool remove(Sets::SetAreasType& set, const std::string& value); + void remove(Sets::SetAreasType& set, const Sets::SetAreasType& otherSet); + bool applyFilter(Sets::SetAreasType& set, const std::string& value); + +private: + AreaList& areas_; +}; // class SetHandlerAreas -#endif // __ANTARES_LIBS_STUDY_SETS_H__ +} // namespace Antares::Data diff --git a/src/libs/antares/study/include/antares/study/study.h b/src/libs/antares/study/include/antares/study/study.h index d558a89213..0a7dd0eb31 100644 --- a/src/libs/antares/study/include/antares/study/study.h +++ b/src/libs/antares/study/include/antares/study/study.h @@ -66,25 +66,8 @@ class Study: public Yuni::NonCopyable, public LayerData //! List of studies using List = std::list; - //! A single set of areas - // CompareAreaName : to control the order of areas in a set of areas. This order can have an - // effect, even if tiny, on the results of aggregations. - using SingleSetOfAreas = std::set; - //! Multiple sets of areas - using SetsOfAreas = Antares::Data::Sets; - - //! A single set of links - using SingleSetOfLinks = std::set; - //! Multiple sets of links - using SetsOfLinks = Antares::Data::Sets; - - //! List of disabled areas - using DisabledAreaList = std::set; - //! List of disabled links - using DisabledAreaLinkList = std::set; - //! List of disabled thermal clusters - using DisabledThermalClusterList = std::set; + using SetsOfAreas = Antares::Data::Sets; //! Extension filename using FileExtension = std::string; @@ -573,8 +556,6 @@ class Study: public Yuni::NonCopyable, public LayerData //@{ //! Sets of areas SetsOfAreas setsOfAreas; - //! Sets of links - SetsOfLinks setsOfLinks; //@} //! \name Scenario Builder diff --git a/src/libs/antares/study/load.cpp b/src/libs/antares/study/load.cpp index 749d0d81ff..626cb3564d 100644 --- a/src/libs/antares/study/load.cpp +++ b/src/libs/antares/study/load.cpp @@ -289,97 +289,6 @@ bool Study::internalLoadBindingConstraints(const StudyLoadOptions& options) return (!r && options.loadOnlyNeeded) ? false : r; } -class SetHandlerAreas -{ -public: - explicit SetHandlerAreas(Study& study): - pStudy(study) - { - } - - void clear(Study::SingleSetOfAreas& set) - { - set.clear(); - } - - uint size(Study::SingleSetOfAreas& set) - { - return (uint)set.size(); - } - - bool add(Study::SingleSetOfAreas& set, const String& value) - { - Area* area = AreaListLFind(&pStudy.areas, value.c_str()); - if (area) - { - set.insert(area); - return true; - } - return false; - } - - bool add(Study::SingleSetOfAreas& set, const Study::SingleSetOfAreas& otherSet) - { - if (!otherSet.empty()) - { - auto end = otherSet.end(); - for (auto i = otherSet.begin(); i != end; ++i) - { - set.insert(*i); - } - } - return true; - } - - bool remove(Study::SingleSetOfAreas& set, const String& value) - { - Area* area = AreaListLFind(&pStudy.areas, value.c_str()); - if (area) - { - set.erase(area); - return true; - } - return false; - } - - bool remove(Study::SingleSetOfAreas& set, const Study::SingleSetOfAreas& otherSet) - { - if (!otherSet.empty()) - { - auto end = otherSet.end(); - for (auto i = otherSet.begin(); i != end; ++i) - { - set.erase(*i); - } - } - return true; - } - - bool applyFilter(Study::SingleSetOfAreas& set, const String& value) - { - if (value == "add-all") - { - auto end = pStudy.areas.end(); - for (auto i = pStudy.areas.begin(); i != end; ++i) - { - set.insert(i->second); - } - return true; - } - - if (value == "remove-all") - { - set.clear(); - return true; - } - return false; - } - -private: - Study& pStudy; - -}; // class SetHandlerAreas - bool Study::internalLoadSets() { const fs::path path = fs::path(folderInput.c_str()) / "areas" / "sets.ini"; @@ -394,10 +303,10 @@ bool Study::internalLoadSets() if (setsOfAreas.loadFromFile(path)) { // Apply the rules - SetHandlerAreas handler(*this); + SetHandlerAreas handler(areas); setsOfAreas.rebuildAllFromRules(handler); // Write the results into the logs - setsOfAreas.dumpToLogs(logs); + setsOfAreas.dumpToLogs(); return true; } @@ -417,7 +326,7 @@ bool Study::reloadXCastData() // if changes are required, please update AreaListLoadFromFolderSingleArea() bool ret = true; areas.each( - [this, &ret](Data::Area& area) + [this, &ret](Area& area) { assert(area.load.prepro); assert(area.solar.prepro); diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 111330e07b..67206dad70 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -110,7 +110,6 @@ void Study::clear() // areas setsOfAreas.clear(); - setsOfLinks.clear(); preproLoadCorrelation.clear(); preproSolarCorrelation.clear(); @@ -150,9 +149,7 @@ void Study::createAsNew() // Sets setsOfAreas.defaultForAreas(); - setsOfLinks.clear(); setsOfAreas.markAsModified(); - setsOfLinks.markAsModified(); // Binding constraints bindingConstraints.clear(); @@ -1171,7 +1168,6 @@ bool Study::forceReload(bool reload) const ret = preproHydroCorrelation.forceReload(reload) and ret; ret = setsOfAreas.forceReload(reload) and ret; - ret = setsOfLinks.forceReload(reload) and ret; return ret; } @@ -1187,7 +1183,6 @@ void Study::markAsModified() const bindingConstraints.markAsModified(); setsOfAreas.markAsModified(); - setsOfLinks.markAsModified(); } void Study::relocate(const std::string& newFolder) diff --git a/src/solver/variable/include/antares/solver/variable/setofareas.h b/src/solver/variable/include/antares/solver/variable/setofareas.h index d2444df247..1263b986f3 100644 --- a/src/solver/variable/include/antares/solver/variable/setofareas.h +++ b/src/solver/variable/include/antares/solver/variable/setofareas.h @@ -204,7 +204,7 @@ class SetsOfAreas //! Area list SetOfAreasVector pSetsOfAreas; //! Reference to the origina set - std::vector pOriginalSets; + std::vector pOriginalSets; //! An iterator for the begining of the list typename SetOfAreasVector::iterator pBegin; //! An iterator to the end of the list From f6ee594ef4fa3ad99bfa3d77a56694c314ad5144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 26 Aug 2024 14:36:11 +0200 Subject: [PATCH 111/127] Fix clang++ warning about typeid (#2340) Expression with side effects will be evaluated despite being used as an operand to 'typeid' --- src/solver/infeasible-problem-analysis/report.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index 4be4463400..a323b30be2 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -49,13 +49,18 @@ void InfeasibleProblemReport::buildConstraintsFromSlackVars( bool lessTypeName(const std::shared_ptr a, const std::shared_ptr b) { - return std::type_index(typeid(*a)) < std::type_index(typeid(*b)); + const WatchedConstraint* a_raw = a.get(); + const WatchedConstraint* b_raw = b.get(); + // TODO Compiler-dependent behavior + return std::type_index(typeid(*a_raw)) < std::type_index(typeid(*b_raw)); } bool sameType(const std::shared_ptr a, const std::shared_ptr b) { - return std::type_index(typeid(*a)) == std::type_index(typeid(*b)); + const WatchedConstraint* a_raw = a.get(); + const WatchedConstraint* b_raw = b.get(); + return std::type_index(typeid(*a_raw)) == std::type_index(typeid(*b_raw)); } bool greaterValue(const std::shared_ptr a, std::shared_ptr b) From c8ffce8725079ad7c410373d11839cd7da7b6bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 26 Aug 2024 14:36:34 +0200 Subject: [PATCH 112/127] Disable CMAKE_COLOR_DIAGNOSTICS (#2344) Revert #2320 It completely messes with my editor (emacs), to the point where I'm no longer able to navigate to files. ![image](https://github.com/user-attachments/assets/af5c9a9e-52d6-442b-b92d-2080ca827204) @payetvin You can force this option locally using -DXXXX=ON --- src/cmake/common-settings.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cmake/common-settings.cmake b/src/cmake/common-settings.cmake index 69d52bc3ad..b659a5f46c 100644 --- a/src/cmake/common-settings.cmake +++ b/src/cmake/common-settings.cmake @@ -14,7 +14,6 @@ set(COMMON_MSVC_FLAGS "/W3 /MP4") set(COMMON_MSVC_FLAGS "${COMMON_MSVC_FLAGS} /we4715 /we4716") #adding no return or no return for all code paths as errors set(ADDITIONAL_C_FLAGS " -Wconversion -Wmissing-prototypes -Wstrict-prototypes") set(ADDITIONAL_C_FLAGS "${ADDITIONAL_C_FLAGS} -Wmissing-noreturn -Wpacked -Wredundant-decls -Wbad-function-cast -W -Wcast-align -Wcast-qual -Wsign-compare -fno-exceptions -Wdeclaration-after-statement") -set(CMAKE_COLOR_DIAGNOSTICS on) Set(ANTARES_VERSION_TARGET "unknown") From b472829ae6f9cc88b7ee9cd114533c72caa876be Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Fri, 30 Aug 2024 09:40:12 +0200 Subject: [PATCH 113/127] Remove manually allocated memory (#2363) #2244 --- src/libs/antares/study/area/area.cpp | 12 +++--- src/libs/antares/study/area/list.cpp | 21 +++++----- .../antares/study/parts/hydro/container.h | 6 +-- .../antares/study/parts/load/container.h | 5 +-- .../antares/study/parts/solar/container.h | 5 +-- .../antares/study/parts/wind/container.h | 5 +-- .../antares/study/progression/progression.h | 16 +------ .../antares/study/progression/progression.hxx | 10 +---- .../antares/study/parts/hydro/container.cpp | 7 ---- .../antares/study/parts/load/container.cpp | 7 ---- .../antares/study/parts/solar/container.cpp | 6 --- .../antares/study/parts/wind/container.cpp | 6 --- src/libs/antares/study/study.cpp | 8 ++-- src/solver/ts-generator/generator.cpp | 4 +- src/solver/ts-generator/hydro.cpp | 4 +- .../solver/ts-generator/xcast/studydata.h | 4 +- src/solver/ts-generator/xcast/studydata.cpp | 42 +------------------ src/solver/ts-generator/xcast/xcast.cpp | 2 +- .../datagrid/renderer/area/hydroprepro.cpp | 2 +- 19 files changed, 42 insertions(+), 130 deletions(-) diff --git a/src/libs/antares/study/area/area.cpp b/src/libs/antares/study/area/area.cpp index 130c56a0d6..3bd4b91222 100644 --- a/src/libs/antares/study/area/area.cpp +++ b/src/libs/antares/study/area/area.cpp @@ -185,7 +185,7 @@ uint64_t Area::memoryUsage() const ret += wind.memoryUsage(); // Hydro - ret += PreproHydroMemoryUsage(hydro.prepro); + ret += PreproHydroMemoryUsage(hydro.prepro.get()); if (hydro.series) { ret += hydro.series->memoryUsage(); @@ -223,7 +223,7 @@ void Area::createMissingTimeSeries() { if (!hydro.series) { - hydro.series = new DataSeriesHydro(); + hydro.series = std::make_unique(); } } @@ -231,19 +231,19 @@ void Area::createMissingPrepros() { if (!load.prepro) { - load.prepro = new Data::Load::Prepro(); + load.prepro = std::make_unique(); } if (!solar.prepro) { - solar.prepro = new Data::Solar::Prepro(); + solar.prepro = std::make_unique(); } if (!wind.prepro) { - wind.prepro = new Data::Wind::Prepro(); + wind.prepro = std::make_unique(); } if (!hydro.prepro) { - hydro.prepro = new PreproHydro(); + hydro.prepro = std::make_unique(); } thermal.list.ensureDataPrepro(); } diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index 46a2e98c6f..cee20dc5d5 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -934,11 +934,10 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, ret = area.hydro.prepro->validate(area.id) && ret; } - auto* hydroSeries = area.hydro.series; if (!options.loadOnlyNeeded || !area.hydro.prepro) // Series { buffer.clear() << study.folderInput << SEP << "hydro" << SEP << "series"; - ret = hydroSeries->loadGenerationTS(area.id, buffer, studyVersion) && ret; + ret = area.hydro.series->loadGenerationTS(area.id, buffer, studyVersion) && ret; } if (studyVersion < StudyVersion(9, 1)) @@ -953,12 +952,12 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, else { buffer.clear() << study.folderInput << SEP << "hydro" << SEP << "series"; - ret = hydroSeries->LoadMaxPower(area.id, buffer) && ret; + ret = area.hydro.series->LoadMaxPower(area.id, buffer) && ret; } - hydroSeries->resizeTSinDeratedMode(study.parameters.derated, - studyVersion, - study.usedByTheSolver); + area.hydro.series->resizeTSinDeratedMode(study.parameters.derated, + studyVersion, + study.usedByTheSolver); } // Wind @@ -1320,7 +1319,7 @@ void AreaListEnsureDataLoadPrepro(AreaList* l) { if (!area.load.prepro) { - area.load.prepro = new Antares::Data::Load::Prepro(); + area.load.prepro = std::make_unique(); } }); } @@ -1335,7 +1334,7 @@ void AreaListEnsureDataSolarPrepro(AreaList* l) { if (!area.solar.prepro) { - area.solar.prepro = new Antares::Data::Solar::Prepro(); + area.solar.prepro = std::make_unique(); } }); } @@ -1350,7 +1349,7 @@ void AreaListEnsureDataWindPrepro(AreaList* l) { if (!area.wind.prepro) { - area.wind.prepro = new Antares::Data::Wind::Prepro(); + area.wind.prepro = std::make_unique(); } }); } @@ -1365,7 +1364,7 @@ void AreaListEnsureDataHydroTimeSeries(AreaList* l) { if (!area.hydro.series) { - area.hydro.series = new DataSeriesHydro(); + area.hydro.series = std::make_unique(); } }); } @@ -1380,7 +1379,7 @@ void AreaListEnsureDataHydroPrepro(AreaList* l) { if (!area.hydro.prepro) { - area.hydro.prepro = new PreproHydro(); + area.hydro.prepro = std::make_unique(); } }); } diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index 01c219b46b..1da5ab6023 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -138,7 +138,7 @@ class PartHydro */ PartHydro(); //! Destructor - ~PartHydro(); + ~PartHydro() = default; /*! ** \brief Reset internal data @@ -211,10 +211,10 @@ class PartHydro HydroAllocation allocation; //! Data for the pre-processor - PreproHydro* prepro; + std::unique_ptr prepro; //! Data for time-series - DataSeriesHydro* series; + std::unique_ptr series; // TODO : following time series could be hosted by the series data member above (of type // DataSeriesHydro), // which contains other time. diff --git a/src/libs/antares/study/include/antares/study/parts/load/container.h b/src/libs/antares/study/include/antares/study/parts/load/container.h index 083dc6df7d..ec7402034a 100644 --- a/src/libs/antares/study/include/antares/study/parts/load/container.h +++ b/src/libs/antares/study/include/antares/study/parts/load/container.h @@ -44,7 +44,7 @@ class Container final: private Yuni::NonCopyable */ Container(); //! Destructor - ~Container(); + ~Container() = default; //@} /*! @@ -67,9 +67,8 @@ class Container final: private Yuni::NonCopyable */ uint64_t memoryUsage() const; -public: //! Data for the pre-processor - Data::Load::Prepro* prepro; + std::unique_ptr prepro; TimeSeriesNumbers tsNumbers; diff --git a/src/libs/antares/study/include/antares/study/parts/solar/container.h b/src/libs/antares/study/include/antares/study/parts/solar/container.h index a4ea96d55b..390b72cd90 100644 --- a/src/libs/antares/study/include/antares/study/parts/solar/container.h +++ b/src/libs/antares/study/include/antares/study/parts/solar/container.h @@ -41,7 +41,7 @@ class Container */ Container(); //! Destructor - ~Container(); + ~Container() = default; //@} /*! @@ -64,9 +64,8 @@ class Container */ uint64_t memoryUsage() const; -public: //! Data for the pre-processor - Data::Solar::Prepro* prepro; + std::unique_ptr prepro; TimeSeriesNumbers tsNumbers; diff --git a/src/libs/antares/study/include/antares/study/parts/wind/container.h b/src/libs/antares/study/include/antares/study/parts/wind/container.h index 7e36522597..ba149068f5 100644 --- a/src/libs/antares/study/include/antares/study/parts/wind/container.h +++ b/src/libs/antares/study/include/antares/study/parts/wind/container.h @@ -41,7 +41,7 @@ class Container */ Container(); //! Destructor - ~Container(); + ~Container() = default; //@} /*! @@ -64,9 +64,8 @@ class Container */ uint64_t memoryUsage() const; -public: //! Data for the pre-processor - Data::Wind::Prepro* prepro; + std::unique_ptr prepro; TimeSeriesNumbers tsNumbers; diff --git a/src/libs/antares/study/include/antares/study/progression/progression.h b/src/libs/antares/study/include/antares/study/progression/progression.h index 5e013df957..19c2be8c00 100644 --- a/src/libs/antares/study/include/antares/study/progression/progression.h +++ b/src/libs/antares/study/include/antares/study/progression/progression.h @@ -169,15 +169,7 @@ class Progression final public: Meter(); - virtual ~Meter() - { - if (logsContainer) - { - delete[] logsContainer; - } - } - - void allocateLogsContainer(uint nb); + virtual ~Meter() = default; /*! ** \brief Prepare enough space to allow @n simultaneous tasks @@ -188,16 +180,12 @@ class Progression final virtual bool onInterval(uint) override; public: - // Progression::Part::Map parts; Part::ListRef inUse; std::mutex mutex; uint nbParallelYears; - // Because writing something to the logs might be expensive, we have to - // reduce the time spent in locking the mutex. - // We will use a temp vector of string to delay the writing into the logs - Yuni::CString<256, false>* logsContainer; + std::vector> logsContainer; }; // class Meter diff --git a/src/libs/antares/study/include/antares/study/progression/progression.hxx b/src/libs/antares/study/include/antares/study/progression/progression.hxx index 91430681dc..ad262b4ad5 100644 --- a/src/libs/antares/study/include/antares/study/progression/progression.hxx +++ b/src/libs/antares/study/include/antares/study/progression/progression.hxx @@ -26,16 +26,10 @@ namespace Antares namespace Solver { inline Progression::Meter::Meter(): - nbParallelYears(0), - logsContainer(nullptr) + nbParallelYears(0) { } -inline void Progression::Meter::allocateLogsContainer(uint nb) -{ - logsContainer = new Yuni::CString<256, false>[nb]; -} - inline void Progression::Meter::taskCount(uint n) { (void)n; @@ -49,7 +43,7 @@ inline void Progression::add(Section section, int nbTicks) inline void Progression::setNumberOfParallelYears(uint nb) { pProgressMeter.nbParallelYears = nb; - pProgressMeter.allocateLogsContainer(nb); + pProgressMeter.logsContainer.resize(nb); } inline Progression::Part& Progression::begin(uint year, Progression::Section section) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 92d13a586e..336595b95b 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -48,17 +48,10 @@ PartHydro::PartHydro(): leewayLowerBound(1.), leewayUpperBound(1.), pumpingEfficiency(1.), - prepro(nullptr), series(nullptr) { } -PartHydro::~PartHydro() -{ - delete prepro; - delete series; -} - void PartHydro::reset() { intraDailyModulation = 24; diff --git a/src/libs/antares/study/parts/load/container.cpp b/src/libs/antares/study/parts/load/container.cpp index b377eb0bf3..364b761985 100644 --- a/src/libs/antares/study/parts/load/container.cpp +++ b/src/libs/antares/study/parts/load/container.cpp @@ -31,17 +31,10 @@ using namespace Yuni; namespace Antares::Data::Load { Container::Container(): - prepro(nullptr), series(tsNumbers) { } -Container::~Container() -{ - delete prepro; - prepro = nullptr; -} - bool Container::forceReload(bool reload) const { bool ret = true; diff --git a/src/libs/antares/study/parts/solar/container.cpp b/src/libs/antares/study/parts/solar/container.cpp index 27e96d823c..08c85a0cc0 100644 --- a/src/libs/antares/study/parts/solar/container.cpp +++ b/src/libs/antares/study/parts/solar/container.cpp @@ -31,16 +31,10 @@ using namespace Yuni; namespace Antares::Data::Solar { Container::Container(): - prepro(nullptr), series(tsNumbers) { } -Container::~Container() -{ - delete prepro; -} - bool Container::forceReload(bool reload) const { bool ret = true; diff --git a/src/libs/antares/study/parts/wind/container.cpp b/src/libs/antares/study/parts/wind/container.cpp index eff23dff6f..64575b73ab 100644 --- a/src/libs/antares/study/parts/wind/container.cpp +++ b/src/libs/antares/study/parts/wind/container.cpp @@ -30,16 +30,10 @@ using namespace Yuni; namespace Antares::Data::Wind { Container::Container(): - prepro(nullptr), series(tsNumbers) { } -Container::~Container() -{ - delete prepro; -} - bool Container::forceReload(bool reload) const { bool ret = true; diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 67206dad70..29f22e9bf5 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -979,22 +979,22 @@ bool Study::clusterRename(Cluster* cluster, ClusterName newName) void Study::destroyAllLoadTSGeneratorData() { - areas.each([](Data::Area& area) { FreeAndNil(area.load.prepro); }); + areas.each([](Data::Area& area) { area.load.prepro.reset(); }); } void Study::destroyAllSolarTSGeneratorData() { - areas.each([](Data::Area& area) { FreeAndNil(area.solar.prepro); }); + areas.each([](Data::Area& area) { area.solar.prepro.reset(); }); } void Study::destroyAllHydroTSGeneratorData() { - areas.each([](Data::Area& area) { FreeAndNil(area.hydro.prepro); }); + areas.each([](Data::Area& area) { area.hydro.prepro.reset(); }); } void Study::destroyAllWindTSGeneratorData() { - areas.each([](Data::Area& area) { FreeAndNil(area.wind.prepro); }); + areas.each([](Data::Area& area) { area.wind.prepro.reset(); }); } void Study::ensureDataAreLoadedForAllBindingConstraints() diff --git a/src/solver/ts-generator/generator.cpp b/src/solver/ts-generator/generator.cpp index 3423a9a8ad..c682e412ab 100644 --- a/src/solver/ts-generator/generator.cpp +++ b/src/solver/ts-generator/generator.cpp @@ -50,9 +50,7 @@ void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params) // Hydro if (params.timeSeriesToGenerate & Data::timeSeriesHydro) { - Data::DataSeriesHydro* const series = area.hydro.series; - const uint nbSeries = params.nbTimeSeriesHydro; - series->resizeTS(nbSeries); + area.hydro.series->resizeTS(params.nbTimeSeriesHydro); } // Thermal diff --git a/src/solver/ts-generator/hydro.cpp b/src/solver/ts-generator/hydro.cpp index c5c2601bed..ccf61f9466 100644 --- a/src/solver/ts-generator/hydro.cpp +++ b/src/solver/ts-generator/hydro.cpp @@ -96,7 +96,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu for (uint i = 0; i < DIM; i++) { uint areaIndexI = i / MONTHS_PER_YEAR; - auto* prepro = study.areas.byIndex[areaIndexI]->hydro.prepro; + auto* prepro = study.areas.byIndex[areaIndexI]->hydro.prepro.get(); auto& corre = CORRE[i]; @@ -105,7 +105,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, Solver::IResu for (uint j = 0; j < DIM; j++) { uint areaIndexJ = j / MONTHS_PER_YEAR; - auto* preproJ = study.areas.byIndex[areaIndexJ]->hydro.prepro; + auto* preproJ = study.areas.byIndex[areaIndexJ]->hydro.prepro.get(); x = std::abs(((int)(i % MONTHS_PER_YEAR) - (int)(j % MONTHS_PER_YEAR)) / 2.); diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/xcast/studydata.h b/src/solver/ts-generator/include/antares/solver/ts-generator/xcast/studydata.h index 81c42be09a..1ff51a068d 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/xcast/studydata.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/xcast/studydata.h @@ -40,7 +40,7 @@ class StudyData final /*! ** \brief Destructor */ - ~StudyData(); + ~StudyData() = default; //@} /*! @@ -77,7 +77,7 @@ class StudyData final //! List of all areas (sub-set of the complete list) Data::Area::Vector localareas; //! Correlation coefficients for each month - const Matrix* correlation[12]; + std::array, 12> correlation; /*! ** \brief Correlation mode (monthly / annual) ** diff --git a/src/solver/ts-generator/xcast/studydata.cpp b/src/solver/ts-generator/xcast/studydata.cpp index c6bbd15b4e..9cf7e641ba 100644 --- a/src/solver/ts-generator/xcast/studydata.cpp +++ b/src/solver/ts-generator/xcast/studydata.cpp @@ -32,32 +32,6 @@ namespace Antares::TSGenerator::XCast StudyData::StudyData(): mode(Data::Correlation::modeNone) { - for (uint realmonth = 0; realmonth != 12; ++realmonth) - { - correlation[realmonth] = nullptr; - } -} - -StudyData::~StudyData() -{ - switch (mode) - { - case Data::Correlation::modeMonthly: - { - for (uint realmonth = 0; realmonth != 12; ++realmonth) - { - delete correlation[realmonth]; - } - break; - } - case Data::Correlation::modeAnnual: - { - delete correlation[0]; - break; - } - case Data::Correlation::modeNone: - break; - } } void StudyData::prepareMatrix(Matrix& m, const Matrix& source) const @@ -92,12 +66,9 @@ void StudyData::reloadDataFromAreaList(const Data::Correlation& originalCorrelat { case Data::Correlation::modeAnnual: { - auto* m = new Matrix(); - prepareMatrix(*m, originalCorrelation.annual); - for (uint realmonth = 0; realmonth != 12; ++realmonth) { - correlation[realmonth] = m; + prepareMatrix(correlation[realmonth], originalCorrelation.annual); } break; } @@ -105,9 +76,7 @@ void StudyData::reloadDataFromAreaList(const Data::Correlation& originalCorrelat { for (uint realmonth = 0; realmonth != 12; ++realmonth) { - auto* m = new Matrix(); - correlation[realmonth] = m; - prepareMatrix(*m, originalCorrelation.monthly[realmonth]); + prepareMatrix(correlation[realmonth], originalCorrelation.monthly[realmonth]); } break; } @@ -115,13 +84,6 @@ void StudyData::reloadDataFromAreaList(const Data::Correlation& originalCorrelat break; } } - else - { - for (uint realmonth = 0; realmonth != 12; ++realmonth) - { - correlation[realmonth] = nullptr; - } - } } } // namespace Antares::TSGenerator::XCast diff --git a/src/solver/ts-generator/xcast/xcast.cpp b/src/solver/ts-generator/xcast/xcast.cpp index b431e8d8ff..2c8a391a22 100644 --- a/src/solver/ts-generator/xcast/xcast.cpp +++ b/src/solver/ts-generator/xcast/xcast.cpp @@ -325,7 +325,7 @@ bool XCast::runWithPredicate(PredicateT& predicate, Progression::Task& progressi pNewMonth = true; - pCorrMonth = pData.correlation[realmonth]; + pCorrMonth = &pData.correlation[realmonth]; for (uint s = 0; s != processCount; ++s) { diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/hydroprepro.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/area/hydroprepro.cpp index f2d0ebbabf..115bc0b0d4 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/hydroprepro.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/hydroprepro.cpp @@ -141,7 +141,7 @@ void HydroPrepro::internalAreaChanged(Antares::Data::Area* area) if (area && !study) study = GetCurrentStudy(); - auto* pPreproHydro = (area) ? area->hydro.prepro : nullptr; + auto* pPreproHydro = (area) ? area->hydro.prepro.get() : nullptr; Renderer::ARendererArea::internalAreaChanged(area); if (pPreproHydro) { From 01960d041464b458f267ef8c0bbd94213bff8616 Mon Sep 17 00:00:00 2001 From: Peter Mitri Date: Mon, 2 Sep 2024 16:12:56 +0200 Subject: [PATCH 114/127] Add cucumber tests tool (#2347) --- .github/workflows/cucumber-tests/action.yml | 23 ++++++ .github/workflows/ubuntu.yml | 16 ++++- .github/workflows/windows-vcpkg.yml | 16 ++++- .gitmodules | 3 + src/tests/CMakeLists.txt | 3 +- src/tests/cucumber/CMakeLists.txt | 2 + .../cucumber/features/medium_tests.feature | 15 ++++ .../cucumber/features/short_tests.feature | 45 ++++++++++++ .../cucumber/features/steps/assertions.py | 4 ++ .../cucumber/features/steps/context_utils.py | 22 ++++++ .../cucumber/features/steps/output_utils.py | 37 ++++++++++ .../features/steps/simulator_utils.py | 47 +++++++++++++ src/tests/cucumber/features/steps/steps.py | 67 ++++++++++++++++++ .../features/steps/study_input_handler.py | 31 ++++++++ src/tests/cucumber/readme.md | 70 +++++++++++++++++++ src/tests/cucumber/requirements.txt | 2 + .../resources/Antares_Simulator_Tests_NR | 1 + src/tests/run-study-tests/readme.md | 2 +- 18 files changed, 401 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/cucumber-tests/action.yml create mode 100644 src/tests/cucumber/CMakeLists.txt create mode 100644 src/tests/cucumber/features/medium_tests.feature create mode 100644 src/tests/cucumber/features/short_tests.feature create mode 100644 src/tests/cucumber/features/steps/assertions.py create mode 100644 src/tests/cucumber/features/steps/context_utils.py create mode 100644 src/tests/cucumber/features/steps/output_utils.py create mode 100644 src/tests/cucumber/features/steps/simulator_utils.py create mode 100644 src/tests/cucumber/features/steps/steps.py create mode 100644 src/tests/cucumber/features/steps/study_input_handler.py create mode 100644 src/tests/cucumber/readme.md create mode 100644 src/tests/cucumber/requirements.txt create mode 160000 src/tests/resources/Antares_Simulator_Tests_NR diff --git a/.github/workflows/cucumber-tests/action.yml b/.github/workflows/cucumber-tests/action.yml new file mode 100644 index 0000000000..475d3310b3 --- /dev/null +++ b/.github/workflows/cucumber-tests/action.yml @@ -0,0 +1,23 @@ +name: "Run cucumber tests" +description: "Run cucumber tests" +inputs: + feature: + description: 'Feature file or folder to run (default runs all features in "features" folder)' + required: false + default: 'features' + tags: + description: 'Tags to run (default skips tests marked @flaky)' + required: false + default: '~@flaky' +runs: + using: "composite" + steps: + - name: Install Python requirements + shell: bash + run: python3 -m pip install -r src/tests/cucumber/requirements.txt + + - name: Run tests + shell: bash + run: | + cd src/tests/cucumber + behave --tags ${{ inputs.tags }} ${{ inputs.feature }} diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 01d2b3a10e..2c73097adb 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -142,10 +142,14 @@ jobs: run: | echo "SIMTEST=${{ fromJson(env.SIMTEST_JSON).version }}" >> $GITHUB_ENV - - name: Init submodule + - name: Init submodule Antares_Simulator_Tests run: | git submodule update --init --remote --recursive src/tests/resources/Antares_Simulator_Tests + - name: Init submodule Antares_Simulator_Tests_NR + run: | + git submodule update --init --remote --recursive src/tests/resources/Antares_Simulator_Tests_NR + - name: Run named mps tests if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests @@ -231,6 +235,11 @@ jobs: batch-name: short-tests os: ${{ env.os }} + - name: Run cucumber on short-tests + uses: ./.github/workflows/cucumber-tests + with: + feature: "features/short_tests.feature" + - name: Run mps tests if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests @@ -273,6 +282,11 @@ jobs: batch-name: medium-tests os: ${{ env.os }} + - name: Run cucumber on medium-tests + uses: ./.github/workflows/cucumber-tests + with: + feature: "features/medium_tests.feature" + - name: Run long-tests-1 if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index eadd043a69..e5cf8fea3f 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -110,10 +110,14 @@ jobs: - name: Install pip dependencies if necessary run: pip install -r src/tests/examples/requirements.txt - - name: Init submodule + - name: Init submodule Antares_Simulator_Tests run: | git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests + - name: Init submodule Antares_Simulator_Tests_NR + run: | + git submodule update --init --remote src/tests/resources/Antares_Simulator_Tests_NR + - name: Enable git longpaths run: git config --system core.longpaths true @@ -241,6 +245,11 @@ jobs: batch-name: short-tests os: ${{ env.os }} + - name: Run cucumber on short-tests + uses: ./.github/workflows/cucumber-tests + with: + feature: "features/short_tests.feature" + - name: Run mps tests if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests @@ -275,6 +284,11 @@ jobs: batch-name: medium-tests os: ${{ env.os }} + - name: Run cucumber on medium-tests + uses: ./.github/workflows/cucumber-tests + with: + feature: "features/medium_tests.feature" + - name: Run long-tests-1 if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests diff --git a/.gitmodules b/.gitmodules index 77fb4921c7..16639d0fb1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "vcpkg"] path = vcpkg url = https://github.com/microsoft/vcpkg.git +[submodule "src/tests/resources/Antares_Simulator_Tests_NR"] + path = src/tests/resources/Antares_Simulator_Tests_NR + url = https://github.com/AntaresSimulatorTeam/Antares_Simulator_Tests_NR.git diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index fcbc5cd6b2..2babe91fab 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -9,8 +9,7 @@ if (Boost_FOUND) set_target_properties(Boost::unit_test_framework PROPERTIES IMPORTED_GLOBAL TRUE) endif() - - +add_subdirectory(cucumber) # end to end test require boost 1.6.x because of boost::test_tools::tolerance, BOOST_TEST # old versions of Boost don't contain a '.', also ignore them diff --git a/src/tests/cucumber/CMakeLists.txt b/src/tests/cucumber/CMakeLists.txt new file mode 100644 index 0000000000..cf22c8415b --- /dev/null +++ b/src/tests/cucumber/CMakeLists.txt @@ -0,0 +1,2 @@ +file(GENERATE OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/conf.yaml CONTENT "antares-solver : $" + CONDITION $,${CMAKE_BUILD_TYPE}>) \ No newline at end of file diff --git a/src/tests/cucumber/features/medium_tests.feature b/src/tests/cucumber/features/medium_tests.feature new file mode 100644 index 0000000000..98e8a6fb26 --- /dev/null +++ b/src/tests/cucumber/features/medium_tests.feature @@ -0,0 +1,15 @@ +Feature: medium tests + + @fast @medium @incomplete + Scenario: 035 Mixed Expansion - Smart grid model 2 + Given the study path is "medium-tests/035 Mixed Expansion - Smart grid model 2" + When I run antares simulator + Then the simulation takes less than 15 seconds + And the simulation succeeds + And the expected value of the annual system cost is 3.725e+10 + And the minimum annual system cost is 3.642e+10 + And the maximum annual system cost is 4.011e+10 + And the annual system cost is + | EXP | STD | MIN | MAX | + | 3.725e+10 | 1.063e+09 | 3.642e+10 | 4.011e+10 | + # TODO : add steps when we understand what this test is supposed to test \ No newline at end of file diff --git a/src/tests/cucumber/features/short_tests.feature b/src/tests/cucumber/features/short_tests.feature new file mode 100644 index 0000000000..8a1d65d6c7 --- /dev/null +++ b/src/tests/cucumber/features/short_tests.feature @@ -0,0 +1,45 @@ +Feature: short tests + + @fast @short + Scenario: 001 One node - passive + Given the study path is "short-tests/001 One node - passive" + When I run antares simulator + Then the simulation takes less than 5 seconds + And the simulation succeeds + And the annual system cost is + | EXP | STD | MIN | MAX | + | 0 | 0 | 0 | 0 | + + @fast @short + Scenario: 002 Thermal fleet - Base + Given the study path is "short-tests/002 Thermal fleet - Base" + When I run antares simulator + Then the simulation takes less than 5 seconds + And the simulation succeeds + And the annual system cost is + | EXP | STD | MIN | MAX | + | 2.729e+7 | 0 | 2.729e+7 | 2.729e+7 | + And in area "AREA", during year 1, loss of load lasts 1 hours + And in area "AREA", unsupplied energy on "02 JAN 09:00" of year 1 is of 52 MW + + @fast @short + Scenario: 003 Thermal fleet - Must-run + Given the study path is "short-tests/003 Thermal fleet - Must-run" + When I run antares simulator + Then the simulation takes less than 5 seconds + And the simulation succeeds + And the annual system cost is + | EXP | STD | MIN | MAX | + | 2.751e+7 | 0 | 2.751e+7 | 2.751e+7 | + And in area "AREA", during year 1, loss of load lasts 1 hours + And in area "AREA", unsupplied energy on "02 JAN 09:00" of year 1 is of 52 MW + + @fast @short + Scenario: 021 Four areas - DC law + Given the study path is "short-tests/021 Four areas - DC law" + When I run antares simulator + Then the simulation takes less than 20 seconds + And the simulation succeeds + And the annual system cost is + | EXP | STD | MIN | MAX | + | 7.972e+10 | 2.258e+10 | 5.613e+10 | 1.082e+11 | \ No newline at end of file diff --git a/src/tests/cucumber/features/steps/assertions.py b/src/tests/cucumber/features/steps/assertions.py new file mode 100644 index 0000000000..dda7d0232c --- /dev/null +++ b/src/tests/cucumber/features/steps/assertions.py @@ -0,0 +1,4 @@ +# Custom assertions + +def assert_double_close(expected, actual, relative_tolerance): + assert abs((actual - expected) / max(1e-6, expected)) <= relative_tolerance \ No newline at end of file diff --git a/src/tests/cucumber/features/steps/context_utils.py b/src/tests/cucumber/features/steps/context_utils.py new file mode 100644 index 0000000000..5a7af9dfe3 --- /dev/null +++ b/src/tests/cucumber/features/steps/context_utils.py @@ -0,0 +1,22 @@ +# Manage cached output data in "context" object + +from output_utils import * + +def get_annual_system_cost(context): + if context.annual_system_cost is None: + context.annual_system_cost = parse_annual_system_cost(context.output_path) + return context.annual_system_cost + +def get_hourly_values_for_specific_hour(context, area : str, year : int, date : str): + df = get_hourly_values(context, area, year) + day, month, hour = date.split(" ") + return df.loc[(df['Unnamed: 2'] == int(day)) & (df['Unnamed: 3'] == month) & (df['Unnamed: 4'] == hour)] + +def get_hourly_values(context, area : str, year : int): + if context.hourly_values is None: + context.hourly_values = {} + if area not in context.hourly_values: + context.hourly_values[area] = {} + if year not in context.hourly_values[area]: + context.hourly_values[area][year] = parse_hourly_values(context.output_path, area, year) + return context.hourly_values[area][year] \ No newline at end of file diff --git a/src/tests/cucumber/features/steps/output_utils.py b/src/tests/cucumber/features/steps/output_utils.py new file mode 100644 index 0000000000..778a1d36b9 --- /dev/null +++ b/src/tests/cucumber/features/steps/output_utils.py @@ -0,0 +1,37 @@ +# Antares outputs parsing + +import os +import pandas +import configparser + +def parse_output_folder_from_logs(logs: bytes) -> str: + for line in logs.splitlines(): + if b'Output folder : ' in line: + return line.split(b'Output folder : ')[1].decode('ascii') + raise LookupError("Could not parse output folder in output logs") + + +def parse_annual_system_cost(output_path: str) -> dict: + file = open(os.path.join(output_path, "annualSystemCost.txt"), 'r') + keys = ["EXP", "STD", "MIN", "MAX"] + annual_system_cost = {} + for line in file.readlines(): + for key in keys: + if key in line: + annual_system_cost[key] = float(line.split(key + " : ")[1]) + return annual_system_cost + + +def parse_simu_time(output_path: str) -> float: + execution_info = configparser.ConfigParser() + execution_info.read(os.path.join(output_path, "execution_info.ini")) + return float(execution_info['durations_ms']['total']) / 1000 + + +def parse_hourly_values(output_path: str, area: str, year: int): + return read_csv(os.path.join(output_path, "economy", "mc-ind", f"{year:05d}", "areas", area, "values-hourly.txt")) + + +def read_csv(file_name): + ignore_rows = [0, 1, 2, 3, 5, 6] + return pandas.read_csv(file_name, skiprows=ignore_rows, sep='\t', low_memory=False) \ No newline at end of file diff --git a/src/tests/cucumber/features/steps/simulator_utils.py b/src/tests/cucumber/features/steps/simulator_utils.py new file mode 100644 index 0000000000..91da69a5ad --- /dev/null +++ b/src/tests/cucumber/features/steps/simulator_utils.py @@ -0,0 +1,47 @@ +# Methods to run Antares simulator + +import subprocess +import glob +import yaml +from pathlib import Path +from study_input_handler import study_input_handler +from output_utils import parse_output_folder_from_logs + + +def get_solver_path(): + with open("conf.yaml") as file: + content = yaml.full_load(file) + return content.get("antares-solver") + +SOLVER_PATH = get_solver_path() # we only need to run this once + + +def run_simulation(context): + activate_simu_outputs(context) # TODO : remove this and update studies instead + command = build_antares_solver_command(context) + print(f"Running command: {command}") + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) + out, err = process.communicate() + context.output_path = parse_output_folder_from_logs(out) + context.return_code = process.returncode + context.annual_system_cost = None + context.hourly_values = None + + +def activate_simu_outputs(context): + sih = study_input_handler(Path(context.study_path)) + sih.set_value(variable="synthesis", value="true", file_nick_name="general") + sih.set_value(variable="year-by-year", value="true", file_nick_name="general") + + +def build_antares_solver_command(context): + command = [SOLVER_PATH, "-i", str(context.study_path)] + if context.use_ortools: + command.append('--use-ortools') + command.append('--ortools-solver=' + context.ortools_solver) + if context.named_mps_problems: + command.append('--named-mps-problems') + if context.parallel: + command.append('--force-parallel=4') + return command + diff --git a/src/tests/cucumber/features/steps/steps.py b/src/tests/cucumber/features/steps/steps.py new file mode 100644 index 0000000000..f49bed8868 --- /dev/null +++ b/src/tests/cucumber/features/steps/steps.py @@ -0,0 +1,67 @@ +# Gherkins test steps definitions + +import os +from behave import * +from simulator_utils import * +from assertions import * +from context_utils import * + +@given('the study path is "{string}"') +def study_path_is(context, string): + context.study_path = os.path.join("..", "resources", "Antares_Simulator_Tests_NR" , string.replace("/", os.sep)) + +@when('I run antares simulator') +def run_antares(context): + context.use_ortools = True + context.ortools_solver = "sirius" + context.named_mps_problems = False + context.parallel = False + run_simulation(context) + +@then('the simulation succeeds') +def simu_success(context): + assert context.return_code == 0 + +@then('the simulation fails') +def simu_success(context): + assert context.return_code != 0 + +@then('the expected value of the annual system cost is {value}') +def check_annual_cost_expected(context, value): + assert_double_close(float(value), get_annual_system_cost(context)["EXP"], 0.001) + +@then('the minimum annual system cost is {value}') +def check_annual_cost_min(context, value): + assert_double_close(float(value), get_annual_system_cost(context)["MIN"], 0.001) + +@then('the maximum annual system cost is {value}') +def check_annual_cost_max(context, value): + assert_double_close(float(value), get_annual_system_cost(context)["MAX"], 0.001) + +@then('the annual system cost is') +def check_annual_cost(context): + for row in context.table: + assert_double_close(float(row["EXP"]), get_annual_system_cost(context)["EXP"], 0.001) + assert_double_close(float(row["STD"]), get_annual_system_cost(context)["STD"], 0.001) + assert_double_close(float(row["MIN"]), get_annual_system_cost(context)["MIN"], 0.001) + assert_double_close(float(row["MAX"]), get_annual_system_cost(context)["MAX"], 0.001) + +@then('the simulation takes less than {seconds} seconds') +def check_simu_time(context, seconds): + actual_simu_time = parse_simu_time(context.output_path) + assert actual_simu_time <= float(seconds) + +@then('in area "{area}", during year {year}, loss of load lasts {lold_hours} hours') +def check_lold_duration(context, area, year, lold_hours): + assert int(lold_hours) == get_hourly_values(context, area.lower(), int(year))["LOLD"].sum() + +@then('in area "{area}", unsupplied energy on "{date}" of year {year} is of {lold_value_mw} MW') +def check_lold_value(context, area, date, year, lold_value_mw): + actual_unsp_energ = get_hourly_values_for_specific_hour(context, area.lower(), int(year), date)["UNSP. ENRG"].sum() + assert_double_close(float(lold_value_mw), actual_unsp_energ, 0.001) + +def after_feature(context, feature): + # post-processing a test: clean up output files to avoid taking up all the disk space + if (context.output_path != None): + pathlib.Path.rmdir(context.output_path) + diff --git a/src/tests/cucumber/features/steps/study_input_handler.py b/src/tests/cucumber/features/steps/study_input_handler.py new file mode 100644 index 0000000000..90f27d7221 --- /dev/null +++ b/src/tests/cucumber/features/steps/study_input_handler.py @@ -0,0 +1,31 @@ +# Currently used to activate simulation outputs +# TODO : remove this and update parameters in simulation input files + +import os + + +class study_input_handler: + def __init__(self, study_root_directory): + self.study_root_dir = study_root_directory + self.name = os.path.basename(study_root_directory) + self.files_path = {} + self.files_path["desktop"] = self.study_root_dir / "Desktop.ini" + self.files_path["general"] = self.study_root_dir / "settings" / "generaldata.ini" + self.files_path["study"] = self.study_root_dir / "study.antares" + + def set_value(self, variable, value, file_nick_name): + # File path + file = self.files_path[file_nick_name] + # Content to print in file (tmp content) + content_out = [] + # Reading the file content (content in) + with open(file) as f: + # Searching variable and setting its value in a tmp content + for line in f: + if line.strip().startswith(variable): + content_out.append(variable + " = " + value + "\n") + else: + content_out.append(line) + # Erasing file content with the tmp content (content out) + with open(file, "w") as f: + f.writelines(content_out) diff --git a/src/tests/cucumber/readme.md b/src/tests/cucumber/readme.md new file mode 100644 index 0000000000..7ed6304d9f --- /dev/null +++ b/src/tests/cucumber/readme.md @@ -0,0 +1,70 @@ +# Antares Cucumber Tests + +This module contains non-regression functional tests for Antares written in the [Gherkin language](https://cucumber.io/docs/gherkin/). + +## Tests structure + +### Features, scenarios and tags +Features are supposed to represent big-picture features of the application. Every feature can have its own set of tests, +defined in a `.feature` file. Features are under the [features](./features) folder. +Every feature has multiple scenarios (every scenario represents a test case). +A scenario can be tagged in order to add it to a category, allowing us to run the tests on a filtered subset of the +scenarios later. The tags currently used in Antares are: +- @fast: tests that run fast +- @slow: tests that run slow +- @short: tests from the legacy "short-tests" batch +- @medium: tests from the legacy "medium-tests" batch +- @flaky: quarantine for flaky tests (i.e. sometimes pass, sometimes fail) that are to be skipped by the CI + +### Steps structure +Currently, tests are being migrated from the [legacy non-regression testing process](../run-study-tests). Thus, they +all begin by defining the path to the study to run and then call antares, through the following "steps": +~~~gherkin +Given the study path is "someFolder/someStudy" +When I run antares simulator +~~~ +The test will load the study, run antares-simulator, and hold on to its outputs. +Next, assertion "steps" can be added. For example, this next assertion checks that the simulation time (as measured by +antares-simulator and reported in its logs) is less than 15 seconds: +~~~gherkin +Then the simulation takes less than 15 seconds +~~~ +And the next step checks the expected value of the annual system cost: +~~~gherkin +Then the expected value of the annual system cost is 3.725e+10 +~~~ + +## Running the tests +### On your PC +First, you need to build antares-simulator. The tests will run the last antares-simulator executable built by the Cmake +projet. +Then, if needed, install the requirements by running: +~~~bash +pip install -r requirements.txt +~~~ +Then just run the following to execute the tests: +~~~bash +cd src/tests/cucumber +behave +~~~ +If you want to filter on a feature file and given tags, you can use: +~~~bash +behave --tags @some-tag features/some_feature.feature +~~~ +Refer to the [behave documentation](https://behave.readthedocs.io/en/latest/) for more information. + +### In the CI +Cucumber tests are run in the same way as the legacy tests in the Ubuntu & Windows CIs, except that they don't need the +reference values from the SimTest repository, since reference values are stored explicitly in the feature files. +Note that tests marked as "@flaky" are skipped by default. +Workflow file: [here](../../../.github/workflows/cucumber-tests/action.yml) + +## Under the hood +### Test files +Tests are hosted in the [Antares_Simulator_Tests_NR submodule](https://github.com/AntaresSimulatorTeam/Antares_Simulator_Tests_NR) +into the `src/test/resources` folder. Adding or modifying a study should thus change contents of this submodule. + +### Code-behind +All Gherkin steps have a code-behind definition called "step definitions". These are defined in the python files under +[features/steps](./features/steps) and use the [behave](https://behave.readthedocs.io/en/latest/) implementation of +cucumber. Feel free to add extra steps for your tests. diff --git a/src/tests/cucumber/requirements.txt b/src/tests/cucumber/requirements.txt new file mode 100644 index 0000000000..fd5e363e68 --- /dev/null +++ b/src/tests/cucumber/requirements.txt @@ -0,0 +1,2 @@ +behave +pyyaml \ No newline at end of file diff --git a/src/tests/resources/Antares_Simulator_Tests_NR b/src/tests/resources/Antares_Simulator_Tests_NR new file mode 160000 index 0000000000..9983782bc0 --- /dev/null +++ b/src/tests/resources/Antares_Simulator_Tests_NR @@ -0,0 +1 @@ +Subproject commit 9983782bc07c62f99854b1c7394d320830a40e14 diff --git a/src/tests/run-study-tests/readme.md b/src/tests/run-study-tests/readme.md index 5701d722d7..d2536dab64 100644 --- a/src/tests/run-study-tests/readme.md +++ b/src/tests/run-study-tests/readme.md @@ -212,7 +212,7 @@ The schema can be found at : **src/tests/run-study-tests/parse_studies/json_sche ```bash > cd src/tests/run-study-tests -> python -m pytest -m mps --solver-path=/path/to/the/Antares/solver/antares-x.y-solver.exe +> python -m pytest -m json --solver-path=/path/to/the/Antares/solver/antares-x.y-solver.exe ``` # TO DO From 420ccbacb88f6e4f3c5ead890b5ac713c88351d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Mon, 2 Sep 2024 19:39:08 +0200 Subject: [PATCH 115/127] Expression visitors : first implementation (#2290) TODO - [x] Add missing object types - [x] Add missing visitors - [x] Re-organize source files / split header/source, use the usual hierarchy with `include/XXX/`, define visitor / node types separately, etc. - [x] Deep copy for nodes (copy operator/constructor is currently deleted because of `std::unique_ptr`) - [x] `private` children for nodes ? - [x] Use a generic type to avoid defining ~14 object types manually ? - [x] Sonar issues - [x] Separate tests (move existing calls to test, add more tests) ~~The following causes a double free because of two `std::unique_ptr` holding the same memory address~~ ```cpp Parameter* p = new Parameter(1.); Add(p, p); ``` --------- Co-authored-by: Abdoulbari Zakir Co-authored-by: Abdoulbari Zaher <32519851+a-zakir@users.noreply.github.com> Co-authored-by: guilpier-code <62292552+guilpier-code@users.noreply.github.com> --- src/solver/CMakeLists.txt | 2 +- src/solver/expressions/CMakeLists.txt | 74 +++++ .../antares/solver/expressions/IName.h | 33 ++ .../antares/solver/expressions/Registry.hxx | 53 ++++ .../solver/expressions/nodes/AddNode.h | 37 +++ .../solver/expressions/nodes/BinaryNode.h | 64 ++++ .../solver/expressions/nodes/ComparisonNode.h | 35 +++ .../solver/expressions/nodes/ComponentNode.h | 89 ++++++ .../solver/expressions/nodes/DivisionNode.h | 40 +++ .../solver/expressions/nodes/EqualNode.h | 40 +++ .../expressions/nodes/ExpressionsNodes.h | 35 +++ .../nodes/GreaterThanOrEqualNode.h | 40 +++ .../antares/solver/expressions/nodes/Leaf.h | 63 ++++ .../expressions/nodes/LessThanOrEqualNode.h | 40 +++ .../solver/expressions/nodes/LiteralNode.h | 20 ++ .../expressions/nodes/MultiplicationNode.h | 40 +++ .../solver/expressions/nodes/NegationNode.h | 40 +++ .../antares/solver/expressions/nodes/Node.h | 34 ++ .../nodes/NodesForwardDeclaration.h | 41 +++ .../solver/expressions/nodes/ParameterNode.h | 22 ++ .../solver/expressions/nodes/PortFieldNode.h | 67 ++++ .../expressions/nodes/SubtractionNode.h | 40 +++ .../solver/expressions/nodes/UnaryNode.h | 52 ++++ .../solver/expressions/nodes/VariableNode.h | 23 ++ .../expressions/visitors/CloneVisitor.h | 60 ++++ .../expressions/visitors/CompareVisitor.h | 54 ++++ .../solver/expressions/visitors/EvalVisitor.h | 77 +++++ .../expressions/visitors/EvaluationContext.h | 61 ++++ .../solver/expressions/visitors/InvalidNode.h | 32 ++ .../expressions/visitors/LinearStatus.h | 178 +++++++++++ .../expressions/visitors/LinearityVisitor.h | 52 ++++ .../solver/expressions/visitors/NodeVisitor.h | 262 ++++++++++++++++ .../expressions/visitors/PrintVisitor.h | 51 +++ .../visitors/SubstitutionVisitor.h | 58 ++++ .../solver/expressions/visitors/TimeIndex.h | 57 ++++ .../expressions/visitors/TimeIndexVisitor.h | 61 ++++ src/solver/expressions/nodes/BinaryNode.cpp | 41 +++ .../expressions/nodes/ComponentNode.cpp | 40 +++ .../expressions/nodes/PortFieldNode.cpp | 40 +++ src/solver/expressions/nodes/UnaryNode.cpp | 34 ++ .../expressions/visitors/CloneVisitor.cpp | 115 +++++++ .../expressions/visitors/CompareVisitor.cpp | 137 ++++++++ .../expressions/visitors/EvalVisitor.cpp | 136 ++++++++ .../visitors/EvaluationContext.cpp | 21 ++ .../expressions/visitors/InvalidNode.cpp | 10 + .../expressions/visitors/LinearityVisitor.cpp | 104 +++++++ .../expressions/visitors/PrintVisitor.cpp | 104 +++++++ .../visitors/SubstitutionVisitor.cpp | 59 ++++ .../expressions/visitors/TimeIndexVisitor.cpp | 108 +++++++ src/tests/src/solver/CMakeLists.txt | 2 +- .../src/solver/expressions/CMakeLists.txt | 28 ++ .../solver/expressions/test_CloneVisitor.cpp | 69 ++++ .../expressions/test_CompareVisitor.cpp | 133 ++++++++ .../solver/expressions/test_DeepWideTrees.cpp | 87 ++++++ .../solver/expressions/test_LinearVisitor.cpp | 293 +++++++++++++++++ .../expressions/test_PrintAndEvalNodes.cpp | 294 ++++++++++++++++++ .../expressions/test_SubstitutionVisitor.cpp | 89 ++++++ .../expressions/test_TimeIndexVisitor.cpp | 200 ++++++++++++ .../src/solver/expressions/test_main.cpp | 25 ++ .../src/solver/expressions/test_nodes.cpp | 93 ++++++ 60 files changed, 4287 insertions(+), 2 deletions(-) create mode 100644 src/solver/expressions/CMakeLists.txt create mode 100644 src/solver/expressions/include/antares/solver/expressions/IName.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/Registry.hxx create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/AddNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/BinaryNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/ComparisonNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/ComponentNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/DivisionNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/EqualNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/ExpressionsNodes.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/GreaterThanOrEqualNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/Leaf.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/LessThanOrEqualNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/LiteralNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/MultiplicationNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/NegationNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/Node.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/NodesForwardDeclaration.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/ParameterNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/PortFieldNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/SubtractionNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/UnaryNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/nodes/VariableNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/CloneVisitor.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/CompareVisitor.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/EvalVisitor.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/EvaluationContext.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/InvalidNode.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/LinearStatus.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/LinearityVisitor.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/NodeVisitor.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/PrintVisitor.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/SubstitutionVisitor.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndex.h create mode 100644 src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndexVisitor.h create mode 100644 src/solver/expressions/nodes/BinaryNode.cpp create mode 100644 src/solver/expressions/nodes/ComponentNode.cpp create mode 100644 src/solver/expressions/nodes/PortFieldNode.cpp create mode 100644 src/solver/expressions/nodes/UnaryNode.cpp create mode 100644 src/solver/expressions/visitors/CloneVisitor.cpp create mode 100644 src/solver/expressions/visitors/CompareVisitor.cpp create mode 100644 src/solver/expressions/visitors/EvalVisitor.cpp create mode 100644 src/solver/expressions/visitors/EvaluationContext.cpp create mode 100644 src/solver/expressions/visitors/InvalidNode.cpp create mode 100644 src/solver/expressions/visitors/LinearityVisitor.cpp create mode 100644 src/solver/expressions/visitors/PrintVisitor.cpp create mode 100644 src/solver/expressions/visitors/SubstitutionVisitor.cpp create mode 100644 src/solver/expressions/visitors/TimeIndexVisitor.cpp create mode 100644 src/tests/src/solver/expressions/CMakeLists.txt create mode 100644 src/tests/src/solver/expressions/test_CloneVisitor.cpp create mode 100644 src/tests/src/solver/expressions/test_CompareVisitor.cpp create mode 100644 src/tests/src/solver/expressions/test_DeepWideTrees.cpp create mode 100644 src/tests/src/solver/expressions/test_LinearVisitor.cpp create mode 100644 src/tests/src/solver/expressions/test_PrintAndEvalNodes.cpp create mode 100644 src/tests/src/solver/expressions/test_SubstitutionVisitor.cpp create mode 100644 src/tests/src/solver/expressions/test_TimeIndexVisitor.cpp create mode 100644 src/tests/src/solver/expressions/test_main.cpp create mode 100644 src/tests/src/solver/expressions/test_nodes.cpp diff --git a/src/solver/CMakeLists.txt b/src/solver/CMakeLists.txt index 13ab3bfa6c..632affa433 100644 --- a/src/solver/CMakeLists.txt +++ b/src/solver/CMakeLists.txt @@ -19,7 +19,7 @@ add_subdirectory(simulation) add_subdirectory(ts-generator) add_subdirectory(utils) add_subdirectory(variable) - +add_subdirectory(expressions) # # Resource file for Windows # diff --git a/src/solver/expressions/CMakeLists.txt b/src/solver/expressions/CMakeLists.txt new file mode 100644 index 0000000000..be6ad0c83e --- /dev/null +++ b/src/solver/expressions/CMakeLists.txt @@ -0,0 +1,74 @@ +project(Expressions) + + +set(SRC_Expressions + nodes/PortFieldNode.cpp + nodes/ComponentNode.cpp + nodes/BinaryNode.cpp + nodes/UnaryNode.cpp + + visitors/CloneVisitor.cpp + visitors/CompareVisitor.cpp + visitors/EvalVisitor.cpp + visitors/EvaluationContext.cpp + visitors/LinearityVisitor.cpp + visitors/TimeIndexVisitor.cpp + visitors/PrintVisitor.cpp + visitors/SubstitutionVisitor.cpp + visitors/InvalidNode.cpp + + include/antares/solver/expressions/nodes/AddNode.h + include/antares/solver/expressions/nodes/BinaryNode.h + include/antares/solver/expressions/nodes/ComparisonNode.h + include/antares/solver/expressions/nodes/ComponentNode.h + include/antares/solver/expressions/nodes/DivisionNode.h + include/antares/solver/expressions/nodes/EqualNode.h + include/antares/solver/expressions/nodes/ExpressionsNodes.h + include/antares/solver/expressions/nodes/GreaterThanOrEqualNode.h + include/antares/solver/expressions/nodes/Leaf.h + include/antares/solver/expressions/nodes/LessThanOrEqualNode.h + include/antares/solver/expressions/nodes/LiteralNode.h + include/antares/solver/expressions/nodes/MultiplicationNode.h + include/antares/solver/expressions/nodes/NegationNode.h + include/antares/solver/expressions/nodes/Node.h + include/antares/solver/expressions/nodes/NodesForwardDeclaration.h + include/antares/solver/expressions/nodes/ParameterNode.h + include/antares/solver/expressions/nodes/PortFieldNode.h + include/antares/solver/expressions/nodes/SubtractionNode.h + include/antares/solver/expressions/nodes/UnaryNode.h + include/antares/solver/expressions/nodes/VariableNode.h + + include/antares/solver/expressions/visitors/CloneVisitor.h + include/antares/solver/expressions/visitors/CompareVisitor.h + include/antares/solver/expressions/visitors/EvalVisitor.h + include/antares/solver/expressions/visitors/EvaluationContext.h + include/antares/solver/expressions/visitors/LinearStatus.h + include/antares/solver/expressions/visitors/LinearityVisitor.h + include/antares/solver/expressions/visitors/NodeVisitor.h + include/antares/solver/expressions/visitors/PrintVisitor.h + include/antares/solver/expressions/visitors/TimeIndexVisitor.h + include/antares/solver/expressions/visitors/TimeIndex.h + include/antares/solver/expressions/visitors/SubstitutionVisitor.h + include/antares/solver/expressions/visitors/InvalidNode.h + + include/antares/solver/expressions/Registry.hxx + include/antares/solver/expressions/IName.h +) + + +source_group("expressions" FILES ${SRC_Expressions}) +add_library(antares-solver-expressions + ${SRC_Expressions}) + +target_include_directories(antares-solver-expressions + PUBLIC + $ +) +target_link_libraries(antares-solver-expressions + PUBLIC + Antares::logs +) +install(DIRECTORY include/antares + DESTINATION "include" +) + diff --git a/src/solver/expressions/include/antares/solver/expressions/IName.h b/src/solver/expressions/include/antares/solver/expressions/IName.h new file mode 100644 index 0000000000..237fe6d567 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/IName.h @@ -0,0 +1,33 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once +#include + +namespace Antares::Solver +{ +class IName +{ +public: + virtual ~IName() = default; + virtual std::string name() const = 0; + bool operator==(const IName& other) const = default; +}; +} // namespace Antares::Solver diff --git a/src/solver/expressions/include/antares/solver/expressions/Registry.hxx b/src/solver/expressions/include/antares/solver/expressions/Registry.hxx new file mode 100644 index 0000000000..2ccc9ff8fd --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/Registry.hxx @@ -0,0 +1,53 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include +#include +#include +#include + +namespace Antares::Solver +{ +// Template class to manage the memory allocation and registry for a base class +template +class Registry +{ +public: + // Method to create a new derived class object and add it to the registry + template + requires std::derived_from + Derived* create(Args&&... args) + { + auto created = std::make_unique(std::forward(args)...); + + std::lock_guard lock(mutex_); + registry_.push_back(std::move(created)); + return dynamic_cast( + registry_.back().get()); // Return the pointer to the newly created object + } + +private: + std::vector> + registry_; // Registry to manage dynamically allocated objects + std::mutex mutex_; +}; +} // namespace Antares::Solver diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/AddNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/AddNode.h new file mode 100644 index 0000000000..ea0e251607 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/AddNode.h @@ -0,0 +1,37 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +class AddNode: public BinaryNode +{ +public: + using BinaryNode::BinaryNode; + + std::string name() const override + { + return "AddNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/BinaryNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/BinaryNode.h new file mode 100644 index 0000000000..1ce7e05bd1 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/BinaryNode.h @@ -0,0 +1,64 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +class BinaryNode: public Node +{ +public: + /** + * @brief Constructs a binary node with the specified left and right operands. + * + * @param left The left operand. + * @param right The right operand. + * @note BinaryNode(n1, n2) and BinaryNode(n2, n1) are not equivalent. + */ + explicit BinaryNode(Node* left, Node* right); + + /** + * @brief Retrieves a pointer to the left operand. + * + * @return A pointer to the left operand. + */ + Node* left() const; + + /** + * @brief Retrieves a pointer to the right operand. + * + * @return A pointer to the right operand. + */ + Node* right() const; + +private: + /** + * @brief A pointer to the left operand. + */ + Node* leftOperand_ = nullptr; + + /** + * @brief A pointer to the right operand. + */ + Node* rightOperand_ = nullptr; +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/ComparisonNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/ComparisonNode.h new file mode 100644 index 0000000000..7fd6ac9cb2 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/ComparisonNode.h @@ -0,0 +1,35 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a comparison node in a syntax tree. + */ +class ComparisonNode: public BinaryNode +{ +public: + using BinaryNode::BinaryNode; +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/ComponentNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/ComponentNode.h new file mode 100644 index 0000000000..50e25439a8 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/ComponentNode.h @@ -0,0 +1,89 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once +#include + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a component node in a syntax tree. + */ +class ComponentNode: public Node +{ +public: + /** + * @brief Constructs a component node with the specified ID and name. + * + * @param component_id The component ID. + * @param component_name The component name. + */ + explicit ComponentNode(const std::string& component_id, const std::string& component_name); + /** + * @brief Retrieves the component ID. + * + * @return The component ID. + */ + const std::string& getComponentId() const; + + /** + * @brief Retrieves the component name. + * + * @return The component name. + */ + const std::string& getComponentName() const; + + bool operator==(const ComponentNode& other) const = default; + +private: + std::string component_id_; + std::string component_name_; +}; + +/** + * @brief Represents a component variable node in a syntax tree. + */ +class ComponentVariableNode: public ComponentNode +{ +public: + using ComponentNode::ComponentNode; + + std::string name() const override + { + return "ComponentVariableNode"; + } +}; + +/** + * @brief Represents a component parameter node in a syntax tree. + */ +class ComponentParameterNode: public ComponentNode +{ +public: + using ComponentNode::ComponentNode; + + std::string name() const override + { + return "ComponentParameterNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/DivisionNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/DivisionNode.h new file mode 100644 index 0000000000..989324756e --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/DivisionNode.h @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a division node in a syntax tree. + */ +class DivisionNode: public BinaryNode +{ +public: + using BinaryNode::BinaryNode; + + std::string name() const override + { + return "DivisionNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/EqualNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/EqualNode.h new file mode 100644 index 0000000000..75eb2e43a5 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/EqualNode.h @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents an equality comparison node in a syntax tree. + */ +class EqualNode: public ComparisonNode +{ +public: + using ComparisonNode::ComparisonNode; + + std::string name() const override + { + return "EqualNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/ExpressionsNodes.h b/src/solver/expressions/include/antares/solver/expressions/nodes/ExpressionsNodes.h new file mode 100644 index 0000000000..2ecf1fe001 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/ExpressionsNodes.h @@ -0,0 +1,35 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/GreaterThanOrEqualNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/GreaterThanOrEqualNode.h new file mode 100644 index 0000000000..bee2c16413 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/GreaterThanOrEqualNode.h @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a greater than or equal comparison node in a syntax tree. + */ +class GreaterThanOrEqualNode: public ComparisonNode +{ +public: + using ComparisonNode::ComparisonNode; + + std::string name() const override + { + return "GreaterThanOrEqualNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/Leaf.h b/src/solver/expressions/include/antares/solver/expressions/nodes/Leaf.h new file mode 100644 index 0000000000..c971be8fb4 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/Leaf.h @@ -0,0 +1,63 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a leaf node in a syntax tree. + * + * @tparam T The type of the value stored in the leaf node. + */ +template +class Leaf: public Node +{ +public: + /** + * @brief Constructs a leaf node with the specified value. + * + * @param value The value to store in the leaf node. + */ + explicit Leaf(const T& value): + value_(value) + { + } + + /** + * @brief Retrieves the value stored in the leaf node. + * + * @return The value stored in the leaf node. + */ + T value() const + { + return value_; + } + +private: + /** + * @brief The value stored in the leaf node. + */ + T value_; +}; + +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/LessThanOrEqualNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/LessThanOrEqualNode.h new file mode 100644 index 0000000000..25cc479529 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/LessThanOrEqualNode.h @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a less than or equal comparison node in a syntax tree. + */ +class LessThanOrEqualNode: public ComparisonNode +{ +public: + using ComparisonNode::ComparisonNode; + + std::string name() const override + { + return "LessThanOrEqualNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/LiteralNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/LiteralNode.h new file mode 100644 index 0000000000..f875b754b9 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/LiteralNode.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a literal node in a syntax tree, storing a double value. + */ +class LiteralNode: public Leaf +{ +public: + using Leaf::Leaf; + + std::string name() const override + { + return "LiteralNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/MultiplicationNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/MultiplicationNode.h new file mode 100644 index 0000000000..4b6e877dd0 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/MultiplicationNode.h @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a multiplication node in a syntax tree. + */ +class MultiplicationNode: public BinaryNode +{ +public: + using BinaryNode::BinaryNode; + + std::string name() const override + { + return "MultiplicationNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/NegationNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/NegationNode.h new file mode 100644 index 0000000000..d8eec04a24 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/NegationNode.h @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a negation node in a syntax tree. + */ +class NegationNode final: public UnaryNode +{ +public: + using UnaryNode::UnaryNode; + + std::string name() const override + { + return "NegationNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/Node.h b/src/solver/expressions/include/antares/solver/expressions/nodes/Node.h new file mode 100644 index 0000000000..410a1cd7e6 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/Node.h @@ -0,0 +1,34 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Base class for nodes in a syntax tree. + */ +class Node: public IName +{ +public: + virtual ~Node() = default; +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/NodesForwardDeclaration.h b/src/solver/expressions/include/antares/solver/expressions/nodes/NodesForwardDeclaration.h new file mode 100644 index 0000000000..bc1b44b2a1 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/NodesForwardDeclaration.h @@ -0,0 +1,41 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +namespace Antares::Solver::Nodes +{ +class Node; +class AddNode; +class SubtractionNode; +class MultiplicationNode; +class DivisionNode; +class EqualNode; +class LessThanOrEqualNode; +class GreaterThanOrEqualNode; +class NegationNode; +class LiteralNode; +class ComponentNode; +class ComponentVariableNode; +class ComponentParameterNode; +class ParameterNode; +class VariableNode; +class PortFieldNode; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/ParameterNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/ParameterNode.h new file mode 100644 index 0000000000..45f97bccf8 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/ParameterNode.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a parameter node in a syntax tree, storing a string value. + */ +class ParameterNode final: public Leaf +{ +public: + using Leaf::Leaf; + + std::string name() const override + { + return "ParameterNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/PortFieldNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/PortFieldNode.h new file mode 100644 index 0000000000..32895d3be5 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/PortFieldNode.h @@ -0,0 +1,67 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once +#include + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a port field node in a syntax tree. + */ +class PortFieldNode: public Node +{ +public: + /** + * @brief Constructs a port field node with the specified port and field names. + * + * @param port_name The port name. + * @param field_name The field name. + */ + explicit PortFieldNode(const std::string& port_name, const std::string& field_name); + + /** + * @brief Retrieves the port name. + * + * @return The port name. + */ + const std::string& getPortName() const; + + /** + * @brief Retrieves the field name. + * + * @return The field name. + */ + const std::string& getFieldName() const; + + bool operator==(const PortFieldNode& other) const = default; + + std::string name() const override + { + return "PortFieldNode"; + } + +private: + std::string port_name_; + std::string field_name_; +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/SubtractionNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/SubtractionNode.h new file mode 100644 index 0000000000..822bf2620c --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/SubtractionNode.h @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a subtraction node in a syntax tree. + */ +class SubtractionNode: public BinaryNode +{ +public: + using BinaryNode::BinaryNode; + + std::string name() const override + { + return "SubtractionNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/UnaryNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/UnaryNode.h new file mode 100644 index 0000000000..c02969554e --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/UnaryNode.h @@ -0,0 +1,52 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a unary node in a syntax tree. + */ +class UnaryNode: public Node +{ +public: + /** + * @brief Constructs a unary node with the specified child. + * + * @param child The child node. + */ + explicit UnaryNode(Node* child); + /** + * @brief Retrieves a pointer to the child node. + * + * @return A pointer to the child node. + */ + Node* child() const; + +private: + /** + * @brief A pointer to the child node. + */ + Node* child_ = nullptr; +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/nodes/VariableNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/VariableNode.h new file mode 100644 index 0000000000..cc29ad9016 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/VariableNode.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include + +namespace Antares::Solver::Nodes +{ + +/** + * @brief Represents a variable node in a syntax tree, storing a string value. + */ +class VariableNode final: public Leaf +{ +public: + using Leaf::Leaf; + + std::string name() const override + { + return "VariableNode"; + } +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/CloneVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/CloneVisitor.h new file mode 100644 index 0000000000..caafab8df0 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/CloneVisitor.h @@ -0,0 +1,60 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include +#include "antares/solver/expressions/visitors/NodeVisitor.h" + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents a visitor for cloning nodes in a syntax tree. + */ +class CloneVisitor: public NodeVisitor +{ +public: + /** + * @brief Constructs a clone visitor with the specified registry for creating new nodes. + * + * @param registry The registry used for creating new nodes. + */ + explicit CloneVisitor(Registry& registry); + std::string name() const override; + + Nodes::Node* visit(const Nodes::AddNode* node) override; + Nodes::Node* visit(const Nodes::SubtractionNode* node) override; + Nodes::Node* visit(const Nodes::MultiplicationNode* node) override; + Nodes::Node* visit(const Nodes::DivisionNode* node) override; + Nodes::Node* visit(const Nodes::EqualNode* node) override; + Nodes::Node* visit(const Nodes::LessThanOrEqualNode* node) override; + Nodes::Node* visit(const Nodes::GreaterThanOrEqualNode* node) override; + Nodes::Node* visit(const Nodes::NegationNode* node) override; + Nodes::Node* visit(const Nodes::VariableNode* node) override; + Nodes::Node* visit(const Nodes::ParameterNode* node) override; + Nodes::Node* visit(const Nodes::LiteralNode* node) override; + Nodes::Node* visit(const Nodes::PortFieldNode* node) override; + Nodes::Node* visit(const Nodes::ComponentVariableNode* node) override; + Nodes::Node* visit(const Nodes::ComponentParameterNode* node) override; + +private: + Registry& registry_; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/CompareVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/CompareVisitor.h new file mode 100644 index 0000000000..579eb8c2ed --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/CompareVisitor.h @@ -0,0 +1,54 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include +#include "antares/solver/expressions/visitors/NodeVisitor.h" + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents a visitor for comparing nodes in a syntax tree. + */ +class CompareVisitor: public NodeVisitor +{ +public: + CompareVisitor() = default; + std::string name() const override; + + bool visit(const Nodes::AddNode* add, const Nodes::Node* other) override; + bool visit(const Nodes::SubtractionNode* add, const Nodes::Node* other) override; + bool visit(const Nodes::MultiplicationNode* add, const Nodes::Node* other) override; + bool visit(const Nodes::DivisionNode* add, const Nodes::Node* other) override; + bool visit(const Nodes::EqualNode* add, const Nodes::Node* other) override; + bool visit(const Nodes::LessThanOrEqualNode* add, const Nodes::Node* other) override; + bool visit(const Nodes::GreaterThanOrEqualNode* add, const Nodes::Node* other) override; + bool visit(const Nodes::NegationNode* neg, const Nodes::Node* other) override; + bool visit(const Nodes::VariableNode* param, const Nodes::Node* other) override; + bool visit(const Nodes::ParameterNode* param, const Nodes::Node* other) override; + bool visit(const Nodes::LiteralNode* param, const Nodes::Node* other) override; + bool visit(const Nodes::PortFieldNode* port_field_node, const Nodes::Node* other) override; + bool visit(const Nodes::ComponentVariableNode* component_node, + const Nodes::Node* other) override; + bool visit(const Nodes::ComponentParameterNode* component_node, + const Nodes::Node* other) override; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/EvalVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/EvalVisitor.h new file mode 100644 index 0000000000..0ec4ae6612 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/EvalVisitor.h @@ -0,0 +1,77 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include +#include "antares/solver/expressions/visitors/NodeVisitor.h" + +namespace Antares::Solver::Visitors +{ + +class EvalVisitorDivisionException: public std::runtime_error +{ +public: + EvalVisitorDivisionException(double left, double right, const std::string& message); +}; + +class EvalVisitorNotImplemented: public std::invalid_argument +{ +public: + EvalVisitorNotImplemented(const std::string& visitor, const std::string& node); +}; + +/** + * @brief Represents a visitor for evaluating expressions within a given context. + */ +class EvalVisitor: public NodeVisitor +{ +public: + /** + * @brief Default constructor, creates an evaluation visitor with no context. + */ + EvalVisitor() = default; // No context (variables / parameters) + + /** + * @brief Constructs an evaluation visitor with the specified context. + * + * @param context The evaluation context. + */ + explicit EvalVisitor(EvaluationContext context); + std::string name() const override; + +private: + const EvaluationContext context_; + double visit(const Nodes::AddNode* node) override; + double visit(const Nodes::SubtractionNode* node) override; + double visit(const Nodes::MultiplicationNode* node) override; + double visit(const Nodes::DivisionNode* node) override; + double visit(const Nodes::EqualNode* node) override; + double visit(const Nodes::LessThanOrEqualNode* node) override; + double visit(const Nodes::GreaterThanOrEqualNode* node) override; + double visit(const Nodes::NegationNode* node) override; + double visit(const Nodes::VariableNode* node) override; + double visit(const Nodes::ParameterNode* node) override; + double visit(const Nodes::LiteralNode* node) override; + double visit(const Nodes::PortFieldNode* node) override; + double visit(const Nodes::ComponentVariableNode* node) override; + double visit(const Nodes::ComponentParameterNode* node) override; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/EvaluationContext.h b/src/solver/expressions/include/antares/solver/expressions/visitors/EvaluationContext.h new file mode 100644 index 0000000000..7e985eb248 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/EvaluationContext.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents the context for evaluating expressions. + * + * Stores and provides access to parameter and variable values. + */ +class EvaluationContext +{ +public: + /** + * @brief Default constructor, creates an evaluation context without parameter and variable + * values. + */ + EvaluationContext() = default; + /** + * @brief Constructs an evaluation context with the specified parameter and variable + * values. + * + * @param parameters parameter values. + * @param variables variable values. + */ + explicit EvaluationContext(std::map parameters, + std::map variables); + + /** + * @brief Retrieves the value of a variable. + * + * @param name The name of the variable. + * @return The value of the variable. + * @throws std::out_of_range If the variable is not found. + */ + double getVariableValue(const std::string& key) const; + + /** + * @brief Retrieves the value of a parameter. + * + * @param name The name of the parameter. + * @return The value of the parameter. + * @throws std::out_of_range If the parameter is not found. + */ + double getParameterValue(const std::string& key) const; + +private: + /** + * @brief A map storing parameter values. + */ + std::map parameters_; + + /** + * @brief A map storing variable values. + */ + std::map variables_; +}; + +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/InvalidNode.h b/src/solver/expressions/include/antares/solver/expressions/visitors/InvalidNode.h new file mode 100644 index 0000000000..9edbca3203 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/InvalidNode.h @@ -0,0 +1,32 @@ + +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once +#include + +namespace Antares::Solver::Visitors +{ +class InvalidNode: public std::invalid_argument +{ +public: + explicit InvalidNode(const std::string& node_name = ""); +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/LinearStatus.h b/src/solver/expressions/include/antares/solver/expressions/visitors/LinearStatus.h new file mode 100644 index 0000000000..590bedbcf9 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/LinearStatus.h @@ -0,0 +1,178 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents the linearity of a node. + */ +enum class LinearStatus : char +{ + CONSTANT = 0, + LINEAR = 1, + NON_LINEAR = 2 +}; + +/** + * @brief Combines two LinearStatus values into a single character. + * + * @param a The first LinearStatus value. + * @param b The second LinearStatus value. + * + * @return The combined LinearStatus value as a character. + */ +constexpr char pair(LinearStatus a, LinearStatus b) +{ + return static_cast(a) << 4 | static_cast(b); +} + +/** + * @brief Multiplies two LinearStatus values. + * + * @param a The first LinearStatus value. + * @param b The second LinearStatus value. + * + * @return The resulting LinearStatus value based on the multiplication of a and b. + */ +constexpr LinearStatus operator*(LinearStatus a, LinearStatus b) +{ + switch (pair(a, b)) + { + case pair(LinearStatus::CONSTANT, LinearStatus::CONSTANT): + return LinearStatus::CONSTANT; + case pair(LinearStatus::CONSTANT, LinearStatus::LINEAR): + return LinearStatus::LINEAR; + case pair(LinearStatus::CONSTANT, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + case pair(LinearStatus::LINEAR, LinearStatus::CONSTANT): + return LinearStatus::LINEAR; + case pair(LinearStatus::LINEAR, LinearStatus::LINEAR): + case pair(LinearStatus::LINEAR, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + case pair(LinearStatus::NON_LINEAR, LinearStatus::CONSTANT): + case pair(LinearStatus::NON_LINEAR, LinearStatus::LINEAR): + case pair(LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + default: + return LinearStatus::NON_LINEAR; + } +} + +/** + * @brief Divides two LinearStatus values. + * + * @param a The first LinearStatus value. + * @param b The second LinearStatus value. + * + * @return The resulting LinearStatus value based on the division of a and b. + */ +constexpr LinearStatus operator/(LinearStatus a, LinearStatus b) +{ + switch (pair(a, b)) + { + case pair(LinearStatus::CONSTANT, LinearStatus::CONSTANT): + return LinearStatus::CONSTANT; + case pair(LinearStatus::CONSTANT, LinearStatus::LINEAR): + return LinearStatus::NON_LINEAR; + case pair(LinearStatus::CONSTANT, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + case pair(LinearStatus::LINEAR, LinearStatus::CONSTANT): + return LinearStatus::LINEAR; + case pair(LinearStatus::LINEAR, LinearStatus::LINEAR): + case pair(LinearStatus::LINEAR, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + case pair(LinearStatus::NON_LINEAR, LinearStatus::CONSTANT): + case pair(LinearStatus::NON_LINEAR, LinearStatus::LINEAR): + case pair(LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + default: + return LinearStatus::NON_LINEAR; + } +} + +/** + * @brief Add two LinearStatus values. + * + * @param a The first LinearStatus value. + * @param b The second LinearStatus value. + * + * @return The resulting LinearStatus value based on the addition of a and b. + */ +constexpr LinearStatus operator+(LinearStatus a, LinearStatus b) +{ + switch (pair(a, b)) + { + case pair(LinearStatus::CONSTANT, LinearStatus::CONSTANT): + return LinearStatus::CONSTANT; + case pair(LinearStatus::CONSTANT, LinearStatus::LINEAR): + return LinearStatus::LINEAR; + case pair(LinearStatus::CONSTANT, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + case pair(LinearStatus::LINEAR, LinearStatus::CONSTANT): + return LinearStatus::LINEAR; + case pair(LinearStatus::LINEAR, LinearStatus::LINEAR): + return LinearStatus::LINEAR; + case pair(LinearStatus::LINEAR, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + case pair(LinearStatus::NON_LINEAR, LinearStatus::CONSTANT): + case pair(LinearStatus::NON_LINEAR, LinearStatus::LINEAR): + case pair(LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR): + return LinearStatus::NON_LINEAR; + + default: + return LinearStatus::NON_LINEAR; + } +} + +/** + * @brief Subtracts two LinearStatus values. + * + * @param a The first LinearStatus value. + * @param b The second LinearStatus value. + * + * @return The resulting LinearStatus value based on the subtraction of a and b. + */ +constexpr LinearStatus operator-(LinearStatus a, LinearStatus b) +{ + return operator+(a, b); +} + +/** + * @brief Negates a LinearStatus value (no effect). + * + * @param a The LinearStatus value to negate. + * + * @return The unchanged LinearStatus value. + */ +constexpr LinearStatus operator-(LinearStatus a) +{ + return a; +} +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/LinearityVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/LinearityVisitor.h new file mode 100644 index 0000000000..2db78786a9 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/LinearityVisitor.h @@ -0,0 +1,52 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include "antares/solver/expressions/visitors/LinearStatus.h" +#include "antares/solver/expressions/visitors/NodeVisitor.h" + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents a visitor for determining the linearity of nodes (expression). + */ +class LinearityVisitor: public NodeVisitor +{ +public: + std::string name() const override; + +private: + LinearStatus visit(const Nodes::AddNode* add) override; + LinearStatus visit(const Nodes::SubtractionNode* add) override; + LinearStatus visit(const Nodes::MultiplicationNode* add) override; + LinearStatus visit(const Nodes::DivisionNode* add) override; + LinearStatus visit(const Nodes::EqualNode* add) override; + LinearStatus visit(const Nodes::LessThanOrEqualNode* add) override; + LinearStatus visit(const Nodes::GreaterThanOrEqualNode* add) override; + LinearStatus visit(const Nodes::NegationNode* neg) override; + LinearStatus visit(const Nodes::VariableNode* param) override; + LinearStatus visit(const Nodes::ParameterNode* param) override; + LinearStatus visit(const Nodes::LiteralNode* lit) override; + LinearStatus visit(const Nodes::PortFieldNode* port_field_node) override; + LinearStatus visit(const Nodes::ComponentVariableNode* component_variable_node) override; + LinearStatus visit(const Nodes::ComponentParameterNode* component_parameter_node) override; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/NodeVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/NodeVisitor.h new file mode 100644 index 0000000000..218987fa76 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/NodeVisitor.h @@ -0,0 +1,262 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace Antares::Solver::Visitors +{ + +template +RetT tryVisit(const Nodes::Node* node, VisitorT& visitor, Args... args) +{ + auto* x = dynamic_cast(node); + return visitor.visit(x, args...); +} + +template +class NodeVisitor; + +template +struct NodeVisitsProvider +{ + using FunctionT = R (*)(const Nodes::Node*, NodeVisitor&, Args... args); + + /** + * Creates a map associating node types with corresponding visitor functions. + * + * @tparam NodeTypes A variadic pack of node types to be included in the map. + * @return An `std::unordered_map` containing the associations between node types and their + * corresponding visitor functions. + */ + template + static auto NodesVisitList() + { + std::unordered_map nodeDispatchFunctions; + ( + [&nodeDispatchFunctions] { + nodeDispatchFunctions[typeid(NodeTypes)] = &tryVisit, + NodeTypes>; + }(), + ...); + return nodeDispatchFunctions; + } +}; + +template +class NodeVisitor: public IName +{ +public: + virtual ~NodeVisitor() = default; + + /** + * Dispatches a node to an appropriate visitor function based on its type. + * + * This method uses a map that associates node types + * with their corresponding visitor functions. It attempts to find the visitor function + * for the provided `node`. If a match is found, the corresponding + * visitor function is called with the node, and any + * additional arguments (`args...`). + * + * @param node A pointer to the Node object to be visited. + * @param args Variadic template arguments to be passed to the visitor functions. + * @return The return value of the visitor function. + * + */ + R dispatch(const Nodes::Node* node, Args... args) + { + if (!node) + { + throw InvalidNode(); + } + + const static auto nodeVisitList = NodeVisitsProvider::template NodesVisitList< + Nodes::AddNode, + Nodes::SubtractionNode, + Nodes::MultiplicationNode, + Nodes::DivisionNode, + Nodes::EqualNode, + Nodes::LessThanOrEqualNode, + Nodes::GreaterThanOrEqualNode, + Nodes::NegationNode, + Nodes::ParameterNode, + Nodes::VariableNode, + Nodes::LiteralNode, + Nodes::PortFieldNode, + Nodes::ComponentVariableNode, + Nodes::ComponentParameterNode>(); + + try + { + return nodeVisitList.at(typeid(*node))(node, *this, args...); + } + catch (std::exception&) + { + logs.error() << "Antares::Solver::Visitor: could not visit the node!"; + throw; + } + } + + /** + * @brief Visits an AddNode and processes its children. + * + * @param node A pointer to the AddNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the AddNode. + */ + virtual R visit(const Nodes::AddNode*, Args... args) = 0; + /** + * @brief Visits a SubtractionNode and processes its children. + * + * @param node A pointer to the SubtractionNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the SubtractionNode. + */ + virtual R visit(const Nodes::SubtractionNode*, Args... args) = 0; + /** + * @brief Visits a MultiplicationNode and processes its children. + * + * @param node A pointer to the MultiplicationNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the MultiplicationNode. + */ + virtual R visit(const Nodes::MultiplicationNode*, Args... args) = 0; + /** + * @brief Visits a DivisionNode and processes its children. + * + * @param node A pointer to the DivisionNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the DivisionNode. + */ + virtual R visit(const Nodes::DivisionNode*, Args... args) = 0; + /** + * @brief Visits an EqualNode and processes its children. + * + * @param node A pointer to the EqualNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the EqualNode. + */ + virtual R visit(const Nodes::EqualNode*, Args... args) = 0; + + /** + * @brief Visits a LessThanOrEqualNode and processes its children. + * + * @param node A pointer to the LessThanOrEqualNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the LessThanOrEqualNode. + */ + virtual R visit(const Nodes::LessThanOrEqualNode*, Args... args) = 0; + + /** + * @brief Visits a GreaterThanOrEqualNode and processes its children. + * + * @param node A pointer to the GreaterThanOrEqualNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the GreaterThanOrEqualNode. + */ + virtual R visit(const Nodes::GreaterThanOrEqualNode*, Args... args) = 0; + + /** + * @brief Visits a NegationNode and processes its child. + * + * @param node A pointer to the NegationNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the NegationNode. + */ + virtual R visit(const Nodes::NegationNode*, Args... args) = 0; + + /** + * @brief Visits a LiteralNode. + * + * @param node A pointer to the LiteralNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the LiteralNode. + */ + virtual R visit(const Nodes::LiteralNode*, Args... args) = 0; + + /** + * @brief Visits a VariableNode. + * + * @param node A pointer to the VariableNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the VariableNode. + */ + virtual R visit(const Nodes::VariableNode*, Args... args) = 0; + + /** + * @brief Visits a ParameterNode. + * + * @param node A pointer to the ParameterNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the ParameterNode. + */ + virtual R visit(const Nodes::ParameterNode*, Args... args) = 0; + + /** + * @brief Visits a PortFieldNode. + * + * @param node A pointer to the PortFieldNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the PortFieldNode. + */ + virtual R visit(const Nodes::PortFieldNode*, Args... args) = 0; + + /** + * @brief Visits a ComponentVariableNode. + * + * @param node A pointer to the ComponentVariableNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the ComponentVariableNode. + */ + virtual R visit(const Nodes::ComponentVariableNode*, Args... args) = 0; + + /** + * @brief Visits a ComponentParameterNode. + * + * @param node A pointer to the ComponentParameterNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the ComponentParameterNode. + */ + virtual R visit(const Nodes::ComponentParameterNode*, Args... args) = 0; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/PrintVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/PrintVisitor.h new file mode 100644 index 0000000000..abe19f8122 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/PrintVisitor.h @@ -0,0 +1,51 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include "antares/solver/expressions/visitors/NodeVisitor.h" + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents a visitor for printing nodes in a syntax tree as strings. + */ +class PrintVisitor: public NodeVisitor +{ +public: + std::string name() const override; + +private: + std::string visit(const Nodes::AddNode* node) override; + std::string visit(const Nodes::SubtractionNode* node) override; + std::string visit(const Nodes::MultiplicationNode* node) override; + std::string visit(const Nodes::DivisionNode* node) override; + std::string visit(const Nodes::EqualNode* node) override; + std::string visit(const Nodes::LessThanOrEqualNode* node) override; + std::string visit(const Nodes::GreaterThanOrEqualNode* node) override; + std::string visit(const Nodes::NegationNode* node) override; + std::string visit(const Nodes::VariableNode* node) override; + std::string visit(const Nodes::ParameterNode* node) override; + std::string visit(const Nodes::LiteralNode* node) override; + std::string visit(const Nodes::PortFieldNode* node) override; + std::string visit(const Nodes::ComponentVariableNode* node) override; + std::string visit(const Nodes::ComponentParameterNode* node) override; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/SubstitutionVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/SubstitutionVisitor.h new file mode 100644 index 0000000000..14ea70de3c --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/SubstitutionVisitor.h @@ -0,0 +1,58 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include + +#include +#include +#include + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents the context for performing substitutions in a syntax tree. + */ +struct SubstitutionContext +{ + std::unordered_set variables; +}; + +/** + * @brief Represents a visitor for substituting component variables in a syntax tree. + * + * @param registry The registry used for creating new nodes. + * @param ctx The substitution context. + */ +class SubstitutionVisitor: public CloneVisitor +{ +public: + SubstitutionVisitor(Registry& registry, SubstitutionContext& ctx); + + SubstitutionContext& ctx_; + Registry& registry_; + std::string name() const override; + +private: + // Only override visit method for ComponentVariableNode, clone the rest + Nodes::Node* visit(const Nodes::ComponentVariableNode* node) override; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndex.h b/src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndex.h new file mode 100644 index 0000000000..06b561fc6c --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndex.h @@ -0,0 +1,57 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents the time and scenario variation of a value. + */ +enum class TimeIndex : unsigned int +{ + CONSTANT_IN_TIME_AND_SCENARIO = 0, + VARYING_IN_TIME_ONLY = 1, + VARYING_IN_SCENARIO_ONLY = 2, + VARYING_IN_TIME_AND_SCENARIO = 3 +}; + +/** + * @brief Combines two TimeIndex values. + * + * @param left The left operand. + * @param right The right operand. + * + * @return The combined TimeIndex value. + */ +constexpr TimeIndex operator|(const TimeIndex& left, const TimeIndex& right) +{ + /* + 0 | x = x + 3 | x = 3 + 1 | 1 = 1 + 1 | 2 = 3 + 2 | 2 = 2 + */ + return static_cast(static_cast(left) + | static_cast(right)); +} + +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndexVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndexVisitor.h new file mode 100644 index 0000000000..1b9c8ddd37 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndexVisitor.h @@ -0,0 +1,61 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#pragma once + +#include "antares/solver/expressions/visitors/NodeVisitor.h" +#include "antares/solver/expressions/visitors/TimeIndex.h" + +namespace Antares::Solver::Visitors +{ +/** + * @brief Represents a visitor for determining the time and scenario dependency of nodes in a syntax + * tree. + */ +class TimeIndexVisitor: public NodeVisitor +{ +public: + /** + * @brief Constructs a time index visitor with the specified context. + * + * @param context The context containing the time index for each node. + */ + explicit TimeIndexVisitor(std::unordered_map context); + + std::string name() const override; + +private: + std::unordered_map context_; + TimeIndex visit(const Nodes::AddNode* add) override; + TimeIndex visit(const Nodes::SubtractionNode* add) override; + TimeIndex visit(const Nodes::MultiplicationNode* add) override; + TimeIndex visit(const Nodes::DivisionNode* add) override; + TimeIndex visit(const Nodes::EqualNode* add) override; + TimeIndex visit(const Nodes::LessThanOrEqualNode* add) override; + TimeIndex visit(const Nodes::GreaterThanOrEqualNode* add) override; + TimeIndex visit(const Nodes::NegationNode* neg) override; + TimeIndex visit(const Nodes::VariableNode* param) override; + TimeIndex visit(const Nodes::ParameterNode* param) override; + TimeIndex visit(const Nodes::LiteralNode* lit) override; + TimeIndex visit(const Nodes::PortFieldNode* port_field_node) override; + TimeIndex visit(const Nodes::ComponentVariableNode* component_variable_node) override; + TimeIndex visit(const Nodes::ComponentParameterNode* component_parameter_node) override; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/nodes/BinaryNode.cpp b/src/solver/expressions/nodes/BinaryNode.cpp new file mode 100644 index 0000000000..31f22a7fc0 --- /dev/null +++ b/src/solver/expressions/nodes/BinaryNode.cpp @@ -0,0 +1,41 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#include + +namespace Antares::Solver::Nodes +{ +BinaryNode::BinaryNode(Node* left, Node* right): + leftOperand_(left), + rightOperand_(right) +{ +} + +Node* BinaryNode::right() const +{ + return rightOperand_; +} + +Node* BinaryNode::left() const +{ + return leftOperand_; +} + +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/nodes/ComponentNode.cpp b/src/solver/expressions/nodes/ComponentNode.cpp new file mode 100644 index 0000000000..4f72ffe940 --- /dev/null +++ b/src/solver/expressions/nodes/ComponentNode.cpp @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#include + +namespace Antares::Solver::Nodes +{ +ComponentNode::ComponentNode(const std::string& component_id, const std::string& component_name): + component_id_(component_id), + component_name_(component_name) +{ +} + +const std::string& ComponentNode::getComponentId() const +{ + return component_id_; +} + +const std::string& ComponentNode::getComponentName() const +{ + return component_name_; +} +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/nodes/PortFieldNode.cpp b/src/solver/expressions/nodes/PortFieldNode.cpp new file mode 100644 index 0000000000..2490977c6e --- /dev/null +++ b/src/solver/expressions/nodes/PortFieldNode.cpp @@ -0,0 +1,40 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#include + +namespace Antares::Solver::Nodes +{ +PortFieldNode::PortFieldNode(const std::string& port_name, const std::string& field_name): + port_name_(port_name), + field_name_(field_name) +{ +} + +const std::string& PortFieldNode::getPortName() const +{ + return port_name_; +} + +const std::string& PortFieldNode::getFieldName() const +{ + return field_name_; +} +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/nodes/UnaryNode.cpp b/src/solver/expressions/nodes/UnaryNode.cpp new file mode 100644 index 0000000000..c52b2d973b --- /dev/null +++ b/src/solver/expressions/nodes/UnaryNode.cpp @@ -0,0 +1,34 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#include + +namespace Antares::Solver::Nodes +{ +UnaryNode::UnaryNode(Node* n): + child_(n) +{ +} + +Node* UnaryNode::child() const +{ + return child_; +} +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/visitors/CloneVisitor.cpp b/src/solver/expressions/visitors/CloneVisitor.cpp new file mode 100644 index 0000000000..36c53084e4 --- /dev/null +++ b/src/solver/expressions/visitors/CloneVisitor.cpp @@ -0,0 +1,115 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#include +#include + +namespace Antares::Solver::Visitors +{ +CloneVisitor::CloneVisitor(Registry& registry): + registry_(registry) +{ +} + +Nodes::Node* CloneVisitor::visit(const Nodes::AddNode* node) +{ + return registry_.create(dispatch(node->left()), dispatch(node->right())); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::SubtractionNode* node) +{ + return registry_.create(dispatch(node->left()), + dispatch(node->right())); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::MultiplicationNode* node) +{ + return registry_.create(dispatch(node->left()), + dispatch(node->right())); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::DivisionNode* node) +{ + return registry_.create(dispatch(node->left()), dispatch(node->right())); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::EqualNode* node) +{ + return registry_.create(dispatch(node->left()), dispatch(node->right())); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::LessThanOrEqualNode* node) +{ + return registry_.create(dispatch(node->left()), + dispatch(node->right())); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::GreaterThanOrEqualNode* node) +{ + return registry_.create(dispatch(node->left()), + dispatch(node->right())); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::NegationNode* negationNode) +{ + return registry_.create(dispatch(negationNode->child())); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::VariableNode* variableNode) +{ + return registry_.create(variableNode->value()); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::ParameterNode* parameterNode) +{ + return registry_.create(parameterNode->value()); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::LiteralNode* literalNode) +{ + return registry_.create(literalNode->value()); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::PortFieldNode* port_field_node) +{ + return registry_.create(port_field_node->getPortName(), + port_field_node->getFieldName()); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::ComponentVariableNode* component_variable_node) +{ + return registry_.create( + component_variable_node->getComponentId(), + component_variable_node->getComponentName()); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::ComponentParameterNode* component_parameter_node) +{ + return registry_.create( + component_parameter_node->getComponentId(), + component_parameter_node->getComponentName()); +} + +std::string CloneVisitor::name() const +{ + return "CloneVisitor"; +} + +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/CompareVisitor.cpp b/src/solver/expressions/visitors/CompareVisitor.cpp new file mode 100644 index 0000000000..c7fc5c71dc --- /dev/null +++ b/src/solver/expressions/visitors/CompareVisitor.cpp @@ -0,0 +1,137 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ +#include +#include + +template +static bool compareBinaryNode(V& visitor, const T* node, const Antares::Solver::Nodes::Node* other) +{ + if (const T* other_node = dynamic_cast(other)) + { + bool left = visitor.dispatch(node->left(), other_node->left()); + bool right = visitor.dispatch(node->right(), other_node->right()); + return left && right; + } + return false; +} + +template +static bool compareGetValue(const T* node, const Antares::Solver::Nodes::Node* other) +{ + if (const T* other_node = dynamic_cast(other)) + { + return node->value() == other_node->value(); + } + return false; +} + +template +static bool compareEqualOperator(const T* node, const Antares::Solver::Nodes::Node* other) +{ + if (const T* other_node = dynamic_cast(other)) + { + return *node == *other_node; + } + return false; +} + +namespace Antares::Solver::Visitors +{ +bool CompareVisitor::visit(const Nodes::AddNode* node, const Nodes::Node* other) +{ + return compareBinaryNode(*this, node, other); +} + +bool CompareVisitor::visit(const Nodes::SubtractionNode* node, const Nodes::Node* other) +{ + return compareBinaryNode(*this, node, other); +} + +bool CompareVisitor::visit(const Nodes::MultiplicationNode* node, const Nodes::Node* other) +{ + return compareBinaryNode(*this, node, other); +} + +bool CompareVisitor::visit(const Nodes::DivisionNode* node, const Nodes::Node* other) +{ + return compareBinaryNode(*this, node, other); +} + +bool CompareVisitor::visit(const Nodes::EqualNode* node, const Nodes::Node* other) +{ + return compareBinaryNode(*this, node, other); +} + +bool CompareVisitor::visit(const Nodes::LessThanOrEqualNode* node, const Nodes::Node* other) +{ + return compareBinaryNode(*this, node, other); +} + +bool CompareVisitor::visit(const Nodes::GreaterThanOrEqualNode* node, const Nodes::Node* other) +{ + return compareBinaryNode(*this, node, other); +} + +bool CompareVisitor::visit(const Nodes::NegationNode* node, const Nodes::Node* other) +{ + if (auto* other_node = dynamic_cast(other)) + { + return dispatch(node->child(), other_node->child()); + } + return false; +} + +bool CompareVisitor::visit(const Nodes::ParameterNode* node, const Nodes::Node* other) +{ + return compareGetValue(node, other); +} + +bool CompareVisitor::visit(const Nodes::LiteralNode* node, const Nodes::Node* other) +{ + return compareGetValue(node, other); +} + +bool CompareVisitor::visit(const Nodes::VariableNode* node, const Nodes::Node* other) +{ + return compareGetValue(node, other); +} + +bool CompareVisitor::visit(const Nodes::PortFieldNode* node, const Nodes::Node* other) +{ + return compareEqualOperator(node, other); +} + +bool CompareVisitor::visit(const Nodes::ComponentVariableNode* node, const Nodes::Node* other) +{ + return compareEqualOperator(node, other); +} + +bool CompareVisitor::visit(const Nodes::ComponentParameterNode* node, const Nodes::Node* other) +{ + return compareEqualOperator(node, other); +} + +std::string CompareVisitor::name() const +{ + return "CompareVisitor"; +} + +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/EvalVisitor.cpp b/src/solver/expressions/visitors/EvalVisitor.cpp new file mode 100644 index 0000000000..336376fd4e --- /dev/null +++ b/src/solver/expressions/visitors/EvalVisitor.cpp @@ -0,0 +1,136 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ + +#include "antares/solver/expressions/visitors/EvalVisitor.h" + +#include + +namespace Antares::Solver::Visitors +{ +EvalVisitor::EvalVisitor(EvaluationContext context): + context_(std::move(context)) +{ +} + +double EvalVisitor::visit(const Nodes::AddNode* node) +{ + return dispatch(node->left()) + dispatch(node->right()); +} + +double EvalVisitor::visit(const Nodes::SubtractionNode* node) +{ + return dispatch(node->left()) - dispatch(node->right()); +} + +double EvalVisitor::visit(const Nodes::MultiplicationNode* node) +{ + return dispatch(node->left()) * dispatch(node->right()); +} + +double EvalVisitor::visit(const Nodes::DivisionNode* node) +{ + double left = dispatch(node->left()); + double right = dispatch(node->right()); + double result = 0.; + try + { + result = left / right; + if (!std::isfinite(result)) + { + throw EvalVisitorDivisionException(left, right, "is not a finite number"); + } + } + catch (const std::exception& ex) + { + throw EvalVisitorDivisionException(left, right, ex.what()); + } + return result; +} + +double EvalVisitor::visit(const Nodes::EqualNode* node) +{ + throw EvalVisitorNotImplemented(name(), node->name()); +} + +double EvalVisitor::visit(const Nodes::LessThanOrEqualNode* node) +{ + throw EvalVisitorNotImplemented(name(), node->name()); +} + +double EvalVisitor::visit(const Nodes::GreaterThanOrEqualNode* node) +{ + throw EvalVisitorNotImplemented(name(), node->name()); +} + +double EvalVisitor::visit(const Nodes::VariableNode* node) +{ + return context_.getVariableValue(node->value()); +} + +double EvalVisitor::visit(const Nodes::ParameterNode* node) +{ + return context_.getParameterValue(node->value()); +} + +double EvalVisitor::visit(const Nodes::LiteralNode* node) +{ + return node->value(); +} + +double EvalVisitor::visit(const Nodes::NegationNode* node) +{ + return -dispatch(node->child()); +} + +double EvalVisitor::visit(const Nodes::PortFieldNode* node) +{ + throw EvalVisitorNotImplemented(name(), node->name()); +} + +double EvalVisitor::visit(const Nodes::ComponentVariableNode* node) +{ + throw EvalVisitorNotImplemented(name(), node->name()); +} + +double EvalVisitor::visit(const Nodes::ComponentParameterNode* node) +{ + throw EvalVisitorNotImplemented(name(), node->name()); +} + +std::string EvalVisitor::name() const +{ + return "EvalVisitor"; +} + +EvalVisitorDivisionException::EvalVisitorDivisionException(double left, + double right, + const std::string& message): + std::runtime_error("DivisionNode: Error while evaluating : " + std::to_string(left) + "/" + + std::to_string(right) + " " + message) +{ +} + +EvalVisitorNotImplemented::EvalVisitorNotImplemented(const std::string& visitor, + const std::string& node): + std::invalid_argument("Visitor" + visitor + " not implemented for node type " + node) +{ +} +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/EvaluationContext.cpp b/src/solver/expressions/visitors/EvaluationContext.cpp new file mode 100644 index 0000000000..d25f9ec603 --- /dev/null +++ b/src/solver/expressions/visitors/EvaluationContext.cpp @@ -0,0 +1,21 @@ +#include + +namespace Antares::Solver::Visitors +{ +EvaluationContext::EvaluationContext(std::map parameters, + std::map variables): + parameters_(std::move(parameters)), + variables_(std::move(variables)) +{ +} + +double EvaluationContext::getVariableValue(const std::string& key) const +{ + return variables_.at(key); +} + +double EvaluationContext::getParameterValue(const std::string& key) const +{ + return parameters_.at(key); +} +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/InvalidNode.cpp b/src/solver/expressions/visitors/InvalidNode.cpp new file mode 100644 index 0000000000..5245a5ebc9 --- /dev/null +++ b/src/solver/expressions/visitors/InvalidNode.cpp @@ -0,0 +1,10 @@ +#include + +namespace Antares::Solver::Visitors +{ + +InvalidNode::InvalidNode(const std::string& node_name): + std::invalid_argument("Antares::Solver::Nodes Visitor: invalid node type " + node_name) +{ +} +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/LinearityVisitor.cpp b/src/solver/expressions/visitors/LinearityVisitor.cpp new file mode 100644 index 0000000000..902ae530fd --- /dev/null +++ b/src/solver/expressions/visitors/LinearityVisitor.cpp @@ -0,0 +1,104 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ + +#include "antares/solver/expressions/visitors/LinearityVisitor.h" + +#include +#include + +namespace Antares::Solver::Visitors +{ + +LinearStatus LinearityVisitor::visit(const Nodes::AddNode* node) +{ + return dispatch(node->left()) + dispatch(node->right()); +} + +LinearStatus LinearityVisitor::visit(const Nodes::SubtractionNode* node) +{ + return dispatch(node->left()) - dispatch(node->right()); +} + +LinearStatus LinearityVisitor::visit(const Nodes::MultiplicationNode* node) +{ + return dispatch(node->left()) * dispatch(node->right()); +} + +LinearStatus LinearityVisitor::visit(const Nodes::DivisionNode* node) +{ + return dispatch(node->left()) / dispatch(node->right()); +} + +LinearStatus LinearityVisitor::visit(const Nodes::EqualNode* node) +{ + return dispatch(node->left()) + dispatch(node->right()); +} + +LinearStatus LinearityVisitor::visit(const Nodes::LessThanOrEqualNode* node) +{ + return dispatch(node->left()) + dispatch(node->right()); +} + +LinearStatus LinearityVisitor::visit(const Nodes::GreaterThanOrEqualNode* node) +{ + return dispatch(node->left()) + dispatch(node->right()); +} + +LinearStatus LinearityVisitor::visit([[maybe_unused]] const Nodes::VariableNode*) +{ + return LinearStatus::LINEAR; +} + +LinearStatus LinearityVisitor::visit([[maybe_unused]] const Nodes::ParameterNode*) +{ + return LinearStatus::CONSTANT; +} + +LinearStatus LinearityVisitor::visit([[maybe_unused]] const Nodes::LiteralNode*) +{ + return LinearStatus::CONSTANT; +} + +LinearStatus LinearityVisitor::visit(const Nodes::NegationNode* node) +{ + return -dispatch(node->child()); +} + +LinearStatus LinearityVisitor::visit(const Nodes::PortFieldNode*) +{ + return LinearStatus::CONSTANT; +} + +LinearStatus LinearityVisitor::visit([[maybe_unused]] const Nodes::ComponentVariableNode*) +{ + return LinearStatus::LINEAR; +} + +LinearStatus LinearityVisitor::visit([[maybe_unused]] const Nodes::ComponentParameterNode*) +{ + return LinearStatus::CONSTANT; +} + +std::string LinearityVisitor::name() const +{ + return "LinearityVisitor"; +} +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/PrintVisitor.cpp b/src/solver/expressions/visitors/PrintVisitor.cpp new file mode 100644 index 0000000000..dda167028c --- /dev/null +++ b/src/solver/expressions/visitors/PrintVisitor.cpp @@ -0,0 +1,104 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#include + +#include +#include + +namespace Antares::Solver::Visitors +{ +std::string PrintVisitor::visit(const Nodes::AddNode* node) +{ + // Ici le compilateur (g++) a besoin de savoir qu'on veut le visit du type de base + // sinon erreur de compil 'fonction non trouvée' + return "(" + dispatch(node->left()) + "+" + dispatch(node->right()) + ")"; +} + +std::string PrintVisitor::visit(const Nodes::SubtractionNode* node) +{ + return "(" + dispatch(node->left()) + "-" + dispatch(node->right()) + ")"; +} + +std::string PrintVisitor::visit(const Nodes::MultiplicationNode* node) +{ + return "(" + dispatch(node->left()) + "*" + dispatch(node->right()) + ")"; +} + +std::string PrintVisitor::visit(const Nodes::DivisionNode* node) +{ + return "(" + dispatch(node->left()) + "/" + dispatch(node->right()) + ")"; +} + +std::string PrintVisitor::visit(const Nodes::EqualNode* node) +{ + return dispatch(node->left()) + "==" + dispatch(node->right()); +} + +std::string PrintVisitor::visit(const Nodes::LessThanOrEqualNode* node) +{ + return dispatch(node->left()) + "<=" + dispatch(node->right()); +} + +std::string PrintVisitor::visit(const Nodes::GreaterThanOrEqualNode* node) +{ + return dispatch(node->left()) + ">=" + dispatch(node->right()); +} + +std::string PrintVisitor::visit(const Nodes::NegationNode* node) +{ + return "-(" + dispatch(node->child()) + ")"; +} + +std::string PrintVisitor::visit(const Nodes::ParameterNode* node) +{ + return node->value(); +} + +std::string PrintVisitor::visit(const Nodes::VariableNode* node) +{ + return node->value(); +} + +std::string PrintVisitor::visit(const Nodes::LiteralNode* node) +{ + return std::to_string(node->value()); +} + +std::string PrintVisitor::visit(const Nodes::PortFieldNode* node) +{ + return node->getPortName() + "." + node->getFieldName(); +} + +std::string PrintVisitor::visit(const Nodes::ComponentVariableNode* node) +{ + return node->getComponentId() + "." + node->getComponentName(); +} + +std::string PrintVisitor::visit(const Nodes::ComponentParameterNode* node) +{ + return node->getComponentId() + "." + node->getComponentName(); +} + +std::string PrintVisitor::name() const +{ + return "PrintVisitor"; +} +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/SubstitutionVisitor.cpp b/src/solver/expressions/visitors/SubstitutionVisitor.cpp new file mode 100644 index 0000000000..417f77a417 --- /dev/null +++ b/src/solver/expressions/visitors/SubstitutionVisitor.cpp @@ -0,0 +1,59 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ + +#include + +#include +#include + +namespace Antares::Solver::Visitors +{ +SubstitutionVisitor::SubstitutionVisitor(Registry& registry, SubstitutionContext& ctx): + CloneVisitor(registry), + ctx_(ctx), + registry_(registry) +{ +} + +Nodes::Node* SubstitutionVisitor::visit(const Nodes::ComponentVariableNode* node) +{ + // This search has linear complexity + // To get a search of log complexity, we need to use std::unordered_set::find + // But std::unordered_set::find_if does not exist + auto it = std::find_if(ctx_.variables.begin(), + ctx_.variables.end(), + [&node](auto* x) { return *x == *node; }); + if (it != ctx_.variables.end()) + { + return *it; + } + + else + { + return CloneVisitor::visit(node); + } +} + +std::string SubstitutionVisitor::name() const +{ + return "SubstitutionVisitor"; +} +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/TimeIndexVisitor.cpp b/src/solver/expressions/visitors/TimeIndexVisitor.cpp new file mode 100644 index 0000000000..5e23c68856 --- /dev/null +++ b/src/solver/expressions/visitors/TimeIndexVisitor.cpp @@ -0,0 +1,108 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ + +#include +#include + +namespace Antares::Solver::Visitors +{ + +TimeIndex TimeIndexVisitor::visit(const Nodes::AddNode* add) +{ + return dispatch(add->left()) | dispatch(add->right()); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::SubtractionNode* sub) +{ + return dispatch(sub->left()) | dispatch(sub->right()); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::MultiplicationNode* mult) +{ + return dispatch(mult->left()) | dispatch(mult->right()); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::DivisionNode* div) +{ + return dispatch(div->left()) | dispatch(div->right()); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::EqualNode* equ) +{ + return dispatch(equ->left()) | dispatch(equ->right()); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::LessThanOrEqualNode* lt) +{ + return dispatch(lt->left()) | dispatch(lt->right()); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::GreaterThanOrEqualNode* gt) +{ + return dispatch(gt->left()) | dispatch(gt->right()); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::VariableNode* var) +{ + return context_.at(var); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::ParameterNode* param) +{ + return context_.at(param); +} + +TimeIndex TimeIndexVisitor::visit([[maybe_unused]] const Nodes::LiteralNode* lit) +{ + return TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO; +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::NegationNode* neg) +{ + return dispatch(neg->child()); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::PortFieldNode* port_field_node) +{ + return context_.at(port_field_node); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::ComponentVariableNode* component_variable_node) +{ + return context_.at(component_variable_node); +} + +TimeIndex TimeIndexVisitor::visit(const Nodes::ComponentParameterNode* component_parameter_node) +{ + return context_.at(component_parameter_node); +} + +TimeIndexVisitor::TimeIndexVisitor(std::unordered_map context): + context_(std::move(context)) +{ +} + +std::string TimeIndexVisitor::name() const +{ + return "TimeIndexVisitor"; +} + +} // namespace Antares::Solver::Visitors diff --git a/src/tests/src/solver/CMakeLists.txt b/src/tests/src/solver/CMakeLists.txt index e301a13a77..814883c633 100644 --- a/src/tests/src/solver/CMakeLists.txt +++ b/src/tests/src/solver/CMakeLists.txt @@ -1,6 +1,6 @@ - add_subdirectory(simulation) add_subdirectory(optimisation) add_subdirectory(utils) add_subdirectory(infeasible-problem-analysis) add_subdirectory(lps) +add_subdirectory(expressions) diff --git a/src/tests/src/solver/expressions/CMakeLists.txt b/src/tests/src/solver/expressions/CMakeLists.txt new file mode 100644 index 0000000000..5cdec566b7 --- /dev/null +++ b/src/tests/src/solver/expressions/CMakeLists.txt @@ -0,0 +1,28 @@ +set(EXECUTABLE_NAME test-expressions) +add_executable(${EXECUTABLE_NAME}) + +target_sources(${EXECUTABLE_NAME} + PRIVATE + test_main.cpp + test_nodes.cpp + test_PrintAndEvalNodes.cpp + test_TimeIndexVisitor.cpp + test_SubstitutionVisitor.cpp + test_LinearVisitor.cpp + test_CompareVisitor.cpp + test_CloneVisitor.cpp + test_DeepWideTrees.cpp +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + antares-solver-expressions +) + +# Storing tests-ts-numbers under the folder Unit-tests in the IDE +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) + +add_test(NAME test-expressions COMMAND ${EXECUTABLE_NAME}) + +set_property(TEST test-expressions PROPERTY LABELS unit) diff --git a/src/tests/src/solver/expressions/test_CloneVisitor.cpp b/src/tests/src/solver/expressions/test_CloneVisitor.cpp new file mode 100644 index 0000000000..b78fe098c6 --- /dev/null +++ b/src/tests/src/solver/expressions/test_CloneVisitor.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include + +#include +#include +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; +using namespace Antares::Solver::Visitors; + +BOOST_AUTO_TEST_SUITE(_CloneVisitor_) + +BOOST_FIXTURE_TEST_CASE(cloneVisitor_With_Add_Neg_ComponentVariableNode, Registry) +{ + std::string cpvar_name("var"), cpvar_id("id1"); + std::string cp_para_name("par"), cp_para_id("id2"); + ComponentVariableNode cpv(cpvar_id, cpvar_name); + ComponentParameterNode cpp(cp_para_id, cp_para_name); + double num1 = 22.0, num2 = 8.; + // (num1+num2) + Node* edge = create(create(num1), create(num2)); + // -((num1+num2)) + Node* negative_edge = create(edge); + // (-((num1+num2))+id1.var) + Node* add_node = create(negative_edge, &cpv); + // (-((-((num1+num2))+id1.var))+id2.par) == + // (-((-((22.000000+8.000000))+id1.var))+id2.par) + Node* root = create(create(add_node), &cpp); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(printed, "(-((-((22.000000+8.000000))+id1.var))+id2.par)"); + CloneVisitor cloneVisitor(*this); + Node* cloned = cloneVisitor.dispatch(root); + BOOST_CHECK_EQUAL(printed, printVisitor.dispatch(cloned)); +} + +BOOST_FIXTURE_TEST_CASE(CloneVisitor_name, Registry) +{ + CloneVisitor cloneVisitor(*this); + BOOST_CHECK_EQUAL(cloneVisitor.name(), "CloneVisitor"); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/expressions/test_CompareVisitor.cpp b/src/tests/src/solver/expressions/test_CompareVisitor.cpp new file mode 100644 index 0000000000..da814fdc13 --- /dev/null +++ b/src/tests/src/solver/expressions/test_CompareVisitor.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include + +#include +#include +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; +using namespace Antares::Solver::Visitors; + +struct ComparisonFixture +{ + Node* createSimpleExpression(double param); + Node* createComplexExpression(); + + Registry registry_; +}; + +Node* ComparisonFixture::createSimpleExpression(double param) +{ + Node* var1 = registry_.create(param); + Node* param1 = registry_.create("param1"); + Node* expr = registry_.create(var1, param1); + return expr; +} + +Node* ComparisonFixture::createComplexExpression() +{ + // NOTE : this expression makes no sense, only for testing purposes + // NOTE2 : Some elements are re-used (e.g simple), this is valid since memory is handled + // separately (no double free) + + Node* simple = createSimpleExpression(42.); + Node* neg = registry_.create(simple); + Node* mult = registry_.create(simple, neg); + Node* comp = registry_.create("hello", "world"); + Node* div = registry_.create(mult, comp); + Node* div2 = registry_.create(div, simple); + Node* add = registry_.create(div, div2); + Node* sub = registry_.create(add, neg); + Node* cmp = registry_.create(sub, add); + Node* pf = registry_.create("port", "field"); + Node* addf = registry_.create(pf, cmp); + return addf; +} + +BOOST_AUTO_TEST_SUITE(_CompareVisitor_) + +BOOST_FIXTURE_TEST_CASE(simple_comparison_to_itself, ComparisonFixture) +{ + CompareVisitor cmp; + Node* expr = createSimpleExpression(65.); + BOOST_CHECK(cmp.dispatch(expr, expr)); +} + +BOOST_FIXTURE_TEST_CASE(comparison_to_other_same, ComparisonFixture) +{ + CompareVisitor cmp; + Node* expr1 = createSimpleExpression(65.); + Node* expr2 = createSimpleExpression(65.); + BOOST_CHECK(cmp.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(comparison_to_other_different, ComparisonFixture) +{ + CompareVisitor cmp; + Node* expr1 = createSimpleExpression(64.); + Node* expr2 = createSimpleExpression(65.); + BOOST_CHECK(!cmp.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(comparison_to_self_complex, ComparisonFixture) +{ + CompareVisitor cmp; + Node* expr = createComplexExpression(); + BOOST_CHECK(cmp.dispatch(expr, expr)); +} + +BOOST_FIXTURE_TEST_CASE(comparison_to_clone_complex, ComparisonFixture) +{ + CompareVisitor cmp; + Node* expr = createComplexExpression(); + CloneVisitor cloneVisitor(registry_); + Node* expr_cloned = cloneVisitor.dispatch(expr); + BOOST_CHECK(cmp.dispatch(expr, expr_cloned)); +} + +BOOST_FIXTURE_TEST_CASE(comparison_to_other_complex, ComparisonFixture) +{ + CompareVisitor cmp; + Node* expr1 = createComplexExpression(); + Node* expr2 = createComplexExpression(); + BOOST_CHECK(cmp.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(comparison_to_other_different_complex, ComparisonFixture) +{ + CompareVisitor cmp; + Node* expr1 = createComplexExpression(); + Node* expr2 = registry_.create(expr1); + BOOST_CHECK(!cmp.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(CompareVisitor_name, Registry) +{ + CompareVisitor compareVisitor; + BOOST_CHECK_EQUAL(compareVisitor.name(), "CompareVisitor"); +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/expressions/test_DeepWideTrees.cpp b/src/tests/src/solver/expressions/test_DeepWideTrees.cpp new file mode 100644 index 0000000000..957996641b --- /dev/null +++ b/src/tests/src/solver/expressions/test_DeepWideTrees.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include + +#include +#include +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; +using namespace Antares::Solver::Visitors; + +BOOST_AUTO_TEST_SUITE(_DeepTree_) + +static Node* deepNegationTree(Registry& registry, double litValue, size_t depth) +{ + Node* node = registry.create(litValue); + for (size_t c = 0; c < depth; c++) + { + node = registry.create(node); + } + return node; +} + +BOOST_FIXTURE_TEST_CASE(deep_tree_even, Registry) +{ + Node* node = deepNegationTree(*this, 42., 1000); + EvalVisitor evalVisitor; + // (-1)^1000 = 1 + BOOST_CHECK_EQUAL(evalVisitor.dispatch(node), 42.); +} + +BOOST_FIXTURE_TEST_CASE(deep_tree_odd, Registry) +{ + Node* node = deepNegationTree(*this, 42., 1001); + EvalVisitor evalVisitor; + // (-1)^1001 = -1 + BOOST_CHECK_EQUAL(evalVisitor.dispatch(node), -42.); +} + +static Node* deepAddTree(Registry& registry, AddNode* root, int depth) +{ + if (depth > 0) + { + Node* left = deepAddTree(registry, root, depth - 1); + Node* right = deepAddTree(registry, root, depth - 1); + return registry.create(left, right); + } + else + { + return registry.create(42.); + } +} + +BOOST_FIXTURE_TEST_CASE(binary_tree, Registry) +{ + // AddNode's children are not mutable, so we'll replace this empty root with an actual one + AddNode* root = create(nullptr, nullptr); + Node* node = deepAddTree(*this, root, 10); + EvalVisitor evalVisitor; + // We expect 1024 = 2^10 literal nodes, each carrying value 42. + BOOST_CHECK_EQUAL(evalVisitor.dispatch(node), 42. * 1024); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/expressions/test_LinearVisitor.cpp b/src/tests/src/solver/expressions/test_LinearVisitor.cpp new file mode 100644 index 0000000000..7bc67ce8ed --- /dev/null +++ b/src/tests/src/solver/expressions/test_LinearVisitor.cpp @@ -0,0 +1,293 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; +using namespace Antares::Solver::Visitors; + +namespace bdata = boost::unit_test::data; + +// Only necessary for BOOST_CHECK_EQUAL +namespace Antares::Solver::Visitors +{ +static std::ostream& operator<<(std::ostream& os, LinearStatus s) +{ + switch (s) + { + case LinearStatus::CONSTANT: + return os << "LinearStatus::CONSTANT"; + case LinearStatus::LINEAR: + return os << "LinearStatus::LINEAR"; + case LinearStatus::NON_LINEAR: + return os << "LinearStatus::NON_LINEAR"; + default: + return os << ""; + } +} +} // namespace Antares::Solver::Visitors + +BOOST_AUTO_TEST_SUITE(_LinearVisitor_) + +BOOST_AUTO_TEST_CASE(linear_status_plus) +{ + BOOST_CHECK_EQUAL(LinearStatus::LINEAR + LinearStatus::LINEAR, LinearStatus::LINEAR); + BOOST_CHECK_EQUAL(LinearStatus::LINEAR + LinearStatus::CONSTANT, LinearStatus::LINEAR); + BOOST_CHECK_EQUAL(LinearStatus::LINEAR + LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR); + + BOOST_CHECK_EQUAL(LinearStatus::CONSTANT + LinearStatus::CONSTANT, LinearStatus::CONSTANT); + BOOST_CHECK_EQUAL(LinearStatus::CONSTANT + LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR); + + BOOST_CHECK_EQUAL(LinearStatus::NON_LINEAR + LinearStatus::NON_LINEAR, + LinearStatus::NON_LINEAR); +} + +BOOST_AUTO_TEST_CASE(linear_status_mult) +{ + BOOST_CHECK_EQUAL(LinearStatus::LINEAR * LinearStatus::LINEAR, LinearStatus::NON_LINEAR); + BOOST_CHECK_EQUAL(LinearStatus::LINEAR * LinearStatus::CONSTANT, LinearStatus::LINEAR); + BOOST_CHECK_EQUAL(LinearStatus::LINEAR * LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR); + + BOOST_CHECK_EQUAL(LinearStatus::CONSTANT * LinearStatus::CONSTANT, LinearStatus::CONSTANT); + BOOST_CHECK_EQUAL(LinearStatus::CONSTANT * LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR); + + BOOST_CHECK_EQUAL(LinearStatus::NON_LINEAR * LinearStatus::NON_LINEAR, + LinearStatus::NON_LINEAR); +} + +BOOST_AUTO_TEST_CASE(linear_status_divide) +{ + BOOST_CHECK_EQUAL(LinearStatus::LINEAR / LinearStatus::LINEAR, LinearStatus::NON_LINEAR); + BOOST_CHECK_EQUAL(LinearStatus::LINEAR / LinearStatus::CONSTANT, LinearStatus::LINEAR); + BOOST_CHECK_EQUAL(LinearStatus::LINEAR / LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR); + + BOOST_CHECK_EQUAL(LinearStatus::CONSTANT / LinearStatus::CONSTANT, LinearStatus::CONSTANT); + BOOST_CHECK_EQUAL(LinearStatus::CONSTANT / LinearStatus::NON_LINEAR, LinearStatus::NON_LINEAR); + + BOOST_CHECK_EQUAL(LinearStatus::NON_LINEAR / LinearStatus::NON_LINEAR, + LinearStatus::NON_LINEAR); +} + +static const std::vector LinearStatus_ALL = {LinearStatus::LINEAR, + LinearStatus::NON_LINEAR, + LinearStatus::CONSTANT}; + +BOOST_DATA_TEST_CASE(linear_status_minus, bdata::make(LinearStatus_ALL), x) +{ + BOOST_CHECK_EQUAL(x, -x); +} + +BOOST_DATA_TEST_CASE(linear_plus_commutative, + bdata::make(LinearStatus_ALL) * bdata::make(LinearStatus_ALL), + x, + y) +{ + BOOST_CHECK_EQUAL(x + y, y + x); +} + +BOOST_DATA_TEST_CASE(linear_subtract_same_as_plus, + bdata::make(LinearStatus_ALL) * bdata::make(LinearStatus_ALL), + x, + y) +{ + BOOST_CHECK_EQUAL(x - y, x + y); +} + +BOOST_DATA_TEST_CASE(linear_multiply_commutative, + bdata::make(LinearStatus_ALL) * bdata::make(LinearStatus_ALL), + x, + y) +{ + BOOST_CHECK_EQUAL(x * y, y * x); +} + +BOOST_FIXTURE_TEST_CASE(comparison_nodes_variable_variable_is_linear, Registry) +{ + PrintVisitor printVisitor; + LinearityVisitor linearVisitor; + + VariableNode var1("x"); + // variable + VariableNode var2("y"); + // x==y + Node* eq = create(&var1, &var2); + BOOST_CHECK_EQUAL(printVisitor.dispatch(eq), "x==y"); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(eq), LinearStatus::LINEAR); + // x<=y + Node* lt = create(&var1, &var2); + BOOST_CHECK_EQUAL(printVisitor.dispatch(lt), "x<=y"); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(lt), LinearStatus::LINEAR); + // x>=y + Node* gt = create(&var1, &var2); + BOOST_CHECK_EQUAL(printVisitor.dispatch(gt), "x>=y"); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(gt), LinearStatus::LINEAR); +} + +BOOST_FIXTURE_TEST_CASE(comparison_nodes_variable_constant_is_linear, Registry) +{ + PrintVisitor printVisitor; + LinearityVisitor linearVisitor; + + VariableNode var1("x"); + // variable + LiteralNode literal(21.); + // x==21 + Node* eq = create(&var1, &literal); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(eq), LinearStatus::LINEAR); + // x<=21 + Node* lt = create(&var1, &literal); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(lt), LinearStatus::LINEAR); + // x>=21 + Node* gt = create(&var1, &literal); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(gt), LinearStatus::LINEAR); +} + +BOOST_FIXTURE_TEST_CASE(comparison_nodes_constant_constant_is_constant, Registry) +{ + PrintVisitor printVisitor; + LinearityVisitor linearVisitor; + + LiteralNode literal1(2.); + LiteralNode literal2(21.); + // 2==21 + Node* eq = create(&literal1, &literal2); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(eq), LinearStatus::CONSTANT); + // 2<=21 + Node* lt = create(&literal1, &literal2); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(lt), LinearStatus::CONSTANT); + // 2>=21 + Node* gt = create(&literal1, &literal2); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(gt), LinearStatus::CONSTANT); +} + +BOOST_FIXTURE_TEST_CASE(comparison_nodes_non_lin_constant_is_constant, Registry) +{ + PrintVisitor printVisitor; + LinearityVisitor linearVisitor; + + VariableNode var1("x"); + // variable + VariableNode var2("y"); + MultiplicationNode mult(&var1, &var2); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(&mult), LinearStatus::NON_LINEAR); + + AddNode add(&mult, &var1); + Node* gt = create(&mult, &var2); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(gt), LinearStatus::NON_LINEAR); +} + +BOOST_FIXTURE_TEST_CASE(simple_linear, Registry) +{ + LiteralNode literalNode1(10.); + VariableNode var1("x"); + // 10.*x + Node* u = create(&literalNode1, &var1); + + LiteralNode literalNode2(20.); + ComponentVariableNode var2("id", "y"); + // 20.*id.y + Node* v = create(&literalNode2, &var2); + // 10.*x+20.*id.y + Node* expr = create(u, v); + + PrintVisitor printVisitor; + BOOST_CHECK_EQUAL(printVisitor.dispatch(expr), "((10.000000*x)+(20.000000*id.y))"); + LinearityVisitor linearVisitor; + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::LINEAR); +} + +BOOST_FIXTURE_TEST_CASE(simple_not_linear, Registry) +{ + VariableNode var1("x"); + ComponentVariableNode var2("id", "y"); + // x*id.y + Node* expr = create(&var1, &var2); + + PrintVisitor printVisitor; + BOOST_CHECK_EQUAL(printVisitor.dispatch(expr), "(x*id.y)"); + LinearityVisitor linearVisitor; + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::NON_LINEAR); +} + +BOOST_FIXTURE_TEST_CASE(simple_linear_division, Registry) +{ + VariableNode var1("x"); + // constant + ParameterNode param("y"); + // x/y + Node* expr = create(&var1, ¶m); + + PrintVisitor printVisitor; + BOOST_CHECK_EQUAL(printVisitor.dispatch(expr), "(x/y)"); + LinearityVisitor linearVisitor; + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::LINEAR); +} + +BOOST_FIXTURE_TEST_CASE(simple_non_linear_division, Registry) +{ + VariableNode var1("x"); + // variable + VariableNode var2("y"); + // x/y + Node* expr = create(&var1, &var2); + + PrintVisitor printVisitor; + BOOST_CHECK_EQUAL(printVisitor.dispatch(expr), "(x/y)"); + LinearityVisitor linearVisitor; + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::NON_LINEAR); +} + +BOOST_FIXTURE_TEST_CASE(simple_constant_expression, Registry) +{ + PrintVisitor printVisitor; + LinearityVisitor linearVisitor; + LiteralNode var1(65.); + // Parameter + ParameterNode par("p1"); + + // Port field + PortFieldNode portFieldNode("port", "field"); + + // 65.*p1 + Node* mult = create(&var1, &par); + // ((65.*p1)+port.field) + Node* expr = create(mult, &portFieldNode); + BOOST_CHECK_EQUAL(printVisitor.dispatch(expr), "((65.000000*p1)+port.field)"); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::CONSTANT); +} + +BOOST_FIXTURE_TEST_CASE(LinearityVisitor_name, Registry) +{ + LinearityVisitor linearityVisitor; + BOOST_CHECK_EQUAL(linearityVisitor.name(), "LinearityVisitor"); +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/expressions/test_PrintAndEvalNodes.cpp b/src/tests/src/solver/expressions/test_PrintAndEvalNodes.cpp new file mode 100644 index 0000000000..8ad5a49a60 --- /dev/null +++ b/src/tests/src/solver/expressions/test_PrintAndEvalNodes.cpp @@ -0,0 +1,294 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include + +#include +#include +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; +using namespace Antares::Solver::Visitors; + +BOOST_AUTO_TEST_SUITE(_PrintAndEvalNodes_) + +BOOST_AUTO_TEST_CASE(print_single_literal) +{ + LiteralNode literal(21); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(&literal); + + BOOST_CHECK_EQUAL(printed, "21.000000"); // TODO Number of decimals implementation dependent ? +} + +BOOST_AUTO_TEST_CASE(eval_single_literal) +{ + LiteralNode literal(21); + + EvalVisitor evalVisitor; + const double eval = evalVisitor.dispatch(&literal); + + BOOST_CHECK_EQUAL(eval, 21.); // TODO Number of decimals implementation dependent ? +} + +/* +Fixtures are used for the Registry that manages the memory allocations of nodes + +So instead of writing + Registry mem; + Node* root = mem.create(mem.create(21), mem.create(2)); +We can just write + Node* root = create(create(21), create(2)); + +since create is short for this->create. +*/ + +BOOST_FIXTURE_TEST_CASE(print_add_two_literals, Registry) +{ + Node* root = create(create(21), create(2)); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(printed, + "(21.000000+2.000000)"); // TODO Number of decimals implementation dependent ? +} + +BOOST_FIXTURE_TEST_CASE(eval_add_two_literals, Registry) +{ + Node* root = create(create(21), create(2)); + EvalVisitor evalVisitor; + double eval = evalVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(eval, 23.); +} + +BOOST_FIXTURE_TEST_CASE(eval_negation_literal, Registry) +{ + const double num = 1428.0; + Node* root = create(create(num)); + EvalVisitor evalVisitor; + double eval = evalVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(eval, -num); +} + +BOOST_FIXTURE_TEST_CASE(eval_Add_And_Negation_Nodes, Registry) +{ + const double num1 = 1428; + const double num2 = 8241; + Node* negative_num2 = create(create(num2)); + Node* root = create(create(num1), negative_num2); + EvalVisitor evalVisitor; + double eval = evalVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(eval, num1 - num2); +} + +BOOST_FIXTURE_TEST_CASE(Negative_of_AddNode, Registry) +{ + const double num1 = 1428; + const double num2 = 8241; + Node* add_node = create(create(num1), create(num2)); + Node* neg = create(add_node); + EvalVisitor evalVisitor; + double eval = evalVisitor.dispatch(neg); + + BOOST_CHECK_EQUAL(eval, -(num1 + num2)); +} + +BOOST_FIXTURE_TEST_CASE(print_port_field_node, Registry) +{ + PortFieldNode pt_fd("august", "2024"); + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(&pt_fd); + + BOOST_CHECK_EQUAL(printed, "august.2024"); +} + +BOOST_FIXTURE_TEST_CASE(evaluate_param, Registry) +{ + ParameterNode root("my-param"); + const double value = 221.3; + EvaluationContext context({{"my-param", value}}, {}); + + EvalVisitor evalVisitor(context); + const double eval = evalVisitor.dispatch(&root); + + BOOST_CHECK_EQUAL(value, eval); +} + +BOOST_FIXTURE_TEST_CASE(evaluate_variable, Registry) +{ + VariableNode root("my-variable"); + const double value = 221.3; + EvaluationContext context({}, {{"my-variable", value}}); + + EvalVisitor evalVisitor(context); + const double eval = evalVisitor.dispatch(&root); + + BOOST_CHECK_EQUAL(value, eval); +} + +BOOST_FIXTURE_TEST_CASE(multiplication_node, Registry) +{ + double num1 = 22.0, num2 = 8; + Node* mult = create(create(num1), create(num2)); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(mult); + + BOOST_CHECK_EQUAL(printed, "(22.000000*8.000000)"); + EvalVisitor evalVisitor; + BOOST_CHECK_EQUAL(evalVisitor.dispatch(mult), num1 * num2); +} + +BOOST_FIXTURE_TEST_CASE(division_node, Registry) +{ + double num1 = 22.0, num2 = 8; + Node* div = create(create(num1), create(num2)); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(div); + + BOOST_CHECK_EQUAL(printed, "(22.000000/8.000000)"); + EvalVisitor evalVisitor; + BOOST_CHECK_EQUAL(evalVisitor.dispatch(div), num1 / num2); +} + +BOOST_FIXTURE_TEST_CASE(division_by_zero, Registry) +{ + double num1 = 22.0, num2 = 0.; + Node* div = create(create(num1), create(num2)); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(div); + + BOOST_CHECK_EQUAL(printed, "(22.000000/0.000000)"); + EvalVisitor evalVisitor; + + BOOST_CHECK_THROW(evalVisitor.dispatch(div), EvalVisitorDivisionException); +} + +BOOST_AUTO_TEST_CASE(DivisionNodeFull) +{ + EvalVisitor evalVisitor; + LiteralNode literalNode1(23.); + LiteralNode literalNode2(-23.); + + DivisionNode divisionNode1(&literalNode1, &literalNode1); + BOOST_CHECK_EQUAL(evalVisitor.dispatch(&divisionNode1), 1.0); + + DivisionNode divisionNode2(&literalNode1, &literalNode2); + BOOST_CHECK_EQUAL(evalVisitor.dispatch(&divisionNode2), -1.0); + + LiteralNode* literalNull = nullptr; + + DivisionNode divisionNode3(&literalNode1, literalNull); + + BOOST_CHECK_THROW(evalVisitor.dispatch(&divisionNode3), InvalidNode); + + // truncated to zero + LiteralNode literalVerySmall(1.e-324); + + DivisionNode divisionNode4(&literalNode1, &literalVerySmall); + + BOOST_CHECK_THROW(evalVisitor.dispatch(&divisionNode4), EvalVisitorDivisionException); +} + +BOOST_FIXTURE_TEST_CASE(subtraction_node, Registry) +{ + double num1 = 22.0, num2 = 8; + Node* sub = create(create(num1), create(num2)); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(sub); + + BOOST_CHECK_EQUAL(printed, "(22.000000-8.000000)"); + EvalVisitor evalVisitor; + BOOST_CHECK_EQUAL(evalVisitor.dispatch(sub), num1 - num2); +} + +BOOST_FIXTURE_TEST_CASE(comparison_node, Registry) +{ + double num1 = 22.0, num2 = 8; + // (num1-num2) = (22.000000-8.000000) + SubtractionNode sub1(create(num1), create(num2)); + // (num2-num1) = (8.000000-22.000000) + SubtractionNode sub2(create(num2), create(num1)); + + PrintVisitor printVisitor; + + EqualNode equ(&sub1, &sub2); + auto printed = printVisitor.dispatch(&equ); + BOOST_CHECK_EQUAL(printed, "(22.000000-8.000000)==(8.000000-22.000000)"); + + LessThanOrEqualNode lt(&sub1, &sub2); + printed = printVisitor.dispatch(<); + BOOST_CHECK_EQUAL(printed, "(22.000000-8.000000)<=(8.000000-22.000000)"); + + GreaterThanOrEqualNode gt(&sub1, &sub2); + printed = printVisitor.dispatch(>); + BOOST_CHECK_EQUAL(printed, "(22.000000-8.000000)>=(8.000000-22.000000)"); +} + +BOOST_AUTO_TEST_CASE(invalidNode) +{ + AddNode* null_node = nullptr; + EvalVisitor evalVisitor; + BOOST_CHECK_THROW(evalVisitor.dispatch(null_node), InvalidNode); +} + +BOOST_FIXTURE_TEST_CASE(NotEvaluableNodes, Registry) +{ + LiteralNode literalNode(23.); + std::string component_id("id"); + std::string name("name"); + std::vector nodes = {create(&literalNode, &literalNode), + create(&literalNode, &literalNode), + create(&literalNode, &literalNode), + create(name, name), + create(component_id, name), + create(component_id, name)}; + EvalVisitor evalVisitor; + for (auto* node: nodes) + { + BOOST_CHECK_THROW(evalVisitor.dispatch(node), EvalVisitorNotImplemented); + } +} + +BOOST_AUTO_TEST_CASE(PrintVisitor_name) +{ + PrintVisitor printVisitor; + BOOST_CHECK_EQUAL(printVisitor.name(), "PrintVisitor"); +} + +BOOST_AUTO_TEST_CASE(EvalVisitor_name) +{ + EvalVisitor evalVisitor; + BOOST_CHECK_EQUAL(evalVisitor.name(), "EvalVisitor"); +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/expressions/test_SubstitutionVisitor.cpp b/src/tests/src/solver/expressions/test_SubstitutionVisitor.cpp new file mode 100644 index 0000000000..8a4080fc0c --- /dev/null +++ b/src/tests/src/solver/expressions/test_SubstitutionVisitor.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include + +#include +#include +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; +using namespace Antares::Solver::Visitors; + +// Only necessary for BOOST_CHECK_EQUAL + +BOOST_AUTO_TEST_SUITE(_SubstitutionVisitor_) + +std::pair fillContext( + SubstitutionContext& ctx, + Registry& registry) +{ + auto add = [&ctx, ®istry](const std::string& component, const std::string& variable) + { + auto* in = registry.create(component, variable); + ctx.variables.insert(in); + return in; + }; + return {add("component1", "variable1"), add("component2", "variable1")}; +} + +BOOST_FIXTURE_TEST_CASE(SubstitutionVisitor_substitute_one_node, Registry) +{ + SubstitutionContext ctx; + auto variables = fillContext(ctx, *this); + + auto* component_original = create("component1", "notInThere"); + + Node* root = create(create("component1", "variable1"), + component_original); + SubstitutionVisitor sub(*this, ctx); + Node* subsd = sub.dispatch(root); + + // The root of the new tree should be different + BOOST_CHECK_NE(root, subsd); + + // We expect to find a substituted node on the left + BOOST_CHECK_EQUAL(dynamic_cast(subsd)->left(), variables.first); + + // We expect to find an original node on the right + auto* right_substituted = dynamic_cast(subsd)->right(); + BOOST_CHECK_NE(right_substituted, variables.first); + BOOST_CHECK_NE(right_substituted, variables.second); + + auto* component = dynamic_cast(right_substituted); + BOOST_REQUIRE(component); + // We don't use BOOST_CHECK_EQUAL because operator<<(..., const ComponentVariableNode&) is + // not implemented + BOOST_CHECK(*component == *component_original); +} + +BOOST_FIXTURE_TEST_CASE(SubstitutionVisitor_name, Registry) +{ + SubstitutionContext ctx; + + SubstitutionVisitor substitutionVisitor(*this, ctx); + BOOST_CHECK_EQUAL(substitutionVisitor.name(), "SubstitutionVisitor"); +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/expressions/test_TimeIndexVisitor.cpp b/src/tests/src/solver/expressions/test_TimeIndexVisitor.cpp new file mode 100644 index 0000000000..21920db288 --- /dev/null +++ b/src/tests/src/solver/expressions/test_TimeIndexVisitor.cpp @@ -0,0 +1,200 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include +#include + +#include +#include +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; +using namespace Antares::Solver::Visitors; + +namespace bdata = boost::unit_test::data; + +namespace Antares::Solver::Visitors +{ +static std::ostream& operator<<(std::ostream& os, TimeIndex s) +{ + switch (s) + { + case TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO: + return os << "TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO"; + case TimeIndex::VARYING_IN_TIME_ONLY: + return os << "TimeIndex::VARYING_IN_TIME_ONLY"; + case TimeIndex::VARYING_IN_SCENARIO_ONLY: + return os << "TimeIndex::VARYING_IN_SCENARIO_ONLY"; + case TimeIndex::VARYING_IN_TIME_AND_SCENARIO: + return os << "TimeIndex::VARYING_IN_TIME_AND_SCENARIO"; + default: + return os << ""; + } +} +} // namespace Antares::Solver::Visitors +BOOST_AUTO_TEST_SUITE(_TimeIndexVisitor_) + +BOOST_FIXTURE_TEST_CASE(simple_time_dependant_expression, Registry) +{ + PrintVisitor printVisitor; + std::unordered_map context; + // LiteralNode --> constant in time and for all scenarios + LiteralNode literalNode(65.); + + // Parameter --> constant in time and varying scenarios + ParameterNode parameterNode1("p1"); + context[¶meterNode1] = TimeIndex::VARYING_IN_SCENARIO_ONLY; + + // Variable time varying but constant across scenarios + VariableNode variableNode1("v1"); + context[&variableNode1] = TimeIndex::VARYING_IN_TIME_ONLY; + TimeIndexVisitor timeIndexVisitor(context); + + BOOST_CHECK_EQUAL(timeIndexVisitor.dispatch(&literalNode), + TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO); + BOOST_CHECK_EQUAL(timeIndexVisitor.dispatch(¶meterNode1), + TimeIndex::VARYING_IN_SCENARIO_ONLY); + BOOST_CHECK_EQUAL(timeIndexVisitor.dispatch(&variableNode1), TimeIndex::VARYING_IN_TIME_ONLY); + + // addition of parameterNode1 and variableNode1 is time and scenario dependent + Node* expr = create(¶meterNode1, &variableNode1); + BOOST_CHECK_EQUAL(timeIndexVisitor.dispatch(expr), TimeIndex::VARYING_IN_TIME_AND_SCENARIO); +} + +static const std::vector TimeIndex_ALL{TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO, + TimeIndex::VARYING_IN_TIME_ONLY, + TimeIndex::VARYING_IN_SCENARIO_ONLY, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO}; + +template +static std::pair s_(Registry& registry) +{ + Node* left = registry.create(42.); + ParameterNode* right = registry.create("param"); + return {registry.create(left, right), right}; +} + +static const std::vector (*)(Registry& registry)> + operator_ALL{&s_, + &s_, + &s_, + &s_, + &s_, + &s_, + &s_}; + +BOOST_DATA_TEST_CASE_F(Registry, + simple_all, + bdata::make(TimeIndex_ALL) * bdata::make(operator_ALL), + timeIndex, + binaryOperator) +{ + auto [root, parameter] = binaryOperator(*this); + std::unordered_map context; + context[parameter] = timeIndex; + TimeIndexVisitor timeIndexVisitor(context); + BOOST_CHECK_EQUAL(timeIndexVisitor.dispatch(root), timeIndex); + Node* neg = create(root); + BOOST_CHECK_EQUAL(timeIndexVisitor.dispatch(neg), timeIndex); +} + +template +static Node* singleNode(Registry& registry) +{ + return registry.create("hello", "world"); +} + +static const std::vector& registry)> singleNode_ALL{ + &singleNode, + &singleNode, + &singleNode}; + +BOOST_DATA_TEST_CASE_F(Registry, + signe_node, + bdata::make(TimeIndex_ALL) * bdata::make(singleNode_ALL), + timeIndex, + singleNode) +{ + Node* root = singleNode(*this); + std::unordered_map context; + context[root] = timeIndex; + TimeIndexVisitor timeIndexVisitor(context); + BOOST_CHECK_EQUAL(timeIndexVisitor.dispatch(root), timeIndex); + Node* neg = create(root); + BOOST_CHECK_EQUAL(timeIndexVisitor.dispatch(neg), timeIndex); +} + +BOOST_AUTO_TEST_CASE(test_time_index_logical_operator) +{ + BOOST_CHECK_EQUAL(TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO + | TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO, + TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO); + BOOST_CHECK_EQUAL(TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO | TimeIndex::VARYING_IN_TIME_ONLY, + TimeIndex::VARYING_IN_TIME_ONLY); + BOOST_CHECK_EQUAL(TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO + | TimeIndex::VARYING_IN_SCENARIO_ONLY, + TimeIndex::VARYING_IN_SCENARIO_ONLY); + BOOST_CHECK_EQUAL(TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO + | TimeIndex::VARYING_IN_TIME_AND_SCENARIO, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); + + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_TIME_ONLY | TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO, + TimeIndex::VARYING_IN_TIME_ONLY); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_TIME_ONLY | TimeIndex::VARYING_IN_TIME_ONLY, + TimeIndex::VARYING_IN_TIME_ONLY); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_TIME_ONLY | TimeIndex::VARYING_IN_SCENARIO_ONLY, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_TIME_ONLY | TimeIndex::VARYING_IN_TIME_AND_SCENARIO, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); + + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_SCENARIO_ONLY + | TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO, + TimeIndex::VARYING_IN_SCENARIO_ONLY); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_SCENARIO_ONLY | TimeIndex::VARYING_IN_TIME_ONLY, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_SCENARIO_ONLY | TimeIndex::VARYING_IN_SCENARIO_ONLY, + TimeIndex::VARYING_IN_SCENARIO_ONLY); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_SCENARIO_ONLY | TimeIndex::VARYING_IN_TIME_AND_SCENARIO, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); + + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_TIME_AND_SCENARIO + | TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_TIME_AND_SCENARIO | TimeIndex::VARYING_IN_TIME_ONLY, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_TIME_AND_SCENARIO | TimeIndex::VARYING_IN_SCENARIO_ONLY, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); + BOOST_CHECK_EQUAL(TimeIndex::VARYING_IN_TIME_AND_SCENARIO + | TimeIndex::VARYING_IN_TIME_AND_SCENARIO, + TimeIndex::VARYING_IN_TIME_AND_SCENARIO); +} + +BOOST_FIXTURE_TEST_CASE(TimeIndexVisitor_name, Registry) +{ + std::unordered_map context; + TimeIndexVisitor timeIndexVisitor(context); + BOOST_CHECK_EQUAL(timeIndexVisitor.name(), "TimeIndexVisitor"); +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/expressions/test_main.cpp b/src/tests/src/solver/expressions/test_main.cpp new file mode 100644 index 0000000000..e304a39422 --- /dev/null +++ b/src/tests/src/solver/expressions/test_main.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define BOOST_TEST_MODULE expressions +#define WIN32_LEAN_AND_MEAN + +#include diff --git a/src/tests/src/solver/expressions/test_nodes.cpp b/src/tests/src/solver/expressions/test_nodes.cpp new file mode 100644 index 0000000000..01e4a5b41c --- /dev/null +++ b/src/tests/src/solver/expressions/test_nodes.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include +#include + +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; + +BOOST_AUTO_TEST_SUITE(_Nodes_) + +// BOOST_AUTO_TEST_CASE(UnaryNodeTest) +// { +// LiteralNode literalNode(23.); +// UnaryNode unaryNodeWithNullChild(nullptr); +// BOOST_CHECK_EQUAL(unaryNodeWithNullChild.child(), nullptr); +// UnaryNode unaryNode(&literalNode); +// BOOST_CHECK_EQUAL(unaryNode.child(), &literalNode); +// } + +BOOST_AUTO_TEST_CASE(PortFieldNodeTest) +{ + LiteralNode literalNode(23.); + std::string portName1("p1"); + std::string portName2("p2"); + std::string fieldName1("f1"); + std::string fieldName2("f2"); + + PortFieldNode portFieldNode1(portName1, fieldName1); + PortFieldNode portFieldNode1TwinNode(portName1, fieldName1); + BOOST_CHECK_EQUAL(portFieldNode1 == portFieldNode1TwinNode, true); + + PortFieldNode shareNameWithPortField1(portName1, fieldName2); + BOOST_CHECK_EQUAL(portFieldNode1 == shareNameWithPortField1, false); + + PortFieldNode shareFieldNameWithPortField1(portName2, fieldName1); + BOOST_CHECK_EQUAL(portFieldNode1 == shareFieldNameWithPortField1, false); + + PortFieldNode portFieldNode2(portName2, fieldName2); + BOOST_CHECK_EQUAL(portFieldNode1 == portFieldNode2, false); +} + +BOOST_FIXTURE_TEST_CASE(nodes_name, Registry) +{ + auto literalNode = create(2024.2); + std::map nodes = { + {literalNode, "LiteralNode"}, + {create(literalNode, literalNode), "AddNode"}, + {create(literalNode, literalNode), "SubtractionNode"}, + {create(literalNode, literalNode), "MultiplicationNode"}, + {create(literalNode, literalNode), "DivisionNode"}, + {create(literalNode, literalNode), "EqualNode"}, + {create(literalNode, literalNode), "LessThanOrEqualNode"}, + {create(literalNode, literalNode), "GreaterThanOrEqualNode"}, + {create(literalNode), "NegationNode"}, + {create(literalNode->name(), literalNode->name()), + "ComponentVariableNode"}, + {create(literalNode->name(), literalNode->name()), + "ComponentParameterNode"}, + {create(literalNode->name()), "ParameterNode"}, + {create(literalNode->name()), "VariableNode"}, + {create(literalNode->name(), literalNode->name()), "PortFieldNode"}}; + + for (auto [node, name]: nodes) + { + BOOST_CHECK_EQUAL(node->name(), name); + } +} + +BOOST_AUTO_TEST_SUITE_END() From 9accb36c6f8592b7effdff5c8cf72bbc33072bb6 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:56:17 +0200 Subject: [PATCH 116/127] Remove adequacy patch lmr [ANT-1933] (#2341) TODO: use warnings for removed parameters, only noticed used to avoid CI errors during dev --- docs/user-guide/04-migration-guides.md | 5 + docs/user-guide/solver/04-parameters.md | 20 --- src/libs/antares/exception/LoadingError.cpp | 5 - .../antares/exception/LoadingError.hpp | 6 - .../study/parameters/adq-patch-params.h | 24 +-- .../study/parameters/adq-patch-params.cpp | 52 ++---- src/solver/optimisation/CMakeLists.txt | 8 +- .../adq_patch_curtailment_sharing.cpp | 2 +- .../adequacy_patch_weekly_optimization.cpp | 78 -------- .../adq_patch_local_matching.cpp | 167 ------------------ .../optimisation/base_weekly_optimization.cpp | 78 -------- .../adequacy_patch_weekly_optimization.h | 51 ------ .../adq_patch_local_matching.h | 39 ---- .../optimisation/base_weekly_optimization.h | 61 ------- .../solver/optimisation/weekly_optimization.h | 28 +-- .../opt_gestion_des_bornes_cas_lineaire.cpp | 20 +-- .../optimisation/post_process_commands.cpp | 3 +- .../optimisation/weekly_optimization.cpp | 27 ++- src/solver/simulation/economy.cpp | 20 +-- .../simulation/adequacy_patch_runtime_data.h | 1 - .../antares/solver/simulation/economy.h | 5 +- .../adequacy_patch/adequacy_patch.cpp | 151 +--------------- .../adequacy-patch/adequacy-patch-options.cpp | 25 +-- 23 files changed, 76 insertions(+), 800 deletions(-) delete mode 100644 src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp delete mode 100644 src/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.cpp delete mode 100644 src/solver/optimisation/base_weekly_optimization.cpp delete mode 100644 src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h delete mode 100644 src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h delete mode 100644 src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 729818c28f..98047dace2 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -2,6 +2,11 @@ This is a list of all recent changes that came with new Antares Simulator features. The main goal of this document is to lower the costs of changing existing interfaces, both GUI and scripts. ## v9.2.0 +### Adequacy Patch LMR +Removed following properties from **settings/generaldata.ini**. +- enable-first-step +- set-to-null-ntc-between-physical-out-for-first-step + ### (TS-generator only) TS generation for link capacities In files input/links//properties.ini, add the following properties - tsgen_direct_XXX, diff --git a/docs/user-guide/solver/04-parameters.md b/docs/user-guide/solver/04-parameters.md index fc8492a9e4..5ca79193a0 100644 --- a/docs/user-guide/solver/04-parameters.md +++ b/docs/user-guide/solver/04-parameters.md @@ -503,16 +503,6 @@ These parameters are listed under the `[adequacy patch]` section in the `.ini` f inside adequacy patch (area type 2). NTC is set to null (if true) only in the first step of adequacy patch local matching rule. NTC from physical areas outside to physical areas inside adequacy patch (set to null / local values) ---- -#### set-to-null-ntc-between-physical-out-for-first-step -[//]: # (TODO: usage is not clear) -- **Expected value:** `true` or `false` -- **Required:** no -- **Default value:** `true` -- **Usage:** Transmission capacities between physical areas outside adequacy patch (area type 1). - NTC is set to null (if true) only in the first step of adequacy patch local matching rule. - NTC between physical areas outside adequacy patch (set to null / local values) - --- #### price-taking-order [//]: # (TODO: document this parameter) @@ -543,16 +533,6 @@ _**This section is under construction**_ - **Default value:** - **Usage:** Check CSR cost function value prior and after CSR (false / true) ---- -#### enable-first-step -[//]: # (TODO: document this parameter) -_**This section is under construction**_ - -- **Expected value:** -- **Required:** **yes** -- **Default value:** -- **Usage:** - --- #### threshold-initiate-curtailment-sharing-rule [//]: # (TODO: document this parameter) diff --git a/src/libs/antares/exception/LoadingError.cpp b/src/libs/antares/exception/LoadingError.cpp index 499f0ed3f6..4a80591bef 100644 --- a/src/libs/antares/exception/LoadingError.cpp +++ b/src/libs/antares/exception/LoadingError.cpp @@ -192,11 +192,6 @@ IncompatibleHurdleCostCSR::IncompatibleHurdleCostCSR(): { } -AdqPatchDisabledLMR::AdqPatchDisabledLMR(): - LoadingError("Incompatible options LMR disabled and priceTakingOrder equal Dens") -{ -} - IncompatibleOutputOptions::IncompatibleOutputOptions(const std::string& text): LoadingError(text) { diff --git a/src/libs/antares/exception/include/antares/exception/LoadingError.hpp b/src/libs/antares/exception/include/antares/exception/LoadingError.hpp index c79b1a791e..d70820e5e9 100644 --- a/src/libs/antares/exception/include/antares/exception/LoadingError.hpp +++ b/src/libs/antares/exception/include/antares/exception/LoadingError.hpp @@ -194,12 +194,6 @@ class IncompatibleHurdleCostCSR: public LoadingError IncompatibleHurdleCostCSR(); }; -class AdqPatchDisabledLMR: public LoadingError -{ -public: - AdqPatchDisabledLMR(); -}; - class IncompatibleOutputOptions: public LoadingError { public: diff --git a/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h b/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h index 25c8b0f79b..12935ca85f 100644 --- a/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h +++ b/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h @@ -78,25 +78,6 @@ enum class AdqPatchPTO }; // enum AdqPatchPTO -struct LocalMatching -{ - bool enabled = true; - //! Transmission capacities from physical areas outside adequacy patch (area type 1) to - //! physical areas inside adequacy patch (area type 2). NTC is set to null (if true) - //! only in the first step of adequacy patch local matching rule. - bool setToZeroOutsideInsideLinks = true; - //! Transmission capacities between physical areas outside adequacy patch (area type 1). - //! NTC is set to null (if true) only in the first step of adequacy patch local matching - //! rule. - bool setToZeroOutsideOutsideLinks = true; - /*! - ** \brief Reset to default values related to local matching - */ - void reset(); - bool updateFromKeyValue(const Yuni::String& key, const Yuni::String& value); - void addProperties(IniFile::Section* section) const; -}; - class CurtailmentSharing { public: @@ -127,7 +108,10 @@ class CurtailmentSharing struct AdqPatchParams { bool enabled; - LocalMatching localMatching; + //! Transmission capacities from physical areas outside adequacy patch (area type 1) to + //! physical areas inside adequacy patch (area type 2). NTC is set to null (if true) + //! only in the first step of adequacy patch local matching rule. + bool setToZeroOutsideInsideLinks = true; CurtailmentSharing curtailmentSharing; void reset(); diff --git a/src/libs/antares/study/parameters/adq-patch-params.cpp b/src/libs/antares/study/parameters/adq-patch-params.cpp index 99d0d0db33..44e86e16b3 100644 --- a/src/libs/antares/study/parameters/adq-patch-params.cpp +++ b/src/libs/antares/study/parameters/adq-patch-params.cpp @@ -31,38 +31,23 @@ namespace Antares::Data::AdequacyPatch // Local matching // ------------------- -void LocalMatching::reset() +static bool legacyLocalMatchingKeys(const Yuni::String& key) { - setToZeroOutsideInsideLinks = true; - setToZeroOutsideOutsideLinks = true; -} - -bool LocalMatching::updateFromKeyValue(const Yuni::String& key, const Yuni::String& value) -{ - if (key == "set-to-null-ntc-from-physical-out-to-physical-in-for-first-step") - { - return value.to(setToZeroOutsideInsideLinks); - } if (key == "set-to-null-ntc-between-physical-out-for-first-step") { - return value.to(setToZeroOutsideOutsideLinks); + logs.warning() << "Parameter set-to-null-ntc-between-physical-out-for-first-step not " + "supported with this solver version, use a version < 9.2"; + return true; } if (key == "enable-first-step") { - return value.to(enabled); + logs.warning() << "Parameter enable-first-step not supported with this solver version, use " + "a version < 9.2"; + return true; } return false; } -void LocalMatching::addProperties(IniFile::Section* section) const -{ - section->add("set-to-null-ntc-from-physical-out-to-physical-in-for-first-step", - setToZeroOutsideInsideLinks); - section->add("set-to-null-ntc-between-physical-out-for-first-step", - setToZeroOutsideOutsideLinks); - section->add("enable-first-step", enabled); -} - // ----------------------- // Curtailment sharing // ----------------------- @@ -141,7 +126,7 @@ bool CurtailmentSharing::updateFromKeyValue(const Yuni::String& key, const Yuni: return value.to(thresholdVarBoundsRelaxation); } - return false; + return legacyLocalMatchingKeys(key); } const char* PriceTakingOrderToString(AdequacyPatch::AdqPatchPTO pto) @@ -175,10 +160,8 @@ void CurtailmentSharing::addProperties(IniFile::Section* section) const // ------------------------ void AdqPatchParams::reset() { - enabled = false; - - localMatching.reset(); curtailmentSharing.reset(); + setToZeroOutsideInsideLinks = true; } void AdqPatchParams::addExcludedVariables(std::vector& out) const @@ -190,12 +173,6 @@ void AdqPatchParams::addExcludedVariables(std::vector& out) const out.emplace_back("SPIL. ENRG. CSR"); out.emplace_back("DTG MRG CSR"); } - - // If the adequacy patch is enabled, but the LMR is disabled, the DENS variable shouldn't exist - if (enabled && !localMatching.enabled) - { - out.emplace_back("DENS"); - } } bool AdqPatchParams::updateFromKeyValue(const Yuni::String& key, const Yuni::String& value) @@ -204,17 +181,20 @@ bool AdqPatchParams::updateFromKeyValue(const Yuni::String& key, const Yuni::Str { return value.to(enabled); } - - return curtailmentSharing.updateFromKeyValue(key, value) - != localMatching.updateFromKeyValue(key, value); // XOR + if (key == "set-to-null-ntc-from-physical-out-to-physical-in-for-first-step") + { + return value.to(setToZeroOutsideInsideLinks); + } + return curtailmentSharing.updateFromKeyValue(key, value); } void AdqPatchParams::saveToINI(IniFile& ini) const { auto* section = ini.addSection("adequacy patch"); section->add("include-adq-patch", enabled); + section->add("set-to-null-ntc-from-physical-out-to-physical-in-for-first-step", + setToZeroOutsideInsideLinks); - localMatching.addProperties(section); curtailmentSharing.addProperties(section); } diff --git a/src/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt index a6c6f01e66..c48f935757 100644 --- a/src/solver/optimisation/CMakeLists.txt +++ b/src/solver/optimisation/CMakeLists.txt @@ -38,10 +38,6 @@ set(RTESOLVER_OPT opt_nombre_min_groupes_demarres_couts_demarrage.cpp include/antares/solver/optimisation/opt_export_structure.h opt_export_structure.cpp - include/antares/solver/optimisation/base_weekly_optimization.h - base_weekly_optimization.cpp - include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h - adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp include/antares/solver/optimisation/weekly_optimization.h weekly_optimization.cpp include/antares/solver/optimisation/optim_post_process_list.h @@ -51,8 +47,6 @@ set(RTESOLVER_OPT include/antares/solver/optimisation/adequacy_patch_csr/hourly_csr_problem.h include/antares/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.h adequacy_patch_csr/adq_patch_post_process_list.cpp - include/antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h - adequacy_patch_local_matching/adq_patch_local_matching.cpp include/antares/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.h adequacy_patch_csr/adq_patch_curtailment_sharing.cpp adequacy_patch_csr/solve_problem.cpp @@ -209,4 +203,4 @@ target_include_directories(model_antares install(DIRECTORY include/antares DESTINATION "include" -) \ No newline at end of file +) diff --git a/src/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.cpp b/src/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.cpp index 63789a5c76..0aa61a969d 100644 --- a/src/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.cpp +++ b/src/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.cpp @@ -125,7 +125,7 @@ void HourlyCSRProblem::calculateCsrParameters() // calculate netPositionInit and the RHS of the AreaBalance constraints std::tie(netPositionInit, std::ignore, std::ignore) = calculateAreaFlowBalance( problemeHebdo_, - adqPatchParams_.localMatching.setToZeroOutsideInsideLinks, + adqPatchParams_.setToZeroOutsideInsideLinks, Area, hour); double ensInit = problemeHebdo_->ResultatsHoraires[Area] diff --git a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp deleted file mode 100644 index 8129d10845..0000000000 --- a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ - -#include "antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h" - -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/simulation/ISimulationObserver.h" -#include "antares/solver/simulation/adequacy_patch_runtime_data.h" -#include "antares/study/fwd.h" - -using namespace Antares::Data::AdequacyPatch; -using Antares::Constants::nbHoursInAWeek; - -namespace Antares::Solver::Optimization -{ -AdequacyPatchOptimization::AdequacyPatchOptimization(const Antares::Data::Study& study, - const OptimizationOptions& options, - PROBLEME_HEBDO* problemeHebdo, - AdqPatchParams& adqPatchParams, - uint thread_number, - IResultWriter& writer, - Simulation::ISimulationObserver& observer): - WeeklyOptimization(options, problemeHebdo, adqPatchParams, thread_number, writer, observer), - study_(study) -{ -} - -void AdequacyPatchOptimization::solve() -{ - Simulation::NullSimulationObserver nullSimulationObserver; - problemeHebdo_->adequacyPatchRuntimeData->AdequacyFirstStep = true; - OPT_OptimisationHebdomadaire(options_, - problemeHebdo_, - adqPatchParams_, - writer_, - nullSimulationObserver); - problemeHebdo_->adequacyPatchRuntimeData->AdequacyFirstStep = false; - - for (uint32_t pays = 0; pays < problemeHebdo_->NombreDePays; ++pays) - { - if (problemeHebdo_->adequacyPatchRuntimeData->areaMode[pays] - == Data::AdequacyPatch::physicalAreaInsideAdqPatch) - { - problemeHebdo_->ResultatsHoraires[pays].ValeursHorairesDENS - = problemeHebdo_->ResultatsHoraires[pays].ValeursHorairesDeDefaillancePositive; - } - else - { - std::ranges::fill(problemeHebdo_->ResultatsHoraires[pays].ValeursHorairesDENS, 0); - } - } - - OPT_OptimisationHebdomadaire(options_, - problemeHebdo_, - adqPatchParams_, - writer_, - nullSimulationObserver); -} - -} // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.cpp b/src/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.cpp deleted file mode 100644 index e61b843403..0000000000 --- a/src/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ - -#include "antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h" - -#include "antares/solver/simulation/adequacy_patch_runtime_data.h" - -namespace Antares::Data::AdequacyPatch -{ -/*! - * Determines restriction type for transmission links for first step of adequacy patch, when start - * node is inside adq path (type 2). - * - * @param ExtremityNodeAdequacyPatchType uint: The adq type of the node at the end of the link. - * - * @return uint from an enumeration that describes the type of restrictions to put on this link for - * adq purposes. - */ -static NtcSetToZeroStatus_AdqPatchStep1 SetNTCForAdequacyFirstStepOriginNodeInsideAdq( - AdequacyPatchMode ExtremityNodeAdequacyPatchType) -{ - switch (ExtremityNodeAdequacyPatchType) - { - case physicalAreaInsideAdqPatch: - case physicalAreaOutsideAdqPatch: - return NtcSetToZeroStatus_AdqPatchStep1::setToZero; - default: - return NtcSetToZeroStatus_AdqPatchStep1::leaveLocalValues; - } -} - -/*! - * Determines restriction type for transmission links for first step of adequacy patch, when start - * node is outside adq path (type 1). - * - * @param ExtremityNodeAdequacyPatchType uint: The adq type of the node at the end of the link. - * - * @param setToZeroNTCfromOutToIn_AdqPatch bool: Switch to cut links from nodes outside adq patch - * (type 1) towards nodes inside adq patch (type 2). - * - * @param setToZeroNTCfromOutToOut_AdqPatch bool: Switch to cut links between nodes outside adq - * patch (type 1). - * - * @return uint from an enumeration that describes the type of restrictions to put on this link for - * adq purposes. - */ -static NtcSetToZeroStatus_AdqPatchStep1 getNTCtoZeroStatusOriginNodeOutsideAdq( - AdequacyPatchMode ExtremityNodeAdequacyPatchType, - bool setToZeroNTCfromOutToIn_AdqPatch, - bool setToZeroNTCfromOutToOut_AdqPatch) -{ - switch (ExtremityNodeAdequacyPatchType) - { - case physicalAreaInsideAdqPatch: - return setToZeroNTCfromOutToIn_AdqPatch - ? NtcSetToZeroStatus_AdqPatchStep1::setToZero - : NtcSetToZeroStatus_AdqPatchStep1::setExtremityOriginToZero; - case physicalAreaOutsideAdqPatch: - return setToZeroNTCfromOutToOut_AdqPatch - ? NtcSetToZeroStatus_AdqPatchStep1::setToZero - : NtcSetToZeroStatus_AdqPatchStep1::leaveLocalValues; - default: - return NtcSetToZeroStatus_AdqPatchStep1::leaveLocalValues; - } -} - -/*! - * Determines restriction type for transmission links for first step of adequacy patch. - * - * @param problemeHebdo PROBLEME_HEBDO*: Weekly problem structure. - * - * @param Interco int: Index of the link. - * - * @return uint from an enumeration that describes the type of restrictions to put on this link for - * adq purposes. - */ -static NtcSetToZeroStatus_AdqPatchStep1 getNTCtoZeroStatus(PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams, - int Interco) -{ - AdequacyPatchMode OriginNodeAdequacyPatchType = problemeHebdo->adequacyPatchRuntimeData - ->originAreaMode[Interco]; - AdequacyPatchMode ExtremityNodeAdequacyPatchType = problemeHebdo->adequacyPatchRuntimeData - ->extremityAreaMode[Interco]; - bool setToZeroNTCfromOutToIn_AdqPatch = adqPatchParams.localMatching - .setToZeroOutsideInsideLinks; - bool setToZeroNTCfromOutToOut_AdqPatch = adqPatchParams.localMatching - .setToZeroOutsideOutsideLinks; - - switch (OriginNodeAdequacyPatchType) - { - case physicalAreaInsideAdqPatch: - return SetNTCForAdequacyFirstStepOriginNodeInsideAdq(ExtremityNodeAdequacyPatchType); - - case physicalAreaOutsideAdqPatch: - return getNTCtoZeroStatusOriginNodeOutsideAdq(ExtremityNodeAdequacyPatchType, - setToZeroNTCfromOutToIn_AdqPatch, - setToZeroNTCfromOutToOut_AdqPatch); - default: - return NtcSetToZeroStatus_AdqPatchStep1::leaveLocalValues; - } -} - -void setNTCbounds(double& Xmax, - double& Xmin, - const VALEURS_DE_NTC_ET_RESISTANCES& ValeursDeNTC, - const int Interco, - PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams) -{ - NtcSetToZeroStatus_AdqPatchStep1 ntcToZeroStatusForAdqPatch; - - // set as default values - Xmax = ValeursDeNTC.ValeurDeNTCOrigineVersExtremite[Interco]; - Xmin = -(ValeursDeNTC.ValeurDeNTCExtremiteVersOrigine[Interco]); - - // set for adq patch first step - if (adqPatchParams.enabled && adqPatchParams.localMatching.enabled - && problemeHebdo->adequacyPatchRuntimeData->AdequacyFirstStep) - { - ntcToZeroStatusForAdqPatch = getNTCtoZeroStatus(problemeHebdo, adqPatchParams, Interco); - - switch (ntcToZeroStatusForAdqPatch) - { - case NtcSetToZeroStatus_AdqPatchStep1::setToZero: - { - Xmax = 0.; - Xmin = 0.; - break; - } - case NtcSetToZeroStatus_AdqPatchStep1::setOriginExtremityToZero: - { - Xmax = 0.; - Xmin = -(ValeursDeNTC.ValeurDeNTCExtremiteVersOrigine[Interco]); - break; - } - case NtcSetToZeroStatus_AdqPatchStep1::setExtremityOriginToZero: - { - Xmax = ValeursDeNTC.ValeurDeNTCOrigineVersExtremite[Interco]; - Xmin = 0.; - break; - } - default: - return; - } - } -} - -} // namespace Antares::Data::AdequacyPatch diff --git a/src/solver/optimisation/base_weekly_optimization.cpp b/src/solver/optimisation/base_weekly_optimization.cpp deleted file mode 100644 index 623331485e..0000000000 --- a/src/solver/optimisation/base_weekly_optimization.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ - -#include "antares/solver/optimisation/base_weekly_optimization.h" - -#include - -#include "antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h" -#include "antares/solver/optimisation/weekly_optimization.h" - -using AdqPatchParams = Antares::Data::AdequacyPatch::AdqPatchParams; - -namespace Antares::Solver::Optimization -{ -WeeklyOptimization::WeeklyOptimization(const OptimizationOptions& options, - PROBLEME_HEBDO* problemesHebdo, - AdqPatchParams& adqPatchParams, - uint thread_number, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver): - options_(options), - problemeHebdo_(problemesHebdo), - adqPatchParams_(adqPatchParams), - thread_number_(thread_number), - writer_(writer), - simulationObserver_(simulationObserver) -{ -} - -std::unique_ptr WeeklyOptimization::create( - const Antares::Data::Study& study, - const OptimizationOptions& options, - AdqPatchParams& adqPatchParams, - PROBLEME_HEBDO* problemeHebdo, - uint thread_number, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver) -{ - if (adqPatchParams.enabled && adqPatchParams.localMatching.enabled) - { - return std::make_unique(study, - options, - problemeHebdo, - adqPatchParams, - thread_number, - writer, - simulationObserver); - } - else - { - return std::make_unique(options, - problemeHebdo, - adqPatchParams, - thread_number, - writer, - simulationObserver); - } -} - -} // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h b/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h deleted file mode 100644 index b11bdc817a..0000000000 --- a/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ - -#pragma once - -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/sim_structure_probleme_economique.h" -#include "antares/study/area/area.h" - -#include "../base_weekly_optimization.h" - -using Antares::Data::AreaList; - -namespace Antares::Solver::Optimization -{ -class AdequacyPatchOptimization: public WeeklyOptimization -{ -public: - explicit AdequacyPatchOptimization(const Antares::Data::Study& study, - const OptimizationOptions& options, - PROBLEME_HEBDO* problemeHebdo, - Data::AdequacyPatch::AdqPatchParams&, - uint numSpace, - IResultWriter& writer, - Simulation::ISimulationObserver& observer); - - ~AdequacyPatchOptimization() override = default; - void solve() override; - -private: - const Antares::Data::Study& study_; -}; -} // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h b/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h deleted file mode 100644 index eff8842d7b..0000000000 --- a/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -** Copyright 2007-2024, RTE (https://www.rte-france.com) -** See AUTHORS.txt -** SPDX-License-Identifier: MPL-2.0 -** This file is part of Antares-Simulator, -** Adequacy and Performance assessment for interconnected energy networks. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the Mozilla Public Licence 2.0 as published by -** the Mozilla Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** Antares_Simulator is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** Mozilla Public Licence 2.0 for more details. -** -** You should have received a copy of the Mozilla Public Licence 2.0 -** along with Antares_Simulator. If not, see . -*/ - -#pragma once - -#include "antares/solver/simulation/sim_structure_probleme_economique.h" - -namespace Antares::Data::AdequacyPatch -{ -/*! - * Sets link bounds for first step of adequacy patch or leaves default values if adequacy patch is - * not used. - */ -void setNTCbounds(double& Xmax, - double& Xmin, - const VALEURS_DE_NTC_ET_RESISTANCES& ValeursDeNTC, - const int Interco, - PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams); - -} // namespace Antares::Data::AdequacyPatch diff --git a/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h b/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h deleted file mode 100644 index acae5d8aed..0000000000 --- a/src/solver/optimisation/include/antares/solver/optimisation/base_weekly_optimization.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2007-2024, RTE (https://www.rte-france.com) - * See AUTHORS.txt - * SPDX-License-Identifier: MPL-2.0 - * This file is part of Antares-Simulator, - * Adequacy and Performance assessment for interconnected energy networks. - * - * Antares_Simulator is free software: you can redistribute it and/or modify - * it under the terms of the Mozilla Public Licence 2.0 as published by - * the Mozilla Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Antares_Simulator is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Mozilla Public Licence 2.0 for more details. - * - * You should have received a copy of the Mozilla Public Licence 2.0 - * along with Antares_Simulator. If not, see . - */ - -#pragma once - -#include // for "uint" definition - -#include -#include "antares/solver/simulation/ISimulationObserver.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/sim_structure_probleme_economique.h" - -namespace Antares::Solver::Optimization -{ -class WeeklyOptimization -{ -public: - virtual void solve() = 0; - virtual ~WeeklyOptimization() = default; - static std::unique_ptr create( - const Antares::Data::Study& study, - const OptimizationOptions& options, - Antares::Data::AdequacyPatch::AdqPatchParams& adqPatchParams, - PROBLEME_HEBDO* problemesHebdo, - uint numSpace, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver); - -protected: - explicit WeeklyOptimization(const OptimizationOptions& options, - PROBLEME_HEBDO* problemesHebdo, - Antares::Data::AdequacyPatch::AdqPatchParams&, - uint numSpace, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver); - Antares::Solver::Optimization::OptimizationOptions options_; - PROBLEME_HEBDO* const problemeHebdo_ = nullptr; - Antares::Data::AdequacyPatch::AdqPatchParams& adqPatchParams_; - const uint thread_number_ = 0; - IResultWriter& writer_; - std::reference_wrapper simulationObserver_; -}; -} // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h b/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h index 2206d35a25..c1f7774d5d 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/weekly_optimization.h @@ -24,20 +24,26 @@ #include "antares/solver/simulation/ISimulationObserver.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" -#include "base_weekly_optimization.h" - namespace Antares::Solver::Optimization { -class DefaultWeeklyOptimization: public WeeklyOptimization + +class WeeklyOptimization { public: - explicit DefaultWeeklyOptimization(const OptimizationOptions& options, - PROBLEME_HEBDO* problemeHebdo, - Antares::Data::AdequacyPatch::AdqPatchParams&, - uint numSpace, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver); - ~DefaultWeeklyOptimization() override = default; - void solve() override; + WeeklyOptimization(const OptimizationOptions& options, + PROBLEME_HEBDO* problemeHebdo, + Antares::Data::AdequacyPatch::AdqPatchParams&, + uint numSpace, + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver); + ~WeeklyOptimization() = default; + void solve(); + + Antares::Solver::Optimization::OptimizationOptions options_; + PROBLEME_HEBDO* const problemeHebdo_ = nullptr; + Antares::Data::AdequacyPatch::AdqPatchParams& adqPatchParams_; + const uint thread_number_ = 0; + IResultWriter& writer_; + std::reference_wrapper simulationObserver_; }; } // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp index 398af7b814..0cc9c93258 100644 --- a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp @@ -21,7 +21,6 @@ #include -#include "antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h" #include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" #include "antares/solver/simulation/adequacy_patch_runtime_data.h" @@ -133,17 +132,6 @@ void setBoundsForUnsuppliedEnergy(PROBLEME_HEBDO* problemeHebdo, Xmax[var] = 0.; } - // adq patch: update ENS <= DENS in 2nd run - if (adqPatchParams.enabled && adqPatchParams.localMatching.enabled - && !problemeHebdo->adequacyPatchRuntimeData->AdequacyFirstStep - && problemeHebdo->adequacyPatchRuntimeData->areaMode[pays] - == Data::AdequacyPatch::physicalAreaInsideAdqPatch) - { - Xmax[var] = std::min( - Xmax[var], - problemeHebdo->ResultatsHoraires[pays].ValeursHorairesDENS[pdtHebdo]); - } - problemeHebdo->ResultatsHoraires[pays].ValeursHorairesDeDefaillancePositive[pdtHebdo] = 0.0; @@ -249,12 +237,8 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob int var = variableManager.NTCDirect(interco, pdtJour); const COUTS_DE_TRANSPORT& CoutDeTransport = problemeHebdo->CoutDeTransport[interco]; - AdequacyPatch::setNTCbounds(Xmax[var], - Xmin[var], - ValeursDeNTC, - interco, - problemeHebdo, - adqPatchParams); + Xmax[var] = ValeursDeNTC.ValeurDeNTCOrigineVersExtremite[interco]; + Xmin[var] = -(ValeursDeNTC.ValeurDeNTCExtremiteVersOrigine[interco]); if (std::isinf(Xmax[var]) && Xmax[var] > 0) { diff --git a/src/solver/optimisation/post_process_commands.cpp b/src/solver/optimisation/post_process_commands.cpp index 3ced34ba4a..046c2cbb30 100644 --- a/src/solver/optimisation/post_process_commands.cpp +++ b/src/solver/optimisation/post_process_commands.cpp @@ -22,7 +22,6 @@ #include "antares/solver/optimisation/post_process_commands.h" #include "antares/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.h" -#include "antares/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h" #include "antares/solver/simulation/adequacy_patch_runtime_data.h" #include "antares/solver/simulation/common-eco-adq.h" @@ -261,7 +260,7 @@ double CurtailmentSharingPostProcessCmd::calculateDensNewAndTotalLmrViolation() { const auto [netPositionInit, densNew, totalNodeBalance] = calculateAreaFlowBalance( problemeHebdo_, - adqPatchParams_.localMatching.setToZeroOutsideInsideLinks, + adqPatchParams_.setToZeroOutsideInsideLinks, Area, hour); // adjust densNew according to the new specification/request by ELIA diff --git a/src/solver/optimisation/weekly_optimization.cpp b/src/solver/optimisation/weekly_optimization.cpp index 8f36d762d2..0cf6ec84cd 100644 --- a/src/solver/optimisation/weekly_optimization.cpp +++ b/src/solver/optimisation/weekly_optimization.cpp @@ -25,23 +25,22 @@ namespace Antares::Solver::Optimization { -DefaultWeeklyOptimization::DefaultWeeklyOptimization( - const OptimizationOptions& options, - PROBLEME_HEBDO* problemeHebdo, - AdqPatchParams& adqPatchParams, - uint thread_number, - IResultWriter& writer, - Simulation::ISimulationObserver& simulationObserver): - WeeklyOptimization(options, - problemeHebdo, - adqPatchParams, - thread_number, - writer, - simulationObserver) +WeeklyOptimization::WeeklyOptimization(const OptimizationOptions& options, + PROBLEME_HEBDO* problemeHebdo, + AdqPatchParams& adqPatchParams, + uint thread_number, + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver): + options_(options), + problemeHebdo_(problemeHebdo), + adqPatchParams_(adqPatchParams), + thread_number_(thread_number), + writer_(writer), + simulationObserver_(simulationObserver) { } -void DefaultWeeklyOptimization::solve() +void WeeklyOptimization::solve() { OPT_OptimisationHebdomadaire(options_, problemeHebdo_, diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 269fcd26ff..4499c339dc 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -71,7 +71,7 @@ bool Economy::simulationBegin() if (!preproOnly) { pProblemesHebdo.resize(pNbMaxPerformedYearsInParallel); - weeklyOptProblems_.resize(pNbMaxPerformedYearsInParallel); + weeklyOptProblems_.clear(); postProcessesList_.resize(pNbMaxPerformedYearsInParallel); for (uint numSpace = 0; numSpace < pNbMaxPerformedYearsInParallel; numSpace++) @@ -82,14 +82,14 @@ bool Economy::simulationBegin() numSpace); auto options = createOptimizationOptions(study); - weeklyOptProblems_[numSpace] = Antares::Solver::Optimization::WeeklyOptimization:: - create(study, - options, - study.parameters.adqPatchParams, - &pProblemesHebdo[numSpace], - numSpace, - resultWriter, - simulationObserver_.get()); + + weeklyOptProblems_.emplace_back(options, + &pProblemesHebdo[numSpace], + study.parameters.adqPatchParams, + numSpace, + resultWriter, + simulationObserver_.get()); + postProcessesList_[numSpace] = interfacePostProcessList::create( study.parameters.adqPatchParams, &pProblemesHebdo[numSpace], @@ -163,7 +163,7 @@ bool Economy::year(Progression::Task& progression, try { - weeklyOptProblems_[numSpace]->solve(); + weeklyOptProblems_[numSpace].solve(); // Runs all the post processes in the list of post-process commands optRuntimeData opt_runtime_data(state.year, w, hourInTheYear); diff --git a/src/solver/simulation/include/antares/solver/simulation/adequacy_patch_runtime_data.h b/src/solver/simulation/include/antares/solver/simulation/adequacy_patch_runtime_data.h index f91576a233..5ae0f3f5fb 100644 --- a/src/solver/simulation/include/antares/solver/simulation/adequacy_patch_runtime_data.h +++ b/src/solver/simulation/include/antares/solver/simulation/adequacy_patch_runtime_data.h @@ -42,7 +42,6 @@ class AdequacyPatchRuntimeData std::vector originAreaMode; std::vector extremityAreaMode; std::vector hurdleCostCoefficients; - bool AdequacyFirstStep = true; bool wasCSRTriggeredAtAreaHour(int area, int hour) const; void addCSRTriggeredAtAreaHour(int area, int hour); diff --git a/src/solver/simulation/include/antares/solver/simulation/economy.h b/src/solver/simulation/include/antares/solver/simulation/economy.h index 592fac59f8..0ff621e01a 100644 --- a/src/solver/simulation/include/antares/solver/simulation/economy.h +++ b/src/solver/simulation/include/antares/solver/simulation/economy.h @@ -22,7 +22,7 @@ #define __SOLVER_SIMULATION_ECONOMY_H__ #include "antares/infoCollection/StudyInfoCollector.h" -#include "antares/solver/optimisation/base_weekly_optimization.h" +#include "antares/solver/optimisation/weekly_optimization.h" #include "antares/solver/simulation/opt_time_writer.h" #include "antares/solver/simulation/solver.h" // for definition of type yearRandomNumbers #include "antares/solver/variable/economy/all.h" @@ -98,8 +98,7 @@ class Economy uint pStartTime; uint pNbMaxPerformedYearsInParallel; std::vector pProblemesHebdo; - std::vector> - weeklyOptProblems_; + std::vector weeklyOptProblems_; std::vector> postProcessesList_; IResultWriter& resultWriter; std::reference_wrapper simulationObserver_; diff --git a/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp b/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp index 377969fd5d..d4e722fd13 100644 --- a/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp +++ b/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp @@ -31,7 +31,6 @@ #include #include #include "antares/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.h" -#include "antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h" #include "antares/study/parameters/adq-patch-params.h" static double origineExtremite = -1; @@ -39,43 +38,6 @@ static double extremiteOrigine = 5; using namespace Antares::Data::AdequacyPatch; -// NOTE -// Xmax limits the flux origin -> extremity (direct) -// -Xmin limits the flux extremity -> origin (indirect) - -std::pair setNTCboundsForOneTimeStep(AdequacyPatchMode originType, - AdequacyPatchMode extremityType, - bool SetNTCOutsideToOutsideToZero, - bool SetNTCOutsideToInsideToZero) -{ - PROBLEME_HEBDO problem; - problem.adequacyPatchRuntimeData = std::make_shared(); - problem.adequacyPatchRuntimeData->originAreaMode.resize(1); - problem.adequacyPatchRuntimeData->extremityAreaMode.resize(1); - - problem.adequacyPatchRuntimeData->originAreaMode[0] = originType; - problem.adequacyPatchRuntimeData->extremityAreaMode[0] = extremityType; - problem.adequacyPatchRuntimeData->AdequacyFirstStep = true; - - AdqPatchParams adqPatchParams; - adqPatchParams.enabled = true; - adqPatchParams.localMatching.setToZeroOutsideOutsideLinks = SetNTCOutsideToOutsideToZero; - adqPatchParams.localMatching.setToZeroOutsideInsideLinks = SetNTCOutsideToInsideToZero; - - VALEURS_DE_NTC_ET_RESISTANCES ValeursDeNTC; - ValeursDeNTC.ValeurDeNTCOrigineVersExtremite.assign(1, 0.); - ValeursDeNTC.ValeurDeNTCExtremiteVersOrigine.assign(1, 0.); - ValeursDeNTC.ValeurDeNTCOrigineVersExtremite[0] = origineExtremite; - ValeursDeNTC.ValeurDeNTCExtremiteVersOrigine[0] = extremiteOrigine; - - double Xmin(0.); - double Xmax(0.); - - setNTCbounds(Xmax, Xmin, ValeursDeNTC, 0, &problem, adqPatchParams); - - return std::make_pair(Xmin, Xmax); -} - static const double flowArea0toArea1_positive = 10; static const double flowArea0toArea1_negative = -10; static const double flowArea2toArea0_positive = 30; @@ -111,8 +73,7 @@ std::pair calculateAreaFlowBalanceForOneTimeStep( problem.IndexDebutIntercoExtremite = std::vector(1); // input values - adqPatchParams.localMatching.setToZeroOutsideInsideLinks - = !includeFlowsOutsideAdqPatchToDensNew; + adqPatchParams.setToZeroOutsideInsideLinks = !includeFlowsOutsideAdqPatchToDensNew; problem.ResultatsHoraires[Area].ValeursHorairesDeDefaillancePositive[hour] = ensInit; int Interco = 1; problem.IndexDebutIntercoOrigine[Area] = Interco; @@ -131,7 +92,7 @@ std::pair calculateAreaFlowBalanceForOneTimeStep( double densNew; std::tie(netPositionInit, densNew, std::ignore) = calculateAreaFlowBalance( &problem, - adqPatchParams.localMatching.setToZeroOutsideInsideLinks, + adqPatchParams.setToZeroOutsideInsideLinks, Area, hour); @@ -143,119 +104,11 @@ AdqPatchParams createParams() AdqPatchParams p; p.enabled = true; p.curtailmentSharing.includeHurdleCost = true; - p.localMatching.enabled = true; p.curtailmentSharing.priceTakingOrder = AdqPatchPTO::isDens; return p; } -// Virtual -> Virtual (0 -> 0) -// No change in bounds is expected -BOOST_AUTO_TEST_CASE(setNTCboundsForOneTimeStep_virtual_virtual_no_change_expected) -{ - double Xmin, Xmax; - std::tie(Xmin, Xmax) = setNTCboundsForOneTimeStep(virtualArea, - virtualArea, - true /*SetNTCOutsideToOutsideToZero*/, - false); - BOOST_CHECK_EQUAL(Xmax, origineExtremite); - BOOST_CHECK_EQUAL(Xmin, -extremiteOrigine); -} - -// Virtual -> physical area inside adq-patch (0 -> 2) -// No change in bounds is expected -BOOST_AUTO_TEST_CASE(setNTCboundsForOneTimeStep_virtual_inside_no_change_expected) -{ - double Xmin, Xmax; - std::tie(Xmin, Xmax) = setNTCboundsForOneTimeStep(virtualArea, - physicalAreaInsideAdqPatch, - true /*SetNTCOutsideToOutsideToZero*/, - false); - BOOST_CHECK_EQUAL(Xmax, origineExtremite); - BOOST_CHECK_EQUAL(Xmin, -extremiteOrigine); -} - -// Virtual -> physical area outside adq-patch (0 -> 1) -// No change in bounds is expected -BOOST_AUTO_TEST_CASE(setNTCboundsForOneTimeStep_virtual_outside_no_change_expected) -{ - double Xmin, Xmax; - std::tie(Xmin, Xmax) = setNTCboundsForOneTimeStep(virtualArea, - physicalAreaOutsideAdqPatch, - true /*SetNTCOutsideToOutsideToZero*/, - false); - BOOST_CHECK_EQUAL(Xmax, origineExtremite); - BOOST_CHECK_EQUAL(Xmin, -extremiteOrigine); -} - -// physical area outside adq-patch -> physical area outside adq-patch (1 -> 1) -// NTC should be set to 0 in both directions -BOOST_AUTO_TEST_CASE(setNTCboundsForOneTimeStep_outside_outside_zero_expected_both_directions) -{ - double Xmin, Xmax; - std::tie(Xmin, Xmax) = setNTCboundsForOneTimeStep(physicalAreaOutsideAdqPatch, - physicalAreaOutsideAdqPatch, - true /*SetNTCOutsideToOutsideToZero*/, - false); - BOOST_CHECK_EQUAL(Xmax, 0); - BOOST_CHECK_EQUAL(Xmin, 0); -} - -// physical area outside adq-patch -> physical area outside adq-patch (1 -> 1) -// SetNTCOutsideToOutsideToZero = true -// NTC should be set to 0 in both directions -BOOST_AUTO_TEST_CASE(setNTCboundsForOneTimeStep_outside_outside_no_change_expected) -{ - double Xmin, Xmax; - std::tie(Xmin, Xmax) = setNTCboundsForOneTimeStep(physicalAreaOutsideAdqPatch, - physicalAreaOutsideAdqPatch, - false, - false); - - BOOST_CHECK_EQUAL(Xmax, origineExtremite); - BOOST_CHECK_EQUAL(Xmin, -extremiteOrigine); -} - -// physical area inside adq-patch -> physical area outside adq-patch (2 -> 1) -// NTC should be set to 0 in both directions -BOOST_AUTO_TEST_CASE(setNTCboundsForOneTimeStep_inside_outside_zero_expected_both_directions) -{ - double Xmin, Xmax; - std::tie(Xmin, Xmax) = setNTCboundsForOneTimeStep(physicalAreaInsideAdqPatch, - physicalAreaOutsideAdqPatch, - false, - false); - BOOST_CHECK_EQUAL(Xmax, 0); - BOOST_CHECK_EQUAL(Xmin, 0); -} - -// physical area outside adq-patch -> physical area inside adq-patch (1 -> 2) -// NTC should be set to 0 in both directions -BOOST_AUTO_TEST_CASE(setNTCboundsForOneTimeStep_outside_inside_zero_expected_both_directions) -{ - double Xmin, Xmax; - std::tie(Xmin, Xmax) = setNTCboundsForOneTimeStep(physicalAreaOutsideAdqPatch, - physicalAreaInsideAdqPatch, - false, - true /*SetNTCOutsideToInsideToZero*/); - BOOST_CHECK_EQUAL(Xmax, 0); - BOOST_CHECK_EQUAL(Xmin, 0); -} - -// physical area outside adq-patch -> physical area inside adq-patch (1 -> 2) -// NTC should be unchanged in direction origin->extremity (direct) -// NTC should be set to 0 in direction extremity->origin (indirect) -BOOST_AUTO_TEST_CASE(setNTCboundsForOneTimeStep_outside_inside_change_expected_one_direction) -{ - double Xmin, Xmax; - std::tie(Xmin, Xmax) = setNTCboundsForOneTimeStep(physicalAreaOutsideAdqPatch, - physicalAreaInsideAdqPatch, - false, - false); - BOOST_CHECK_EQUAL(Xmax, origineExtremite); - BOOST_CHECK_EQUAL(Xmin, 0); -} - // Area 0 is physical area inside adq-patch connected to two areas: // Area1 virtual-area, and Area2-virtual area // flow from Area0 -> Area1 is positive diff --git a/src/ui/simulator/windows/options/adequacy-patch/adequacy-patch-options.cpp b/src/ui/simulator/windows/options/adequacy-patch/adequacy-patch-options.cpp index 2368e68d13..d65d6ddbeb 100644 --- a/src/ui/simulator/windows/options/adequacy-patch/adequacy-patch-options.cpp +++ b/src/ui/simulator/windows/options/adequacy-patch/adequacy-patch-options.cpp @@ -165,29 +165,13 @@ AdequacyPatchOptions::AdequacyPatchOptions(wxWindow* parent) : button->menu(true); onPopup.bind(this, &AdequacyPatchOptions::onPopupMenuNTC, - PopupInfo(study.parameters.adqPatchParams.localMatching.setToZeroOutsideInsideLinks, + PopupInfo(study.parameters.adqPatchParams.setToZeroOutsideInsideLinks, wxT("NTC"))); button->onPopupMenu(onPopup); s->Add(label, 0, wxRIGHT | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); s->Add(button, 0, wxLEFT | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); pBtnNTCfromOutToInAdqPatch = button; } - // Transmission capacities (NTC) between physical areas outside adequacy patch (area type 1). - // Used in the first step of adequacy patch local matching rule. - { - label = Component::CreateLabel(this, wxT("NTC between physical areas outside adequacy patch")); - button = new Component::Button(this, wxT("Day"), "images/16x16/light_green.png"); - button->SetBackgroundColour(bgColor); - button->menu(true); - onPopup.bind(this, - &AdequacyPatchOptions::onPopupMenuNTC, - PopupInfo(study.parameters.adqPatchParams.localMatching.setToZeroOutsideOutsideLinks, - wxT("NTC"))); - button->onPopupMenu(onPopup); - s->Add(label, 0, wxRIGHT | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); - s->Add(button, 0, wxLEFT | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); - pBtnNTCfromOutToOutAdqPatch = button; - } // PTO (Price Taking Order). User can choose between DENS and Load { label = Component::CreateLabel(this, wxT("Price taking order")); @@ -360,12 +344,7 @@ void AdequacyPatchOptions::refresh() // adequacy patch (area type 2). Used in the first step of adequacy patch local matching rule. buttonType = "ntc"; updateButton(pBtnNTCfromOutToInAdqPatch, - study.parameters.adqPatchParams.localMatching.setToZeroOutsideInsideLinks, - buttonType); - // NTC between physical areas outside adequacy patch (area type 1). Used in the first step of - // adequacy patch local matching rule. - updateButton(pBtnNTCfromOutToOutAdqPatch, - study.parameters.adqPatchParams.localMatching.setToZeroOutsideOutsideLinks, + study.parameters.adqPatchParams.setToZeroOutsideInsideLinks, buttonType); // Price taking order (PTO) for adequacy patch buttonType = "pto"; From 69a8b123b0a0806563f7b5dcf3bcd6044da25da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jason=20Mar=C3=A9chal?= <45510813+JasonMarechal25@users.noreply.github.com> Date: Wed, 4 Sep 2024 09:39:35 +0200 Subject: [PATCH 117/127] Properly set common data in API output when using playlist (#2364) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Common data are only computed once. In the current implementation this computation is done only for the week 1 of the year 1. However when using playlist the year 1 may not exists This PR fix this issue by computing common data is no data exist yet. --------- Co-authored-by: Florian Omnès --- src/api/SimulationObserver.cpp | 19 ++++++++++--------- src/api/private/SimulationObserver.h | 3 ++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/api/SimulationObserver.cpp b/src/api/SimulationObserver.cpp index 7842ce8099..2291702082 100644 --- a/src/api/SimulationObserver.cpp +++ b/src/api/SimulationObserver.cpp @@ -31,12 +31,13 @@ namespace auto translate(const PROBLEME_HEBDO& problemeHebdo, std::string_view name, const Solver::HebdoProblemToLpsTranslator& translator, - const unsigned int year, - const unsigned int week) + std::once_flag& flag) { auto weekly_data = translator.translate(problemeHebdo.ProblemeAResoudre.get(), name); - Solver::ConstantDataFromAntares common_data; - if (year == 1 && week == 1) + std::optional common_data; + bool translateCommonData = false; + std::call_once(flag, [&translateCommonData]() { translateCommonData = true; }); + if (translateCommonData) { common_data = translator.commonProblemData(problemeHebdo.ProblemeAResoudre.get()); } @@ -56,18 +57,18 @@ void SimulationObserver::notifyHebdoProblem(const PROBLEME_HEBDO& problemeHebdo, const unsigned int year = problemeHebdo.year + 1; const unsigned int week = problemeHebdo.weekInTheYear + 1; // common_data and weekly_data computed before the mutex lock to prevent blocking the thread - auto [common_data, weekly_data] = translate(problemeHebdo, name, translator, year, week); - std::lock_guard lock(mutex_); - if (year == 1 && week == 1) + auto [common_data, weekly_data] = translate(problemeHebdo, name, translator, flag_); + std::lock_guard lock(lps_mutex_); + if (common_data) { - lps_.setConstantData(common_data); + lps_.setConstantData(common_data.value()); } lps_.addWeeklyData({year, week}, weekly_data); } Solver::LpsFromAntares&& SimulationObserver::acquireLps() noexcept { - std::lock_guard lock(mutex_); + std::lock_guard lock(lps_mutex_); return std::move(lps_); } } // namespace Antares::API diff --git a/src/api/private/SimulationObserver.h b/src/api/private/SimulationObserver.h index f2d78fc4eb..30a69b3bae 100644 --- a/src/api/private/SimulationObserver.h +++ b/src/api/private/SimulationObserver.h @@ -55,7 +55,8 @@ class SimulationObserver: public Solver::Simulation::ISimulationObserver private: Solver::LpsFromAntares lps_; - std::mutex mutex_; + mutable std::mutex lps_mutex_; + mutable std::once_flag flag_; }; } // namespace Antares::API From fcb52546bc567402e60c397d51ebd681d3bb4d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 4 Sep 2024 10:28:44 +0200 Subject: [PATCH 118/127] Adequacy patch CSR - revamp output variables [ANT-1932] (#2306) ### Variables - Remove Spilled CSR - Add DTG MRG CSR - Add UNSP. ENRG CSR ### Input parameters Remove flag "recompute-dtg-mrg" Make code mode testable by using functions. --------- Co-authored-by: Vincent Payet --- docs/user-guide/04-migration-guides.md | 5 +- docs/user-guide/solver/03-outputs.md | 7 +- .../study/parameters/adq-patch-params.h | 2 - .../study/parameters/adq-patch-params.cpp | 9 +-- src/solver/optimisation/CMakeLists.txt | 2 + .../adequacy_patch_csr/post_processing.cpp | 62 ++++++++++++++ .../set_variable_boundaries.cpp | 2 +- .../adequacy_patch_csr/post_processing.h | 29 +++++++ .../optimisation/post_process_commands.cpp | 45 ++++------- .../sim_structure_probleme_economique.h | 4 +- .../simulation/sim_alloc_probleme_hebdo.cpp | 4 +- src/solver/variable/CMakeLists.txt | 2 +- .../antares/solver/variable/economy/all.h | 80 +++++++++---------- ...dEnergyAfterCSR.h => unsupliedEnergyCsr.h} | 48 +++++------ .../adequacy_patch/adequacy_patch.cpp | 74 +++++++++++++++++ 15 files changed, 262 insertions(+), 113 deletions(-) create mode 100644 src/solver/optimisation/adequacy_patch_csr/post_processing.cpp create mode 100644 src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_csr/post_processing.h rename src/solver/variable/include/antares/solver/variable/economy/{spilledEnergyAfterCSR.h => unsupliedEnergyCsr.h} (87%) diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 98047dace2..eca0ef0fbe 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -28,6 +28,10 @@ with XXX in #### Short term storage: efficiency for withdrawal In input/st-storage/area/list.ini add property: `efficiencywithdrawal` [double] in range 0-1 +### Output +- Remove column SPIL ENRG CSR (adequacy patch) +- Add DTG MRG CSR and UNSP ENRG CSR variables + ## v9.1.0 ### Input #### Hydro Maximum Generation/Pumping Power @@ -198,7 +202,6 @@ In file **settings/generaldata.ini**, in section `adequacy patch`, add propertie * `price-taking-order` [string] can take values `DENS` (default value) and `Load`. * `include-hurdle-cost-csr` [bool]. Default value = `false` * `check-csr-cost-function` [bool]. Default value = `false` -* `recompute-dtg-mrg` [bool]. Default value = `false` * `threshold-initiate-curtailment-sharing-rule` [double]. Default value = `0.0` * `threshold-display-local-matching-rule-violations` [double]. Default value = `0.0` * `threshold-csr-variable-bounds-relaxation` [int]. Default value = `3` diff --git a/docs/user-guide/solver/03-outputs.md b/docs/user-guide/solver/03-outputs.md index cd79b2fdb4..367340cc3e 100644 --- a/docs/user-guide/solver/03-outputs.md +++ b/docs/user-guide/solver/03-outputs.md @@ -117,12 +117,13 @@ The area files that belong to the "values" class display fields corresponding to | SPIL. ENRG | Spilled energy (energy produced that cannot be used and has to be wasted) | | LOLD | Loss of load duration: adequacy indicator (length of shortfalls) | | LOLP | Loss of Load probability: adequacy indicator (probability of at least one hour of shortfall within the considered period, without normalization by the duration of the considered period) | -| AVL. DTG | Available dispatchable thermal generation (sum of av. power over all plants) | -| DTG. MRG | Disp. Ther. Gen. (AVL DTG – sum of all dispatched thermal generation) | +| AVL DTG | Available dispatchable thermal generation (sum of av. power over all plants) | +| DTG MRG | Disp. Ther. Gen. (AVL DTG – sum of all dispatched thermal generation) | | MAX. MRG | Maximum margin: operational margin obtained if the hydro storage energy of the week were used to maximise margins instead of minimizing costs | | DENS | Domestic Energy Not Supplied: the difference between the local production capabilities of an area and its local load[^adqp] | | LMR. VIOL | Local Matching Rule Violation after the Antares Simulation as defined by the adequacy patch[^adqp] | -| SPIL. ENRG. CSR | Spilled Energy after the Curtailment Sharing Rule step of the dequacy patch[^adqp] | +| UNSP. ENRG. CSR | Unsupplied enery after CSR (demand that cannot be satisfied)[^adqp] | +| DTG MRG CSR | DTG MRG after CSR[^adqp] | | _injection | Injection of energy from the area into each short-term storage group | | _withdrawal | Withdrawal of energy from each short-term storage group into the area | | _level | Average level of each short-term storage group | diff --git a/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h b/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h index 12935ca85f..53584a96d5 100644 --- a/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h +++ b/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h @@ -94,8 +94,6 @@ class CurtailmentSharing //! Check CSR cost function prior & after CSR optimization bool checkCsrCostFunction; - bool recomputeDTGMRG = false; - bool updateFromKeyValue(const Yuni::String& key, const Yuni::String& value); void addProperties(IniFile::Section* section) const; diff --git a/src/libs/antares/study/parameters/adq-patch-params.cpp b/src/libs/antares/study/parameters/adq-patch-params.cpp index 44e86e16b3..f0158b85e5 100644 --- a/src/libs/antares/study/parameters/adq-patch-params.cpp +++ b/src/libs/antares/study/parameters/adq-patch-params.cpp @@ -56,7 +56,6 @@ void CurtailmentSharing::reset() priceTakingOrder = AdqPatchPTO::isDens; includeHurdleCost = false; checkCsrCostFunction = false; - recomputeDTGMRG = false; resetThresholds(); } @@ -107,11 +106,6 @@ bool CurtailmentSharing::updateFromKeyValue(const Yuni::String& key, const Yuni: { return value.to(checkCsrCostFunction); } - if (key == "recompute-dtg-mrg") - { - return value.to(recomputeDTGMRG); - } - // Thresholds if (key == "threshold-initiate-curtailment-sharing-rule") { @@ -147,7 +141,6 @@ void CurtailmentSharing::addProperties(IniFile::Section* section) const section->add("price-taking-order", PriceTakingOrderToString(priceTakingOrder)); section->add("include-hurdle-cost-csr", includeHurdleCost); section->add("check-csr-cost-function", checkCsrCostFunction); - section->add("recompute-dtg-mrg", recomputeDTGMRG); // Thresholds section->add("threshold-initiate-curtailment-sharing-rule", thresholdRun); @@ -170,7 +163,7 @@ void AdqPatchParams::addExcludedVariables(std::vector& out) const { out.emplace_back("DENS"); out.emplace_back("LMR VIOL."); - out.emplace_back("SPIL. ENRG. CSR"); + out.emplace_back("UNSP. ENRG CSR"); out.emplace_back("DTG MRG CSR"); } } diff --git a/src/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt index c48f935757..a0d74288e7 100644 --- a/src/solver/optimisation/CMakeLists.txt +++ b/src/solver/optimisation/CMakeLists.txt @@ -46,7 +46,9 @@ set(RTESOLVER_OPT post_process_commands.cpp include/antares/solver/optimisation/adequacy_patch_csr/hourly_csr_problem.h include/antares/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.h + include/antares/solver/optimisation/adequacy_patch_csr/post_processing.h adequacy_patch_csr/adq_patch_post_process_list.cpp + adequacy_patch_csr/post_processing.cpp include/antares/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.h adequacy_patch_csr/adq_patch_curtailment_sharing.cpp adequacy_patch_csr/solve_problem.cpp diff --git a/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp b/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp new file mode 100644 index 0000000000..dea4c55efd --- /dev/null +++ b/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp @@ -0,0 +1,62 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ +#include "antares/solver/optimisation/adequacy_patch_csr/post_processing.h" + +#include + +namespace Antares::Data::AdequacyPatch +{ +double recomputeDTG_MRG(bool triggered, double dtgMrg, double ens) +{ + if (triggered) + { + return std::max(0.0, dtgMrg - ens); + } + else + { + return dtgMrg; + } +} + +double recomputeENS_MRG(bool triggered, double dtgMrg, double ens) +{ + if (triggered) + { + return std::max(0.0, ens - dtgMrg); + } + else + { + return ens; + } +} + +double recomputeMRGPrice(double ensCsr, double originalCost, double unsuppliedEnergyCost) +{ + if (ensCsr > 0.5) + { + return -unsuppliedEnergyCost; + } + else + { + return originalCost; + } +} +} // namespace Antares::Data::AdequacyPatch diff --git a/src/solver/optimisation/adequacy_patch_csr/set_variable_boundaries.cpp b/src/solver/optimisation/adequacy_patch_csr/set_variable_boundaries.cpp index 1ec76ca553..c59f4f71e7 100644 --- a/src/solver/optimisation/adequacy_patch_csr/set_variable_boundaries.cpp +++ b/src/solver/optimisation/adequacy_patch_csr/set_variable_boundaries.cpp @@ -77,7 +77,7 @@ void HourlyCSRProblem::setBoundsOnSpilledEnergy() .ValeursHorairesDeDefaillanceNegative[triggeredHour]; double* AdresseDuResultat = &(problemeHebdo_->ResultatsHoraires[area] - .ValeursHorairesSpilledEnergyAfterCSR[triggeredHour]); + .ValeursHorairesDeDefaillanceNegative[triggeredHour]); problemeAResoudre_.AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = AdresseDuResultat; diff --git a/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_csr/post_processing.h b/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_csr/post_processing.h new file mode 100644 index 0000000000..3ae5ee2d91 --- /dev/null +++ b/src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_csr/post_processing.h @@ -0,0 +1,29 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ + +#pragma once + +namespace Antares::Data::AdequacyPatch +{ +double recomputeDTG_MRG(bool triggered, double dtgMrg, double ens); +double recomputeENS_MRG(bool triggered, double dtgMrg, double ens); +double recomputeMRGPrice(double ensCsr, double originalCost, double unsuppliedEnergyCost); +} // namespace Antares::Data::AdequacyPatch diff --git a/src/solver/optimisation/post_process_commands.cpp b/src/solver/optimisation/post_process_commands.cpp index 046c2cbb30..fb628d694d 100644 --- a/src/solver/optimisation/post_process_commands.cpp +++ b/src/solver/optimisation/post_process_commands.cpp @@ -22,6 +22,7 @@ #include "antares/solver/optimisation/post_process_commands.h" #include "antares/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.h" +#include "antares/solver/optimisation/adequacy_patch_csr/post_processing.h" #include "antares/solver/simulation/adequacy_patch_runtime_data.h" #include "antares/solver/simulation/common-eco-adq.h" @@ -147,32 +148,23 @@ void DTGmarginForAdqPatchPostProcessCmd::execute(const optRuntimeData&) for (uint hour = 0; hour < nbHoursInWeek; hour++) { - // define access to the required variables + auto& hourlyResults = problemeHebdo_->ResultatsHoraires[Area]; const auto& scratchpad = area_list_[Area]->scratchpad[thread_number_]; - double dtgMrg = scratchpad.dispatchableGenerationMargin[hour]; + const double dtgMrg = scratchpad.dispatchableGenerationMargin[hour]; + const double ens = hourlyResults.ValeursHorairesDeDefaillancePositive[hour]; + const bool triggered = problemeHebdo_->adequacyPatchRuntimeData + ->wasCSRTriggeredAtAreaHour(Area, hour); + hourlyResults.ValeursHorairesDtgMrgCsr[hour] = recomputeDTG_MRG(triggered, dtgMrg, ens); + hourlyResults.ValeursHorairesDeDefaillancePositiveCSR[hour] = recomputeENS_MRG( + triggered, + dtgMrg, + ens); - auto& hourlyResults = problemeHebdo_->ResultatsHoraires[Area]; - double& dtgMrgCsr = hourlyResults.ValeursHorairesDtgMrgCsr[hour]; - double& ens = hourlyResults.ValeursHorairesDeDefaillancePositive[hour]; - double& mrgCost = hourlyResults.CoutsMarginauxHoraires[hour]; - // calculate DTG MRG CSR and adjust ENS if neccessary - if (problemeHebdo_->adequacyPatchRuntimeData->wasCSRTriggeredAtAreaHour(Area, hour)) - { - if (adqPatchParams_.curtailmentSharing.recomputeDTGMRG) - { - dtgMrgCsr = std::max(0.0, dtgMrg - ens); - ens = std::max(0.0, ens - dtgMrg); - } - // set MRG PRICE to value of unsupplied energy cost, if LOLD=1.0 (ENS>0.5) - if (ens > 0.5) - { - mrgCost = -area_list_[Area]->thermal.unsuppliedEnergyCost; - } - } - else - { - dtgMrgCsr = dtgMrg; - } + const double unsuppliedEnergyCost = area_list_[Area]->thermal.unsuppliedEnergyCost; + hourlyResults.CoutsMarginauxHoraires[hour] = recomputeMRGPrice( + hourlyResults.ValeursHorairesDtgMrgCsr[hour], + hourlyResults.CoutsMarginauxHoraires[hour], + unsuppliedEnergyCost); } } } @@ -272,11 +264,6 @@ double CurtailmentSharingPostProcessCmd::calculateDensNewAndTotalLmrViolation() problemeHebdo_->ResultatsHoraires[Area].ValeursHorairesDENS[hour] = std::max( 0.0, densNew); - ; - // copy spilled Energy values into spilled Energy values after CSR - problemeHebdo_->ResultatsHoraires[Area].ValeursHorairesSpilledEnergyAfterCSR[hour] - = problemeHebdo_->ResultatsHoraires[Area] - .ValeursHorairesDeDefaillanceNegative[hour]; // check LMR violations totalLmrViolation += LmrViolationAreaHour( problemeHebdo_, diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h index 7805218061..3c8e52f53b 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h @@ -412,10 +412,10 @@ struct PRODUCTION_THERMIQUE_OPTIMALE struct RESULTATS_HORAIRES { std::vector ValeursHorairesDeDefaillancePositive; + std::vector ValeursHorairesDeDefaillancePositiveCSR; std::vector ValeursHorairesDENS; // adq patch domestic unsupplied energy std::vector ValeursHorairesLmrViolations; // adq patch lmr violations - std::vector ValeursHorairesSpilledEnergyAfterCSR; // adq patch spillage after CSR - std::vector ValeursHorairesDtgMrgCsr; // adq patch DTG MRG after CSR + std::vector ValeursHorairesDtgMrgCsr; // adq patch DTG MRG after CSR std::vector ValeursHorairesDeDefaillanceNegative; diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index 936a8e5ac0..1499b502ea 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -365,12 +365,12 @@ void SIM_AllocateAreas(PROBLEME_HEBDO& problem, problem.ResultatsHoraires[k].ValeursHorairesDeDefaillancePositive.assign(NombreDePasDeTemps, 0.); + problem.ResultatsHoraires[k] + .ValeursHorairesDeDefaillancePositiveCSR.assign(NombreDePasDeTemps, 0.); problem.ResultatsHoraires[k].ValeursHorairesDENS.assign(NombreDePasDeTemps, 0.); // adq patch problem.ResultatsHoraires[k].ValeursHorairesLmrViolations.assign(NombreDePasDeTemps, 0); // adq patch - problem.ResultatsHoraires[k].ValeursHorairesSpilledEnergyAfterCSR.assign(NombreDePasDeTemps, - 0.); // adq patch problem.ResultatsHoraires[k].ValeursHorairesDtgMrgCsr.assign(NombreDePasDeTemps, 0.); // adq patch diff --git a/src/solver/variable/CMakeLists.txt b/src/solver/variable/CMakeLists.txt index 11ed4b5c9d..5022d5b542 100644 --- a/src/solver/variable/CMakeLists.txt +++ b/src/solver/variable/CMakeLists.txt @@ -98,9 +98,9 @@ set(SRC_VARIABLE_ECONOMY include/antares/solver/variable/economy/STStorageLevelsByCluster.h include/antares/solver/variable/economy/STStorageCashFlowByCluster.h include/antares/solver/variable/economy/unsupliedEnergy.h + include/antares/solver/variable/economy/unsupliedEnergyCsr.h include/antares/solver/variable/economy/domesticUnsuppliedEnergy.h include/antares/solver/variable/economy/localMatchingRuleViolations.h - include/antares/solver/variable/economy/spilledEnergyAfterCSR.h include/antares/solver/variable/economy/dtgMarginAfterCsr.h include/antares/solver/variable/economy/spilledEnergy.h include/antares/solver/variable/economy/dispatchableGeneration.h diff --git a/src/solver/variable/include/antares/solver/variable/economy/all.h b/src/solver/variable/include/antares/solver/variable/economy/all.h index b7a62eb6bf..8e1c2ed307 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/all.h +++ b/src/solver/variable/include/antares/solver/variable/economy/all.h @@ -60,9 +60,9 @@ #include "renewableGeneration.h" #include "reservoirlevel.h" #include "spilledEnergy.h" -#include "spilledEnergyAfterCSR.h" #include "thermalAirPollutantEmissions.h" #include "unsupliedEnergy.h" +#include "unsupliedEnergyCsr.h" #include "waterValue.h" // By thermal plant @@ -126,22 +126,24 @@ typedef // Prices >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> VariablesPerArea; /*! @@ -203,38 +205,36 @@ typedef // Prices LMRViolations, Common::SpatialAggregate< SpilledEnergy, + // LOLD Common::SpatialAggregate< - SpilledEnergyAfterCSR, - // LOLD + LOLD, Common::SpatialAggregate< - LOLD, + LOLP, Common::SpatialAggregate< - LOLP, + AvailableDispatchGen, Common::SpatialAggregate< - AvailableDispatchGen, + DispatchableGenMargin, Common::SpatialAggregate< - DispatchableGenMargin, + DtgMarginCsr, Common::SpatialAggregate< - DtgMarginCsr, + Marge, + + // Detail Prices Common::SpatialAggregate< - Marge, + NonProportionalCost, // MBO + // 13/05/2014 + // - + // refs: + // #21 - // Detail Prices + // Number Of Dispatched Units Common::SpatialAggregate< - NonProportionalCost, // MBO - // 13/05/2014 - // - - // refs: - // #21 - - // Number Of Dispatched Units - Common::SpatialAggregate< - NbOfDispatchedUnits // MBO - // 25/02/2016 - // - - // refs: - // #55 - >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + NbOfDispatchedUnits // MBO + // 25/02/2016 + // - + // refs: + // #55 + >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> VariablesPerSetOfAreas; typedef BindingConstMarginCost< // Marginal cost for a binding constraint diff --git a/src/solver/variable/include/antares/solver/variable/economy/spilledEnergyAfterCSR.h b/src/solver/variable/include/antares/solver/variable/economy/unsupliedEnergyCsr.h similarity index 87% rename from src/solver/variable/include/antares/solver/variable/economy/spilledEnergyAfterCSR.h rename to src/solver/variable/include/antares/solver/variable/economy/unsupliedEnergyCsr.h index 9881775f78..e4a989de2c 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/spilledEnergyAfterCSR.h +++ b/src/solver/variable/include/antares/solver/variable/economy/unsupliedEnergyCsr.h @@ -18,19 +18,24 @@ ** You should have received a copy of the Mozilla Public Licence 2.0 ** along with Antares_Simulator. If not, see . */ -#ifndef __SOLVER_VARIABLE_ECONOMY_SpilledEnergyAfterCSR_H__ -#define __SOLVER_VARIABLE_ECONOMY_SpilledEnergyAfterCSR_H__ +#pragma once #include "antares/solver/variable/variable.h" -namespace Antares::Solver::Variable::Economy +namespace Antares { -struct VCardSpilledEnergyAfterCSR +namespace Solver +{ +namespace Variable +{ +namespace Economy +{ +struct VCardUnsupliedEnergyCSR { //! Caption static std::string Caption() { - return "SPIL. ENRG. CSR"; + return "UNSP. ENRG CSR"; } //! Unit @@ -42,8 +47,7 @@ struct VCardSpilledEnergyAfterCSR //! The short description of the variable static std::string Description() { - return "Spilled Energy After CSR Optimization (generation that cannot be satisfied) " - "after CSR optimization"; + return "Unsuplied Energy after CSR (demand that cannot be satisfied)"; } //! The expecte results @@ -55,7 +59,7 @@ struct VCardSpilledEnergyAfterCSR ResultsType; //! The VCard to look for for calculating spatial aggregates - typedef VCardSpilledEnergyAfterCSR VCardForSpatialAggregate; + typedef VCardUnsupliedEnergyCSR VCardForSpatialAggregate; //! Data Level static constexpr uint8_t categoryDataLevel = Category::DataLevel::area; @@ -87,21 +91,17 @@ struct VCardSpilledEnergyAfterCSR }; // class VCard -/*! -** \brief C02 Average value of the overrall SpilledEnergyAfterCSR emissions expected from all -** the thermal dispatchable clusters -*/ template -class SpilledEnergyAfterCSR - : public Variable::IVariable, NextT, VCardSpilledEnergyAfterCSR> +class UnsupliedEnergyCSR + : public Variable::IVariable, NextT, VCardUnsupliedEnergyCSR> { public: //! Type of the next static variable typedef NextT NextType; //! VCard - typedef VCardSpilledEnergyAfterCSR VCardType; + typedef VCardUnsupliedEnergyCSR VCardType; //! Ancestor - typedef Variable::IVariable, NextT, VCardType> AncestorType; + typedef Variable::IVariable, NextT, VCardType> AncestorType; //! List of expected results typedef typename VCardType::ResultsType ResultsType; @@ -127,7 +127,8 @@ class SpilledEnergyAfterCSR }; }; - ~SpilledEnergyAfterCSR() +public: + ~UnsupliedEnergyCSR() { delete[] pValuesForTheCurrentYear; } @@ -228,10 +229,8 @@ class SpilledEnergyAfterCSR void hourForEachArea(State& state, unsigned int numSpace) { - // Total SpilledEnergyAfterCSR emissions pValuesForTheCurrentYear[numSpace][state.hourInTheYear] - = state.hourlyResults->ValeursHorairesSpilledEnergyAfterCSR[state.hourInTheWeek]; - + = state.hourlyResults->ValeursHorairesDeDefaillancePositiveCSR[state.hourInTheWeek]; // Next variable NextType::hourForEachArea(state, numSpace); } @@ -266,8 +265,9 @@ class SpilledEnergyAfterCSR typename VCardType::IntermediateValuesType pValuesForTheCurrentYear; unsigned int pNbYearsParallel; -}; // class SpilledEnergyAfterCSR - -} // namespace Antares::Solver::Variable::Economy +}; // class UnsupliedEnergyCSR -#endif // __SOLVER_VARIABLE_ECONOMY_SpilledEnergyAfterCSR_H__ +} // namespace Economy +} // namespace Variable +} // namespace Solver +} // namespace Antares diff --git a/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp b/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp index d4e722fd13..ea9762838b 100644 --- a/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp +++ b/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp @@ -31,12 +31,14 @@ #include #include #include "antares/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.h" +#include "antares/solver/optimisation/adequacy_patch_csr/post_processing.h" #include "antares/study/parameters/adq-patch-params.h" static double origineExtremite = -1; static double extremiteOrigine = 5; using namespace Antares::Data::AdequacyPatch; +namespace tt = boost::test_tools; static const double flowArea0toArea1_positive = 10; static const double flowArea0toArea1_negative = -10; @@ -400,3 +402,75 @@ BOOST_AUTO_TEST_CASE(check_adq_param_wrong_hurdle_cost) auto p = createParams(); BOOST_CHECK_THROW(p.checkAdqPatchIncludeHurdleCost(false), Error::IncompatibleHurdleCostCSR); } + +BOOST_AUTO_TEST_SUITE(adq_patch_post_processing) + +BOOST_AUTO_TEST_CASE(dtg_mrg_triggered_low_ens) +{ + const bool triggered = true; + const double dtgMrg = 32.; + const double ens = 21.; + + BOOST_TEST(recomputeDTG_MRG(triggered, dtgMrg, ens) == 11., tt::tolerance(1.e-6)); + + BOOST_TEST(recomputeDTG_MRG(triggered, dtgMrg, ens) + recomputeENS_MRG(triggered, dtgMrg, ens) + == std::abs(dtgMrg - ens), + tt::tolerance(1.e-6)); +} + +BOOST_AUTO_TEST_CASE(dtg_mrg_triggered_high_ens) +{ + const bool triggered = true; + const double dtgMrg = 32.; + const double ens = 42.; + + BOOST_TEST(recomputeDTG_MRG(triggered, dtgMrg, ens) == 0., tt::tolerance(1.e-6)); + + BOOST_TEST(recomputeDTG_MRG(triggered, dtgMrg, ens) + recomputeENS_MRG(triggered, dtgMrg, ens) + == std::abs(dtgMrg - ens), + tt::tolerance(1.e-6)); +} + +BOOST_AUTO_TEST_CASE(dtg_mrg_not_triggered_low_ens) +{ + const bool triggered = false; + const double dtgMrg = 32.; + const double ens = 21.; + + BOOST_TEST(recomputeDTG_MRG(triggered, dtgMrg, ens) == dtgMrg, tt::tolerance(1.e-6)); + BOOST_TEST(recomputeDTG_MRG(triggered, dtgMrg, ens) + recomputeENS_MRG(triggered, dtgMrg, ens) + == dtgMrg + ens, + tt::tolerance(1.e-6)); +} + +BOOST_AUTO_TEST_CASE(dtg_mrg_not_triggered_high_ens) +{ + const bool triggered = false; + const double dtgMrg = 32.; + const double ens = 42.; + + BOOST_TEST(recomputeDTG_MRG(triggered, dtgMrg, ens) == dtgMrg, tt::tolerance(1.e-6)); + BOOST_TEST(recomputeDTG_MRG(triggered, dtgMrg, ens) + recomputeENS_MRG(triggered, dtgMrg, ens) + == dtgMrg + ens, + tt::tolerance(1.e-6)); +} + +BOOST_AUTO_TEST_CASE(mrgprice_high_enscsr) +{ + const double ensCsr = 21.; + const double originalCost = 3.; + const double unsuppliedEnergyCost = 1000.; + BOOST_TEST(recomputeMRGPrice(ensCsr, originalCost, unsuppliedEnergyCost) + == -unsuppliedEnergyCost, + tt::tolerance(1.e-6)); +} + +BOOST_AUTO_TEST_CASE(mrgprice_low_enscsr) +{ + const double ensCsr = 0.; + const double originalCost = 3.; + const double unsuppliedEnergyCost = 1000.; + BOOST_TEST(recomputeMRGPrice(ensCsr, originalCost, unsuppliedEnergyCost) == originalCost, + tt::tolerance(1.e-6)); +} +BOOST_AUTO_TEST_SUITE_END() From 236169952fcb716e5aca953c7fc7f2261585ccf5 Mon Sep 17 00:00:00 2001 From: Peter Mitri Date: Wed, 4 Sep 2024 11:46:55 +0200 Subject: [PATCH 119/127] Add help button to website (#2368) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add help button to website that would create an issue (with a new template) --------- Co-authored-by: Florian Omnès --- .github/ISSUE_TEMPLATE/support_request.md | 14 ++++++++++++++ mkdocs.yml | 1 + 2 files changed, 15 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/support_request.md diff --git a/.github/ISSUE_TEMPLATE/support_request.md b/.github/ISSUE_TEMPLATE/support_request.md new file mode 100644 index 0000000000..9760b940dc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support_request.md @@ -0,0 +1,14 @@ +--- +name: Request for support +about: Ask any question +title: '' +labels: help wanted + +--- + +**Your identity** +Your name, company, why you are interested in Antares-Simulator... +Any information that can help us understand the context of your request! + +**Question** +Your question, remark... \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 23187934c1..cf71684518 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -84,6 +84,7 @@ nav: - 'Antares ecosystem': 'https://antares-doc.readthedocs.io' - 'Antares website': 'https://antares-simulator.org' - 'RTE website': 'http://www.rte-france.com/' + - 'Contact': 'https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues/new?template=support_request.md' plugins: From 27b22dd553eb6ca5b247cadadefbfec8a3b199b9 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 4 Sep 2024 11:54:53 +0200 Subject: [PATCH 120/127] Fix windows build (#2373) --- src/CMakeLists.txt | 2 +- src/solver/optimisation/adequacy_patch_csr/post_processing.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ae280dcc01..54e0de87d2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,7 @@ set(ANTARES_VERSION_REVISION 0) # Beta release set(ANTARES_BETA 0) -set(ANTARES_RC 1) +set(ANTARES_RC 3) set(ANTARES_VERSION_YEAR 2024) diff --git a/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp b/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp index dea4c55efd..a656c50072 100644 --- a/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp +++ b/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp @@ -20,6 +20,7 @@ */ #include "antares/solver/optimisation/adequacy_patch_csr/post_processing.h" +#include #include namespace Antares::Data::AdequacyPatch From 3f2be185c26d3b702193a7415e568a36070f41fd Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:58:18 +0200 Subject: [PATCH 121/127] Bump simtest version (#2375) Co-authored-by: Florian OMNES <26088210+flomnes@users.noreply.github.com> --- simtest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simtest.json b/simtest.json index d27fde74c1..c1478f4703 100644 --- a/simtest.json +++ b/simtest.json @@ -1,3 +1,3 @@ { - "version": "v9.2.0c" + "version": "v9.2.0d" } From 600c6ac456058487fa9b181eca68410f8abc1b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 4 Sep 2024 15:37:03 +0200 Subject: [PATCH 122/127] Remove unused headers in src/solver (yuni, cstdint, sim_*.h) (#2371) --- .../antares/solver/constraints-builder/grid.h | 4 ---- src/solver/hydro/management/daily.cpp | 1 - src/solver/hydro/management/management.cpp | 3 --- .../adequacy_patch_csr/post_processing.cpp | 1 - src/solver/simulation/TimeSeriesNumbersWriter.cpp | 1 - .../antares/solver/simulation/common-eco-adq.h | 3 --- .../simulation/sim_extern_variables_globales.h | 13 ++----------- .../simulation/sim_structure_probleme_economique.h | 1 - .../include/antares/solver/simulation/solver.data.h | 2 -- .../include/antares/solver/simulation/solver.h | 1 - .../include/antares/solver/simulation/solver.hxx | 3 --- .../antares/solver/simulation/solver_utils.h | 6 +----- .../antares/solver/simulation/timeseries-numbers.h | 2 -- src/solver/simulation/sim_alloc_probleme_hebdo.cpp | 2 -- src/solver/simulation/sim_allocation_tableaux.cpp | 2 -- src/solver/simulation/sim_variables_globales.cpp | 3 +-- src/solver/simulation/solver_utils.cpp | 1 - src/solver/ts-generator/hydro.cpp | 1 + 18 files changed, 5 insertions(+), 45 deletions(-) diff --git a/src/solver/constraints-builder/include/antares/solver/constraints-builder/grid.h b/src/solver/constraints-builder/include/antares/solver/constraints-builder/grid.h index 3f69322359..a29f27eee8 100644 --- a/src/solver/constraints-builder/include/antares/solver/constraints-builder/grid.h +++ b/src/solver/constraints-builder/include/antares/solver/constraints-builder/grid.h @@ -28,10 +28,6 @@ #include -// #include -// #include -// #include - namespace Antares { namespace Graph diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index 254ab2b1b2..d7a2aab668 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 0ad4d4a357..a43dd3161f 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -23,9 +23,6 @@ #include #include -#include - -#include #include #include diff --git a/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp b/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp index a656c50072..bc946a3c57 100644 --- a/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp +++ b/src/solver/optimisation/adequacy_patch_csr/post_processing.cpp @@ -21,7 +21,6 @@ #include "antares/solver/optimisation/adequacy_patch_csr/post_processing.h" #include -#include namespace Antares::Data::AdequacyPatch { diff --git a/src/solver/simulation/TimeSeriesNumbersWriter.cpp b/src/solver/simulation/TimeSeriesNumbersWriter.cpp index 31016bbc49..09122c32e0 100644 --- a/src/solver/simulation/TimeSeriesNumbersWriter.cpp +++ b/src/solver/simulation/TimeSeriesNumbersWriter.cpp @@ -22,7 +22,6 @@ // Created by marechaljas on 17/03/23. // -#include #include #include diff --git a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h index 1139bb9ff9..6a4dabd763 100644 --- a/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h +++ b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h @@ -23,9 +23,6 @@ #include -#include -#include - #include #include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/simulation/solver.h" // for definition of type yearRandomNumbers diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_extern_variables_globales.h b/src/solver/simulation/include/antares/solver/simulation/sim_extern_variables_globales.h index d6c526b37e..cfcc9ff1e6 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_extern_variables_globales.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_extern_variables_globales.h @@ -18,17 +18,8 @@ * You should have received a copy of the Mozilla Public Licence 2.0 * along with Antares_Simulator. If not, see . */ -#ifndef __SOLVER_SIMULATION_EXTERN_H__ -#define __SOLVER_SIMULATION_EXTERN_H__ +#pragma once -#include "antares/solver/simulation/sim_structure_probleme_economique.h" +#include -#include "sim_structure_donnees.h" - -/* Valeurs generees de maniere aleatoire */ - -/* Resultats */ -/*-Economique-*/ extern std::vector> transitMoyenInterconnexionsRecalculQuadratique; - -#endif /* __SOLVER_SIMULATION_EXTERN_H__ */ diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h index 3c8e52f53b..11d1ea116a 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h @@ -23,7 +23,6 @@ #define __SOLVER_SIMULATION_ECO_STRUCTS_H__ #include -#include #include #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.data.h b/src/solver/simulation/include/antares/solver/simulation/solver.data.h index 16de52d570..bb30ec4173 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.data.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver.data.h @@ -21,8 +21,6 @@ #ifndef __SOLVER_SIMULATION_SOLVER_DATA_H__ #define __SOLVER_SIMULATION_SOLVER_DATA_H__ -#include - #include namespace Antares::Solver::Private::Simulation diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.h b/src/solver/simulation/include/antares/solver/simulation/solver.h index 6dc6f85eb8..4ea45461d8 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver.h @@ -21,7 +21,6 @@ #ifndef __SOLVER_SIMULATION_SOLVER_H__ #define __SOLVER_SIMULATION_SOLVER_H__ -#include #include #include diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 539c1d298e..c8ca4775df 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -21,12 +21,9 @@ #ifndef __SOLVER_SIMULATION_SOLVER_HXX__ #define __SOLVER_SIMULATION_SOLVER_HXX__ -#include #include -#include #include -#include #include #include #include diff --git a/src/solver/simulation/include/antares/solver/simulation/solver_utils.h b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h index f7129c6a35..a920ef1f47 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver_utils.h +++ b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h @@ -21,14 +21,10 @@ #ifndef __SOLVER_SIMULATION_SOLVER_UTILS_H__ #define __SOLVER_SIMULATION_SOLVER_UTILS_H__ -#include // For setprecision -#include // For std numeric_limits +#include // For std numeric_limits #include -#include // For ostringstream #include -#include - #include #include diff --git a/src/solver/simulation/include/antares/solver/simulation/timeseries-numbers.h b/src/solver/simulation/include/antares/solver/simulation/timeseries-numbers.h index 2b087b65e6..47fae11d45 100644 --- a/src/solver/simulation/include/antares/solver/simulation/timeseries-numbers.h +++ b/src/solver/simulation/include/antares/solver/simulation/timeseries-numbers.h @@ -23,8 +23,6 @@ #include -#include - #include #include "ITimeSeriesNumbersWriter.h" diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index 1499b502ea..305d5fb31b 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -20,8 +20,6 @@ */ #include "antares/solver/simulation/sim_alloc_probleme_hebdo.h" -#include - #include #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" #include "antares/solver/simulation/sim_extern_variables_globales.h" diff --git a/src/solver/simulation/sim_allocation_tableaux.cpp b/src/solver/simulation/sim_allocation_tableaux.cpp index ef788dfedd..ebb711804d 100644 --- a/src/solver/simulation/sim_allocation_tableaux.cpp +++ b/src/solver/simulation/sim_allocation_tableaux.cpp @@ -19,8 +19,6 @@ ** along with Antares_Simulator. If not, see . */ -#include - #include #include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/study/simulation.h" diff --git a/src/solver/simulation/sim_variables_globales.cpp b/src/solver/simulation/sim_variables_globales.cpp index 252c937631..1fdcc04fa3 100644 --- a/src/solver/simulation/sim_variables_globales.cpp +++ b/src/solver/simulation/sim_variables_globales.cpp @@ -19,7 +19,6 @@ ** along with Antares_Simulator. If not, see . */ -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/sim_structure_probleme_economique.h" +#include std::vector> transitMoyenInterconnexionsRecalculQuadratique; diff --git a/src/solver/simulation/solver_utils.cpp b/src/solver/simulation/solver_utils.cpp index 936957a224..76f5fc0ce3 100644 --- a/src/solver/simulation/solver_utils.cpp +++ b/src/solver/simulation/solver_utils.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #define SEP Yuni::IO::Separator diff --git a/src/solver/ts-generator/hydro.cpp b/src/solver/ts-generator/hydro.cpp index ccf61f9466..6f5fd8dfc7 100644 --- a/src/solver/ts-generator/hydro.cpp +++ b/src/solver/ts-generator/hydro.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include "antares/solver/misc/cholesky.h" From 2791e30f1303f036ffd84cec352c8b6cad7f977d Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:10:11 +0200 Subject: [PATCH 123/127] Centos mirror list (#2372) Using a updated mirror list for centos CI following depreciation --- .github/workflows/centos7.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index 4d7700e203..cc0ae0b8a0 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -43,6 +43,17 @@ jobs: - name: Install gcc 10 run: | + # update mirrors, official centos7 is deprecated + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo &&\ + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo &&\ + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo &&\ + yum update -y + + # not a typo, centos-release-scl is needed to install devtoolset-10 but introduce deprecated mirror + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo &&\ + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo &&\ + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo + yum install -y centos-release-scl yum install -y devtoolset-11-gcc* From 8fc1599304264b7eb473c021fb850492f8cc7a3f Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:39:17 +0200 Subject: [PATCH 124/127] Better dependencies with cmake, antares matrix (#2369) --- src/libs/antares/array/CMakeLists.txt | 4 ++-- src/libs/antares/array/include/antares/array/matrix.h | 2 -- src/libs/antares/series/CMakeLists.txt | 4 ++-- src/libs/antares/series/include/antares/series/series.h | 2 +- src/libs/antares/series/series.cpp | 4 +++- src/libs/antares/study/CMakeLists.txt | 1 + src/libs/antares/study/include/antares/study/xcast/xcast.h | 1 + src/tests/src/libs/antares/study/series/CMakeLists.txt | 1 + 8 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libs/antares/array/CMakeLists.txt b/src/libs/antares/array/CMakeLists.txt index e2a7e48bf5..bfa3f2e4f8 100644 --- a/src/libs/antares/array/CMakeLists.txt +++ b/src/libs/antares/array/CMakeLists.txt @@ -15,7 +15,7 @@ target_link_libraries(array io #matrix.hxx jit #jit.hxx require logs Antares::memory - Antares::study + Antares::utils ) target_include_directories(array @@ -25,4 +25,4 @@ target_include_directories(array install(DIRECTORY include/antares DESTINATION "include" -) \ No newline at end of file +) diff --git a/src/libs/antares/array/include/antares/array/matrix.h b/src/libs/antares/array/include/antares/array/matrix.h index 48eb27dd6f..42432a0ae1 100644 --- a/src/libs/antares/array/include/antares/array/matrix.h +++ b/src/libs/antares/array/include/antares/array/matrix.h @@ -28,9 +28,7 @@ #include #include -#include "antares/antares/antares.h" #include "antares/jit/jit.h" -#include "antares/study/fwd.h" namespace Antares { diff --git a/src/libs/antares/series/CMakeLists.txt b/src/libs/antares/series/CMakeLists.txt index 5f9da57ab2..570680f4cf 100644 --- a/src/libs/antares/series/CMakeLists.txt +++ b/src/libs/antares/series/CMakeLists.txt @@ -11,7 +11,7 @@ target_sources(series $ ) -target_link_libraries(series PUBLIC Antares::array) +target_link_libraries(series PUBLIC Antares::array antares-core) target_include_directories(series PUBLIC @@ -20,4 +20,4 @@ target_include_directories(series install(DIRECTORY include/antares DESTINATION "include" -) \ No newline at end of file +) diff --git a/src/libs/antares/series/include/antares/series/series.h b/src/libs/antares/series/include/antares/series/series.h index d3dde6d092..939b25e40d 100644 --- a/src/libs/antares/series/include/antares/series/series.h +++ b/src/libs/antares/series/include/antares/series/series.h @@ -83,7 +83,7 @@ class TimeSeries ** \param prefix the prefix for the filename ** \return A non-zero value if the operation succeeded, 0 otherwise */ - int saveToFolder(const AreaName& areaID, + int saveToFolder(const std::string& areaID, const std::string& folder, const std::string& prefix) const; diff --git a/src/libs/antares/series/series.cpp b/src/libs/antares/series/series.cpp index 9116a5b5da..03894a9c50 100644 --- a/src/libs/antares/series/series.cpp +++ b/src/libs/antares/series/series.cpp @@ -29,6 +29,8 @@ #include #include +#include + using namespace Yuni; #define SEP IO::Separator @@ -129,7 +131,7 @@ bool TimeSeries::loadFromFile(const std::string& path, const bool average) return ret; } -int TimeSeries::saveToFolder(const AreaName& areaID, +int TimeSeries::saveToFolder(const std::string& areaID, const std::string& folder, const std::string& prefix) const { diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index bc06a77089..a3524a4b96 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -293,6 +293,7 @@ target_link_libraries(study Antares::mersenne Antares::result_writer #study.h Antares::series + Antares::array antares-core antares-solver-simulation Antares::hydro diff --git a/src/libs/antares/study/include/antares/study/xcast/xcast.h b/src/libs/antares/study/include/antares/study/xcast/xcast.h index e331287881..cc7e281763 100644 --- a/src/libs/antares/study/include/antares/study/xcast/xcast.h +++ b/src/libs/antares/study/include/antares/study/xcast/xcast.h @@ -27,6 +27,7 @@ #include #include +#include namespace Antares::Data { diff --git a/src/tests/src/libs/antares/study/series/CMakeLists.txt b/src/tests/src/libs/antares/study/series/CMakeLists.txt index f525878822..27c31d1728 100644 --- a/src/tests/src/libs/antares/study/series/CMakeLists.txt +++ b/src/tests/src/libs/antares/study/series/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(timeseries-tests ${SRC_TIMESERIES_TESTS}) target_link_libraries(timeseries-tests PRIVATE + Antares::array Boost::unit_test_framework Antares::series antares-solver-simulation From cda5d427f5a8a43f7ed8919af89e9f4a5e5e7ec1 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:52:51 +0200 Subject: [PATCH 125/127] Update deprecated actions (#2381) --- .github/workflows/centos7.yml | 16 +++------------- .github/workflows/oracle8.yml | 9 ++++----- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index cc0ae0b8a0..330df8e719 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -100,8 +100,8 @@ jobs: if: ${{ env.IS_RELEASE == 'true' }} run: | wget https://github.com/cli/cli/releases/download/v2.52.0/gh_2.52.0_linux_amd64.rpm - rpm -i gh_2.52.0_linux_amd64.rpm - gh --version + rpm -i gh_2.52.0_linux_amd64.rpm + gh --version - name: Configure run: | @@ -146,16 +146,6 @@ jobs: cd _build cpack -G TGZ - - name: Installer TGZ push - uses: actions/upload-artifact@v3 - with: - path: _build/*.tar.gz - - - name: Installer RPM push - uses: actions/upload-artifact@v3 - with: - path: _build/*.rpm - - name: Publish assets if: ${{ env.IS_RELEASE == 'true' }} env: @@ -163,7 +153,7 @@ jobs: tag: ${{ github.event.inputs.release_tag }} run: | gh release upload "$tag" _build/*.tar.gz _build/*.rpm - + - name: Cache vcpkg binary dir if: always() id: save-cache-vcpkg-binary diff --git a/.github/workflows/oracle8.yml b/.github/workflows/oracle8.yml index 93485068c9..e026b4246a 100644 --- a/.github/workflows/oracle8.yml +++ b/.github/workflows/oracle8.yml @@ -64,8 +64,7 @@ jobs: - name: Restore vcpkg binary dir from cache id: cache-vcpkg-binary - # Note: we are stuck with v3, because v4 is not compatible with oracle8 image - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: ${{ env.VCPKG_CACHE_DIR }} key: vcpkg-cache-oracle8-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} @@ -144,13 +143,13 @@ jobs: - name: Installer TGZ push uses: actions/upload-artifact@v4 with: - name: targz + name: oracle-targz path: _build/*.tar.gz - name: Installer RPM push uses: actions/upload-artifact@v4 with: - name: rpm + name: oracle-rpm path: _build/*.rpm - name: Publish assets @@ -164,7 +163,7 @@ jobs: - name: Cache vcpkg binary dir if: always() id: save-cache-vcpkg-binary - uses: actions/cache/save@v3 + uses: actions/cache/save@v4 with: path: ${{ env.VCPKG_CACHE_DIR }} key: vcpkg-cache-oracle8-${{ hashFiles('src/vcpkg.json', '.git/modules/vcpkg/HEAD') }} From 24256a17b2fa0b161ea07c9039f7253be5cbcd66 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Tue, 10 Sep 2024 14:02:57 +0200 Subject: [PATCH 126/127] Modeler API [ANT-1876] (#2286) --- src/solver/CMakeLists.txt | 4 +- src/solver/modeler/CMakeLists.txt | 2 + src/solver/modeler/api/CMakeLists.txt | 27 ++ .../antares/solver/modeler/api/hasBounds.h | 42 +++ .../antares/solver/modeler/api/hasName.h | 37 +++ .../solver/modeler/api/linearProblem.h | 71 ++++++ .../solver/modeler/api/linearProblemBuilder.h | 40 +++ .../solver/modeler/api/linearProblemData.h | 47 ++++ .../solver/modeler/api/linearProblemFiller.h | 38 +++ .../solver/modeler/api/mipConstraint.h | 37 +++ .../antares/solver/modeler/api/mipSolution.h | 56 ++++ .../antares/solver/modeler/api/mipVariable.h | 34 +++ src/solver/modeler/api/linearProblemData.cpp | 53 ++++ src/solver/modeler/ortoolsImpl/CMakeLists.txt | 35 +++ .../modeler/ortoolsImpl/linearProblem.h | 77 ++++++ .../modeler/ortoolsImpl/mipConstraint.h | 58 +++++ .../solver/modeler/ortoolsImpl/mipSolution.h | 54 ++++ .../solver/modeler/ortoolsImpl/mipVariable.h | 57 +++++ .../modeler/ortoolsImpl/linearProblem.cpp | 178 +++++++++++++ .../modeler/ortoolsImpl/mipConstraint.cpp | 90 +++++++ .../modeler/ortoolsImpl/mipSolution.cpp | 96 +++++++ .../modeler/ortoolsImpl/mipVariable.cpp | 69 +++++ src/tests/src/solver/CMakeLists.txt | 1 + src/tests/src/solver/modeler/CMakeLists.txt | 1 + .../src/solver/modeler/api/CMakeLists.txt | 20 ++ .../api/testApiOrtoolsLinearProblem.cpp | 239 ++++++++++++++++++ 26 files changed, 1462 insertions(+), 1 deletion(-) create mode 100644 src/solver/modeler/CMakeLists.txt create mode 100644 src/solver/modeler/api/CMakeLists.txt create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/hasBounds.h create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/hasName.h create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemBuilder.h create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemData.h create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemFiller.h create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/mipConstraint.h create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h create mode 100644 src/solver/modeler/api/include/antares/solver/modeler/api/mipVariable.h create mode 100644 src/solver/modeler/api/linearProblemData.cpp create mode 100644 src/solver/modeler/ortoolsImpl/CMakeLists.txt create mode 100644 src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h create mode 100644 src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipConstraint.h create mode 100644 src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h create mode 100644 src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipVariable.h create mode 100644 src/solver/modeler/ortoolsImpl/linearProblem.cpp create mode 100644 src/solver/modeler/ortoolsImpl/mipConstraint.cpp create mode 100644 src/solver/modeler/ortoolsImpl/mipSolution.cpp create mode 100644 src/solver/modeler/ortoolsImpl/mipVariable.cpp create mode 100644 src/tests/src/solver/modeler/CMakeLists.txt create mode 100644 src/tests/src/solver/modeler/api/CMakeLists.txt create mode 100644 src/tests/src/solver/modeler/api/testApiOrtoolsLinearProblem.cpp diff --git a/src/solver/CMakeLists.txt b/src/solver/CMakeLists.txt index 632affa433..37d0f4c003 100644 --- a/src/solver/CMakeLists.txt +++ b/src/solver/CMakeLists.txt @@ -19,7 +19,9 @@ add_subdirectory(simulation) add_subdirectory(ts-generator) add_subdirectory(utils) add_subdirectory(variable) +add_subdirectory(modeler) add_subdirectory(expressions) + # # Resource file for Windows # @@ -113,4 +115,4 @@ INSTALL(EXPORT antares-solver ) -######### \ No newline at end of file +######### diff --git a/src/solver/modeler/CMakeLists.txt b/src/solver/modeler/CMakeLists.txt new file mode 100644 index 0000000000..3c631240ac --- /dev/null +++ b/src/solver/modeler/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(api) +add_subdirectory(ortoolsImpl) diff --git a/src/solver/modeler/api/CMakeLists.txt b/src/solver/modeler/api/CMakeLists.txt new file mode 100644 index 0000000000..049c2dfa8e --- /dev/null +++ b/src/solver/modeler/api/CMakeLists.txt @@ -0,0 +1,27 @@ +set(PROJ optim_api) + +set(SRC_API + include/antares/solver/modeler/api/mipVariable.h + include/antares/solver/modeler/api/mipSolution.h + include/antares/solver/modeler/api/mipConstraint.h + + include/antares/solver/modeler/api/hasBounds.h + include/antares/solver/modeler/api/hasName.h + + include/antares/solver/modeler/api/linearProblem.h + include/antares/solver/modeler/api/linearProblemData.h + include/antares/solver/modeler/api/linearProblemFiller.h + include/antares/solver/modeler/api/linearProblemBuilder.h + + linearProblemData.cpp +) + +add_library(${PROJ} ${SRC_API}) +add_library(Antares::${PROJ} ALIAS ${PROJ}) + +set_target_properties(${PROJ} PROPERTIES LINKER_LANGUAGE CXX) + +target_include_directories(${PROJ} + PUBLIC + $ +) diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/hasBounds.h b/src/solver/modeler/api/include/antares/solver/modeler/api/hasBounds.h new file mode 100644 index 0000000000..474a34d74f --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/hasBounds.h @@ -0,0 +1,42 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +namespace Antares::Solver::Modeler::Api +{ + +/// Used to handle bounds for IMipVariable and IMipConstraint +class IHasBounds +{ +public: + virtual ~IHasBounds() = default; + + virtual void setLb(double lb) = 0; + virtual void setUb(double ub) = 0; + + virtual void setBounds(double lb, double ub) = 0; + + virtual double getLb() const = 0; + virtual double getUb() const = 0; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/hasName.h b/src/solver/modeler/api/include/antares/solver/modeler/api/hasName.h new file mode 100644 index 0000000000..0003dd6843 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/hasName.h @@ -0,0 +1,37 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include + +namespace Antares::Solver::Modeler::Api +{ + +/// Inherited by IMipVariable and IMipConstraint +class IHasName +{ +public: + virtual ~IHasName() = default; + virtual const std::string& getName() const = 0; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h new file mode 100644 index 0000000000..b997242ec7 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h @@ -0,0 +1,71 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include +#include + +#include "mipConstraint.h" +#include "mipSolution.h" +#include "mipVariable.h" + +/// Namespace for the classes related to the linear problem API +namespace Antares::Solver::Modeler::Api +{ + +/** + * Linear Problem + * This class is aimed at creating and manipulating variables/constraints + * Also used to to control the objective, maximization or minimization, and to solve the problem + */ +class ILinearProblem +{ +public: + virtual ~ILinearProblem() = default; + + /// Create a continuous variable + virtual IMipVariable* addNumVariable(double lb, double ub, const std::string& name) = 0; + /// Create a integer variable + virtual IMipVariable* addIntVariable(double lb, double ub, const std::string& name) = 0; + virtual IMipVariable* getVariable(const std::string& name) const = 0; + + /// Add a bounded constraint to the problem + virtual IMipConstraint* addConstraint(double lb, double ub, const std::string& name) = 0; + virtual IMipConstraint* getConstraint(const std::string& name) const = 0; + + /// Set the objective coefficient for a given variable + virtual void setObjectiveCoefficient(IMipVariable* var, double coefficient) = 0; + virtual double getObjectiveCoefficient(const IMipVariable* var) const = 0; + + /// Sets the optimization direction to minimize + virtual void setMinimization() = 0; + /// Sets the optimization direction to maximize + virtual void setMaximization() = 0; + + virtual bool isMinimization() const = 0; + virtual bool isMaximization() const = 0; + + /// Solve the problem, returns a IMipSolution + virtual IMipSolution* solve(bool verboseSolver) = 0; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemBuilder.h b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemBuilder.h new file mode 100644 index 0000000000..b4131d4f6b --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemBuilder.h @@ -0,0 +1,40 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include + +#include "linearProblemFiller.h" +#include "mipSolution.h" + +namespace Antares::Solver::Modeler::Api +{ + +class LinearProblemBuilder +{ +public: + virtual void LinearProblemBuilder(std::vector fillers) = 0; + virtual void build(LinearProblemData* data) = 0; + virtual MipSolution* solve() = 0; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemData.h b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemData.h new file mode 100644 index 0000000000..ff3cd2a4e3 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemData.h @@ -0,0 +1,47 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include +#include +#include + +namespace Antares::Solver::Modeler::Api +{ + +class LinearProblemData +{ +public: + unsigned getTimeResolutionInMinutes(); + bool hasScalarData(const std::string& key); + double getScalarData(const std::string& key, unsigned scenario); + bool hasTimedData(const std::string& key); + const std::vector& getTimedData(const std::string& key, unsigned scenario); + +private: + std::vector timeStamps_; + unsigned timeResolutionInMinutes_; + std::map> scalarData_; + std::map>> timedData_; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemFiller.h b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemFiller.h new file mode 100644 index 0000000000..b337dea247 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemFiller.h @@ -0,0 +1,38 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include +#include + +namespace Antares::Solver::Modeler::Api +{ + +class LinearProblemFiller +{ +public: + virtual void addVariables(LinearProblem* problem, LinearProblemData* data) = 0; + virtual void addConstraints(LinearProblem* problem, LinearProblemData* data) = 0; + virtual void addObjectiveCoefficients(LinearProblem* problem, LinearProblemData* data) = 0; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/mipConstraint.h b/src/solver/modeler/api/include/antares/solver/modeler/api/mipConstraint.h new file mode 100644 index 0000000000..71baf95cd8 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/mipConstraint.h @@ -0,0 +1,37 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include "mipVariable.h" + +namespace Antares::Solver::Modeler::Api +{ + +class IMipConstraint: public IHasBounds, public IHasName +{ +public: + virtual void setCoefficient(IMipVariable* var, double coefficient) = 0; + + virtual double getCoefficient(IMipVariable* var) = 0; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h b/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h new file mode 100644 index 0000000000..0018718de2 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/mipSolution.h @@ -0,0 +1,56 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include + +#include "mipVariable.h" + +namespace Antares::Solver::Modeler::Api +{ + +enum class MipStatus +{ + OPTIMAL, + FEASIBLE, + UNBOUNDED, + INFEASIBLE, + MIP_ERROR +}; + +/** + * MipSolution + * Used to get the return status of the solve + * Contains the problem's optimal values for each variable + */ +class IMipSolution +{ +public: + virtual ~IMipSolution() = default; + + virtual MipStatus getStatus() const = 0; + virtual double getObjectiveValue() const = 0; + virtual double getOptimalValue(const IMipVariable* var) const = 0; + virtual std::vector getOptimalValues(const std::vector& vars) const = 0; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/include/antares/solver/modeler/api/mipVariable.h b/src/solver/modeler/api/include/antares/solver/modeler/api/mipVariable.h new file mode 100644 index 0000000000..1caac002bf --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/mipVariable.h @@ -0,0 +1,34 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include "hasBounds.h" +#include "hasName.h" + +namespace Antares::Solver::Modeler::Api +{ + +class IMipVariable: public IHasBounds, public IHasName +{ +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/linearProblemData.cpp b/src/solver/modeler/api/linearProblemData.cpp new file mode 100644 index 0000000000..27cf9415c9 --- /dev/null +++ b/src/solver/modeler/api/linearProblemData.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include + +namespace Antares::Solver::Modeler::Api +{ + +unsigned LinearProblemData::getTimeResolutionInMinutes() +{ + return timeResolutionInMinutes_; +} + +bool LinearProblemData::hasScalarData(const std::string& key) +{ + return scalarData_.contains(key); +} + +double LinearProblemData::getScalarData(const std::string& key, unsigned scenario) +{ + return scalarData_.at(key)[scenario]; +} + +bool LinearProblemData::hasTimedData(const std::string& key) +{ + return timedData_.contains(key); +} + +const std::vector& LinearProblemData::getTimedData(const std::string& key, + unsigned scenario) +{ + return timedData_.at(key)[scenario]; +} + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/ortoolsImpl/CMakeLists.txt b/src/solver/modeler/ortoolsImpl/CMakeLists.txt new file mode 100644 index 0000000000..ef94b552cc --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/CMakeLists.txt @@ -0,0 +1,35 @@ +set(PROJ modeler-ortools-impl) + +set(HEADERS + include/antares/solver/modeler/ortoolsImpl/mipVariable.h + include/antares/solver/modeler/ortoolsImpl/mipSolution.h + include/antares/solver/modeler/ortoolsImpl/mipConstraint.h + + include/antares/solver/modeler/ortoolsImpl/linearProblem.h +) +set(SRC_ORTOOLS_IMPL + ${HEADERS} + mipVariable.cpp + mipSolution.cpp + mipConstraint.cpp + + linearProblem.cpp +) + +source_group("solver\\modeler\\api" FILES ${SRC_ORTOOLS_IMPL}) + +add_library(${PROJ} ${SRC_ORTOOLS_IMPL}) +add_library(Antares::${PROJ} ALIAS ${PROJ}) + +target_link_libraries(${PROJ} + PUBLIC + Antares::optim_api + Antares::logs + Antares::solverUtils + ortools::ortools +) + +target_include_directories(${PROJ} + PUBLIC + $ +) diff --git a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h new file mode 100644 index 0000000000..6a34ccfcc5 --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h @@ -0,0 +1,77 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include +#include +#include +#include + +namespace operations_research +{ +class MPSolver; +class MPSolverParameters; +class MPObjective; +} // namespace operations_research + +namespace Antares::Solver::Modeler::OrtoolsImpl +{ + +class OrtoolsLinearProblem final: public Api::ILinearProblem +{ +public: + OrtoolsLinearProblem(bool isMip, const std::string& solverName); + ~OrtoolsLinearProblem() override = default; + + OrtoolsMipVariable* addNumVariable(double lb, double ub, const std::string& name) override; + OrtoolsMipVariable* addIntVariable(double lb, double ub, const std::string& name) override; + + OrtoolsMipVariable* getVariable(const std::string& name) const override; + + OrtoolsMipConstraint* addConstraint(double lb, double ub, const std::string& name) override; + OrtoolsMipConstraint* getConstraint(const std::string& name) const override; + + void setObjectiveCoefficient(Api::IMipVariable* var, double coefficient) override; + double getObjectiveCoefficient(const Api::IMipVariable* var) const override; + + void setMinimization() override; + void setMaximization() override; + + bool isMinimization() const override; + bool isMaximization() const override; + + OrtoolsMipSolution* solve(bool verboseSolver) override; + +private: + OrtoolsMipVariable* addVariable(double lb, double ub, bool integer, const std::string& name); + + std::shared_ptr mpSolver_; + operations_research::MPObjective* objective_; + operations_research::MPSolverParameters params_; + + std::map> variables_; + std::map> constraints_; + + std::unique_ptr solution_; +}; + +} // namespace Antares::Solver::Modeler::OrtoolsImpl diff --git a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipConstraint.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipConstraint.h new file mode 100644 index 0000000000..cf5b501f60 --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipConstraint.h @@ -0,0 +1,58 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include + +namespace operations_research +{ +class MPConstraint; // forward declaration +} + +namespace Antares::Solver::Modeler::OrtoolsImpl +{ + +class OrtoolsMipConstraint final: public Api::IMipConstraint +{ +public: + void setLb(double lb) override; + void setUb(double ub) override; + + void setBounds(double lb, double ub) override; + void setCoefficient(Api::IMipVariable* var, double coefficient) override; + + double getLb() const override; + double getUb() const override; + + double getCoefficient(Api::IMipVariable* var) override; + + const std::string& getName() const override; + + ~OrtoolsMipConstraint() override = default; + + explicit OrtoolsMipConstraint(operations_research::MPConstraint* mpConstraint); + +private: + operations_research::MPConstraint* mpConstraint_; +}; + +} // namespace Antares::Solver::Modeler::OrtoolsImpl diff --git a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h new file mode 100644 index 0000000000..c046c49ef6 --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipSolution.h @@ -0,0 +1,54 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace Antares::Solver::Modeler::OrtoolsImpl +{ + +class OrtoolsMipSolution final: public Api::IMipSolution +{ +public: + OrtoolsMipSolution(operations_research::MPSolver::ResultStatus& responseStatus, + std::shared_ptr solver); + + ~OrtoolsMipSolution() override = default; + + Api::MipStatus getStatus() const override; + double getObjectiveValue() const override; + double getOptimalValue(const Api::IMipVariable* var) const override; + std::vector getOptimalValues( + const std::vector& vars) const override; + +private: + operations_research::MPSolver::ResultStatus status_; + std::shared_ptr mpSolver_; + std::map solution_; +}; + +} // namespace Antares::Solver::Modeler::OrtoolsImpl diff --git a/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipVariable.h b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipVariable.h new file mode 100644 index 0000000000..528ee0cd9e --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/mipVariable.h @@ -0,0 +1,57 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once + +#include + +namespace operations_research +{ +class MPVariable; // forward declaration +} + +namespace Antares::Solver::Modeler::OrtoolsImpl +{ + +class OrtoolsMipVariable final: public Api::IMipVariable +{ +public: + void setLb(double lb) override; + void setUb(double ub) override; + + void setBounds(double lb, double ub) override; + + double getLb() const override; + double getUb() const override; + + const std::string& getName() const override; + + const operations_research::MPVariable* getMpVar() const; + + ~OrtoolsMipVariable() override = default; + + explicit OrtoolsMipVariable(operations_research::MPVariable*); + +private: + operations_research::MPVariable* mpVar_; +}; + +} // namespace Antares::Solver::Modeler::OrtoolsImpl diff --git a/src/solver/modeler/ortoolsImpl/linearProblem.cpp b/src/solver/modeler/ortoolsImpl/linearProblem.cpp new file mode 100644 index 0000000000..7c6593fa52 --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/linearProblem.cpp @@ -0,0 +1,178 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include +#include +#include + +#include +#include + +namespace Antares::Solver::Modeler::OrtoolsImpl +{ + +OrtoolsLinearProblem::OrtoolsLinearProblem(bool isMip, const std::string& solverName) +{ + auto* mpSolver = isMip ? MPSolver::CreateSolver( + (OrtoolsUtils::solverMap.at(solverName)).MIPSolverName) + : MPSolver::CreateSolver( + (OrtoolsUtils::solverMap.at(solverName)).LPSolverName); + + mpSolver_ = std::unique_ptr(mpSolver); + objective_ = mpSolver->MutableObjective(); + + params_.SetIntegerParam(MPSolverParameters::SCALING, 0); + params_.SetIntegerParam(MPSolverParameters::PRESOLVE, 0); +} + +class ElemAlreadyExists: public std::exception +{ +public: + const char* what() const noexcept override + { + return "Element name already exists in linear problem"; + } +}; + +OrtoolsMipVariable* OrtoolsLinearProblem::addVariable(double lb, + double ub, + bool integer, + const std::string& name) +{ + if (variables_.contains(name)) + { + logs.error() << "This variable already exists: " << name; + throw ElemAlreadyExists(); + } + + auto* mpVar = mpSolver_->MakeVar(lb, ub, integer, name); + + if (!mpVar) + { + logs.error() << "Couldn't add variable to Ortools MPSolver: " << name; + } + + const auto& pair = variables_.emplace(name, std::make_unique(mpVar)); + return pair.first->second.get(); // <, bool> +} + +OrtoolsMipVariable* OrtoolsLinearProblem::addNumVariable(double lb, + double ub, + const std::string& name) +{ + return addVariable(lb, ub, false, name); +} + +OrtoolsMipVariable* OrtoolsLinearProblem::addIntVariable(double lb, + double ub, + const std::string& name) +{ + return addVariable(lb, ub, true, name); +} + +OrtoolsMipVariable* OrtoolsLinearProblem::getVariable(const std::string& name) const +{ + return variables_.at(name).get(); +} + +OrtoolsMipConstraint* OrtoolsLinearProblem::addConstraint(double lb, + double ub, + const std::string& name) +{ + if (constraints_.contains(name)) + { + logs.error() << "This constraint already exists: " << name; + throw ElemAlreadyExists(); + } + + auto* mpConstraint = mpSolver_->MakeRowConstraint(lb, ub, name); + + if (!mpConstraint) + { + logs.error() << "Couldn't add variable to Ortools MPSolver: " << name; + } + + const auto& pair = constraints_.emplace(name, + std::make_unique(mpConstraint)); + return pair.first->second.get(); // <, bool> +} + +OrtoolsMipConstraint* OrtoolsLinearProblem::getConstraint(const std::string& name) const +{ + return constraints_.at(name).get(); +} + +static const operations_research::MPVariable* getMpVar(const Api::IMipVariable* var) + +{ + const auto* OrtoolsMipVar = dynamic_cast(var); + if (!OrtoolsMipVar) + { + logs.error() << "Invalid cast, tried from Api::IMipVariable to OrtoolsMipVariable"; + throw std::bad_cast(); + } + return OrtoolsMipVar->getMpVar(); +} + +void OrtoolsLinearProblem::setObjectiveCoefficient(Api::IMipVariable* var, double coefficient) +{ + objective_->SetCoefficient(getMpVar(var), coefficient); +} + +double OrtoolsLinearProblem::getObjectiveCoefficient(const Api::IMipVariable* var) const +{ + return objective_->GetCoefficient(getMpVar(var)); +} + +void OrtoolsLinearProblem::setMinimization() +{ + objective_->SetMinimization(); +} + +void OrtoolsLinearProblem::setMaximization() +{ + objective_->SetMaximization(); +} + +bool OrtoolsLinearProblem::isMinimization() const +{ + return objective_->minimization(); +} + +bool OrtoolsLinearProblem::isMaximization() const +{ + return objective_->maximization(); +} + +OrtoolsMipSolution* OrtoolsLinearProblem::solve(bool verboseSolver) +{ + if (verboseSolver) + { + mpSolver_->EnableOutput(); + } + + auto mpStatus = mpSolver_->Solve(params_); + + solution_ = std::make_unique(mpStatus, mpSolver_); + return solution_.get(); +} + +} // namespace Antares::Solver::Modeler::OrtoolsImpl diff --git a/src/solver/modeler/ortoolsImpl/mipConstraint.cpp b/src/solver/modeler/ortoolsImpl/mipConstraint.cpp new file mode 100644 index 0000000000..00a24069a4 --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/mipConstraint.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include + +#include +#include +#include + +namespace Antares::Solver::Modeler::OrtoolsImpl +{ + +OrtoolsMipConstraint::OrtoolsMipConstraint(operations_research::MPConstraint* mpConstraint): + mpConstraint_(mpConstraint) +{ +} + +void OrtoolsMipConstraint::setLb(double lb) +{ + mpConstraint_->SetLB(lb); +} + +void OrtoolsMipConstraint::setUb(double ub) +{ + mpConstraint_->SetUB(ub); +} + +void OrtoolsMipConstraint::setBounds(double lb, double ub) +{ + mpConstraint_->SetBounds(lb, ub); +} + +double OrtoolsMipConstraint::getLb() const +{ + return mpConstraint_->lb(); +} + +double OrtoolsMipConstraint::getUb() const +{ + return mpConstraint_->ub(); +} + +void OrtoolsMipConstraint::setCoefficient(Api::IMipVariable* var, double coefficient) +{ + auto* mpvar = dynamic_cast(var); + if (!mpvar) + { + logs.error() << "Invalid cast, tried from Api::IMipVariable to OrtoolsMipVariable"; + throw std::bad_cast(); + } + + mpConstraint_->SetCoefficient(mpvar->getMpVar(), coefficient); +} + +double OrtoolsMipConstraint::getCoefficient(Api::IMipVariable* var) +{ + auto* mpvar = dynamic_cast(var); + if (!mpvar) + { + logs.error() << "Invalid cast, tried from Api::IMipVariable to OrtoolsMipVariable"; + throw std::bad_cast(); + } + + return mpConstraint_->GetCoefficient(mpvar->getMpVar()); +} + +const std::string& OrtoolsMipConstraint::getName() const +{ + return mpConstraint_->name(); +} + +} // namespace Antares::Solver::Modeler::OrtoolsImpl diff --git a/src/solver/modeler/ortoolsImpl/mipSolution.cpp b/src/solver/modeler/ortoolsImpl/mipSolution.cpp new file mode 100644 index 0000000000..8a04484522 --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/mipSolution.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include +#include + +namespace Antares::Solver::Modeler::OrtoolsImpl +{ + +OrtoolsMipSolution::OrtoolsMipSolution(operations_research::MPSolver::ResultStatus& status, + std::shared_ptr solver): + status_(status), + mpSolver_(solver) +{ + for (const auto* var: mpSolver_->variables()) + { + solution_.try_emplace(var->name(), var->solution_value()); + } +} + +Api::MipStatus OrtoolsMipSolution::getStatus() const +{ + switch (status_) + { + case operations_research::MPSolver::ResultStatus::OPTIMAL: + return Api::MipStatus::OPTIMAL; + case operations_research::MPSolver::ResultStatus::FEASIBLE: + return Api::MipStatus::FEASIBLE; + case operations_research::MPSolver::ResultStatus::UNBOUNDED: + return Api::MipStatus::UNBOUNDED; + case operations_research::MPSolver::ResultStatus::INFEASIBLE: + return Api::MipStatus::INFEASIBLE; + default: + logs.warning() << "Solve returned an error status"; + break; + } + return Api::MipStatus::MIP_ERROR; +} + +double OrtoolsMipSolution::getObjectiveValue() const +{ + return mpSolver_->Objective().Value(); +} + +double OrtoolsMipSolution::getOptimalValue(const Api::IMipVariable* var) const +{ + if (!var) + { + return 0; + } + + try + { + return solution_.at(var->getName()); + } + catch (const std::out_of_range& ex) + { + logs.warning() << ex.what(); + logs.warning() << "Solution not found for variable: " << var->getName(); + } + return 0; +} + +std::vector OrtoolsMipSolution::getOptimalValues( + const std::vector& vars) const +{ + std::vector solution; + solution.reserve(vars.size()); + + for (const auto* var: vars) + { + solution.push_back(getOptimalValue(var)); + } + + return solution; +} + +} // namespace Antares::Solver::Modeler::OrtoolsImpl diff --git a/src/solver/modeler/ortoolsImpl/mipVariable.cpp b/src/solver/modeler/ortoolsImpl/mipVariable.cpp new file mode 100644 index 0000000000..5e21924a8f --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/mipVariable.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#include + +#include + +namespace Antares::Solver::Modeler::OrtoolsImpl +{ + +OrtoolsMipVariable::OrtoolsMipVariable(operations_research::MPVariable* mpVar): + mpVar_(mpVar) +{ +} + +void OrtoolsMipVariable::setLb(double lb) +{ + mpVar_->SetLB(lb); +} + +void OrtoolsMipVariable::setUb(double ub) +{ + mpVar_->SetUB(ub); +} + +void OrtoolsMipVariable::setBounds(double lb, double ub) +{ + mpVar_->SetBounds(lb, ub); +} + +double OrtoolsMipVariable::getLb() const +{ + return mpVar_->lb(); +} + +double OrtoolsMipVariable::getUb() const +{ + return mpVar_->ub(); +} + +const operations_research::MPVariable* OrtoolsMipVariable::getMpVar() const +{ + return mpVar_; +} + +const std::string& OrtoolsMipVariable::getName() const +{ + return mpVar_->name(); +} + +} // namespace Antares::Solver::Modeler::OrtoolsImpl diff --git a/src/tests/src/solver/CMakeLists.txt b/src/tests/src/solver/CMakeLists.txt index 814883c633..bf920cb80b 100644 --- a/src/tests/src/solver/CMakeLists.txt +++ b/src/tests/src/solver/CMakeLists.txt @@ -3,4 +3,5 @@ add_subdirectory(optimisation) add_subdirectory(utils) add_subdirectory(infeasible-problem-analysis) add_subdirectory(lps) +add_subdirectory(modeler) add_subdirectory(expressions) diff --git a/src/tests/src/solver/modeler/CMakeLists.txt b/src/tests/src/solver/modeler/CMakeLists.txt new file mode 100644 index 0000000000..53d257b04e --- /dev/null +++ b/src/tests/src/solver/modeler/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(api) diff --git a/src/tests/src/solver/modeler/api/CMakeLists.txt b/src/tests/src/solver/modeler/api/CMakeLists.txt new file mode 100644 index 0000000000..0299f3ec0b --- /dev/null +++ b/src/tests/src/solver/modeler/api/CMakeLists.txt @@ -0,0 +1,20 @@ +set(EXECUTABLE_NAME tests-modeler-api-ortools) +add_executable(${EXECUTABLE_NAME} testApiOrtoolsLinearProblem.cpp) + +target_include_directories(${EXECUTABLE_NAME} + PRIVATE + "${src_solver_optimisation}" +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + Antares::modeler-ortools-impl +) + +# Storing tests-ts-numbers under the folder Unit-tests in the IDE +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) + +add_test(NAME test-modeler-api-ortools COMMAND ${EXECUTABLE_NAME}) + +set_property(TEST test-modeler-api-ortools PROPERTY LABELS unit) diff --git a/src/tests/src/solver/modeler/api/testApiOrtoolsLinearProblem.cpp b/src/tests/src/solver/modeler/api/testApiOrtoolsLinearProblem.cpp new file mode 100644 index 0000000000..06bbcb6669 --- /dev/null +++ b/src/tests/src/solver/modeler/api/testApiOrtoolsLinearProblem.cpp @@ -0,0 +1,239 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ +#define BOOST_TEST_MODULE test modeler api ortools + +#define WIN32_LEAN_AND_MEAN + +#include + +#include + +using namespace Antares::Solver::Modeler; + +struct FixtureEmptyProblem +{ + FixtureEmptyProblem() + { + pb = std::make_unique(false, "sirius"); + } + + std::unique_ptr pb; +}; + +struct FixtureInfeasibleProblem: public FixtureEmptyProblem +{ + FixtureInfeasibleProblem() + { + auto* var = pb->addNumVariable(0, 1, "var"); + auto* constraint = pb->addConstraint(2, 2, "constraint"); + constraint->setCoefficient(var, 1); + } +}; + +struct FixtureFeasibleProblem: public FixtureEmptyProblem +{ + FixtureFeasibleProblem() + { + auto* var = pb->addNumVariable(0, 10, "var"); + auto* constraint = pb->addConstraint(1, 1, "constraint"); + constraint->setCoefficient(var, 1); + pb->setObjectiveCoefficient(var, 1); + } +}; + +BOOST_AUTO_TEST_SUITE(tests_on_OrtoolsLinearProblem) + +BOOST_FIXTURE_TEST_CASE(add_int_variable_to_problem___check_var_exists, FixtureEmptyProblem) +{ + pb->addIntVariable(5, 15, "var"); + auto* var = pb->getVariable("var"); + BOOST_CHECK(var); + BOOST_CHECK_EQUAL(var->getLb(), 5); + BOOST_CHECK_EQUAL(var->getUb(), 15); +} + +BOOST_FIXTURE_TEST_CASE(add_num_variable_to_problem___check_var_exists, FixtureEmptyProblem) +{ + pb->addNumVariable(2., 7., "var"); + auto* var = pb->getVariable("var"); + BOOST_CHECK(var); + BOOST_CHECK_EQUAL(var->getLb(), 2.); + BOOST_CHECK_EQUAL(var->getUb(), 7.); +} + +BOOST_FIXTURE_TEST_CASE(add_constraint_to_problem___check_constraint_exists, FixtureEmptyProblem) +{ + pb->addConstraint(3., 8., "constraint"); + auto* constraint = pb->getConstraint("constraint"); + BOOST_CHECK(constraint); + BOOST_CHECK_EQUAL(constraint->getLb(), 3.); + BOOST_CHECK_EQUAL(constraint->getUb(), 8.); +} + +BOOST_FIXTURE_TEST_CASE(give_coeff_to_var_in_constraint____check_coeff_exists, FixtureEmptyProblem) +{ + auto* var = pb->addNumVariable(0, 1, "var"); + auto* constraint = pb->addConstraint(0, 1, "constraint"); + constraint->setCoefficient(var, 3.2); + + BOOST_CHECK_EQUAL(constraint->getCoefficient(var), 3.2); +} + +BOOST_FIXTURE_TEST_CASE(give_coef_to_null_var_in_constaint_leads_to_bad_cast, FixtureEmptyProblem) +{ + auto* constraint = pb->addConstraint(0, 1, "constraint"); + BOOST_CHECK_THROW(constraint->setCoefficient(nullptr, 3.2), std::bad_cast); +} + +BOOST_FIXTURE_TEST_CASE(get_coef_of_null_var_in_constaint_leads_to_bad_cast, FixtureEmptyProblem) +{ + auto* constraint = pb->addConstraint(0, 1, "constraint"); + BOOST_CHECK_THROW(constraint->getCoefficient(nullptr), std::bad_cast); +} + +bool expectedMessage(const std::exception& ex) +{ + BOOST_CHECK_EQUAL(ex.what(), std::string("Element name already exists in linear problem")); + return true; +} + +BOOST_FIXTURE_TEST_CASE(add_already_existing_var_to_problem_leads_to_exception, FixtureEmptyProblem) +{ + pb->addNumVariable(0, 1, "var"); + BOOST_CHECK_EXCEPTION(pb->addNumVariable(0, 1, "var"), std::exception, expectedMessage); +} + +BOOST_FIXTURE_TEST_CASE(add_already_existing_constaint_to_problem_leads_to_exception, + FixtureEmptyProblem) +{ + pb->addConstraint(0, 1, "constraint"); + BOOST_CHECK_EXCEPTION(pb->addConstraint(0, 1, "constraint"), std::exception, expectedMessage); +} + +BOOST_FIXTURE_TEST_CASE(minimize_problem___check_minimize_status, FixtureEmptyProblem) +{ + pb->setMinimization(); + BOOST_CHECK(pb->isMinimization()); +} + +BOOST_FIXTURE_TEST_CASE(maximize_problem___check_maximize_status, FixtureEmptyProblem) +{ + pb->setMaximization(); + BOOST_CHECK(pb->isMaximization()); +} + +BOOST_FIXTURE_TEST_CASE(give_bounds_to_var___check_bounds_exist, FixtureEmptyProblem) +{ + auto* var = pb->addNumVariable(0, 1, "var"); + var->setLb(-4); + var->setUb(7); + + BOOST_CHECK_EQUAL(var->getLb(), -4); + BOOST_CHECK_EQUAL(var->getUb(), 7); + + var->setBounds(2, 13); + + BOOST_CHECK_EQUAL(var->getLb(), 2); + BOOST_CHECK_EQUAL(var->getUb(), 13); +} + +BOOST_FIXTURE_TEST_CASE(give_bounds_to_constraint___check_bounds_exist, FixtureEmptyProblem) +{ + auto* constraint = pb->addConstraint(0, 1, "var"); + + constraint->setLb(-4); + constraint->setUb(7); + BOOST_CHECK_EQUAL(constraint->getLb(), -4); + BOOST_CHECK_EQUAL(constraint->getUb(), 7); + + constraint->setBounds(2, 13); + BOOST_CHECK_EQUAL(constraint->getLb(), 2); + BOOST_CHECK_EQUAL(constraint->getUb(), 13); +} + +BOOST_FIXTURE_TEST_CASE(give_cost_to_variable___check_cost_exist, FixtureEmptyProblem) +{ + auto* var = pb->addIntVariable(0, 1, "var"); + pb->setObjectiveCoefficient(var, 1); + BOOST_CHECK_EQUAL(pb->getObjectiveCoefficient(var), 1); +} + +BOOST_FIXTURE_TEST_CASE(get_cost_from_null_variable_leads_to_bad_cast, FixtureEmptyProblem) +{ + BOOST_CHECK_THROW(pb->getObjectiveCoefficient(nullptr), std::bad_cast); +} + +BOOST_FIXTURE_TEST_CASE(give_cost_to_null_variable_leads_to_bad_cast, FixtureEmptyProblem) +{ + BOOST_CHECK_THROW(pb->setObjectiveCoefficient(nullptr, 0), std::bad_cast); +} + +BOOST_FIXTURE_TEST_CASE(solve_infeasible_problem_leads_to_error_status, FixtureInfeasibleProblem) +{ + auto* solution = pb->solve(true); + BOOST_CHECK(solution->getStatus() == Api::MipStatus::INFEASIBLE); +} + +BOOST_FIXTURE_TEST_CASE(solve_infeasible_problem_leads_to_null_objective_value, + FixtureInfeasibleProblem) +{ + auto* solution = pb->solve(true); + BOOST_CHECK_EQUAL(solution->getObjectiveValue(), 0); +} + +BOOST_FIXTURE_TEST_CASE(solve_infeasible_problem___check_any_var_is_zero, FixtureInfeasibleProblem) +{ + auto* solution = pb->solve(true); + + auto* var = pb->getVariable("var"); + BOOST_CHECK(var); // searched variable is known by problem + BOOST_CHECK_EQUAL(solution->getOptimalValue(var), 0); +} + +BOOST_FIXTURE_TEST_CASE(solve_feasible_problem___check_status_is_optimal, FixtureFeasibleProblem) +{ + auto* solution = pb->solve(false); + BOOST_CHECK(solution->getStatus() == Api::MipStatus::OPTIMAL); +} + +BOOST_FIXTURE_TEST_CASE(solve_feasible_problem___check_objective_has_expected_value, + FixtureFeasibleProblem) +{ + auto* solution = pb->solve(false); + BOOST_CHECK_EQUAL(solution->getObjectiveValue(), 1); +} + +BOOST_FIXTURE_TEST_CASE(solve_problem_then_add_new_var___new_var_optimal_value_is_zero, + FixtureFeasibleProblem) +{ + auto* solution = pb->solve(false); + auto* newVar = pb->addNumVariable(0, 1, "new var"); + BOOST_CHECK_EQUAL(solution->getOptimalValue(newVar), 0); +} + +BOOST_FIXTURE_TEST_CASE(solve_problem___check_optimal_value_of_null_var_is_zero, + FixtureFeasibleProblem) +{ + auto* solution = pb->solve(false); + BOOST_CHECK_EQUAL(solution->getOptimalValue(nullptr), 0); +} + +BOOST_AUTO_TEST_SUITE_END() From 775224ebfcdd4bbedac14ac6afb54babba7a95d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 10 Sep 2024 16:30:29 +0200 Subject: [PATCH 127/127] Add iterators on ASTs, allowing for loops, std::find/std::find_if, std::count/std::count_if, etc. (#2387) Co-authored-by: OMNES Florian --- src/solver/expressions/CMakeLists.txt | 11 +- .../solver/expressions/iterators/pre-order.h | 58 ++++++++ .../expressions/iterators/pre-order.cpp | 103 +++++++++++++ .../src/solver/expressions/CMakeLists.txt | 2 + .../src/solver/expressions/test_Iterators.cpp | 136 ++++++++++++++++++ 5 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 src/solver/expressions/include/antares/solver/expressions/iterators/pre-order.h create mode 100644 src/solver/expressions/iterators/pre-order.cpp create mode 100644 src/tests/src/solver/expressions/test_Iterators.cpp diff --git a/src/solver/expressions/CMakeLists.txt b/src/solver/expressions/CMakeLists.txt index be6ad0c83e..6ef342a633 100644 --- a/src/solver/expressions/CMakeLists.txt +++ b/src/solver/expressions/CMakeLists.txt @@ -55,7 +55,6 @@ set(SRC_Expressions include/antares/solver/expressions/IName.h ) - source_group("expressions" FILES ${SRC_Expressions}) add_library(antares-solver-expressions ${SRC_Expressions}) @@ -67,7 +66,17 @@ target_include_directories(antares-solver-expressions target_link_libraries(antares-solver-expressions PUBLIC Antares::logs + ) + + + +add_library(antares-solver-expressions-iterators + iterators/pre-order.cpp + include/antares/solver/expressions/iterators/pre-order.h ) + +target_link_libraries(antares-solver-expressions-iterators PRIVATE antares-solver-expressions) + install(DIRECTORY include/antares DESTINATION "include" ) diff --git a/src/solver/expressions/include/antares/solver/expressions/iterators/pre-order.h b/src/solver/expressions/include/antares/solver/expressions/iterators/pre-order.h new file mode 100644 index 0000000000..a3beb9efcc --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/iterators/pre-order.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +namespace Antares::Solver::Nodes +{ +// Forward-declaration is enough + +class Node; + +// PreOrder Iterator for AST +class ASTPreOrderIterator +{ + std::stack nodeStack; + +public: + // Iterator type aliases + using iterator_category = std::forward_iterator_tag; + using value_type = Node; + using difference_type = std::ptrdiff_t; + using pointer = Node*; + using reference = Node&; + + // Constructor + explicit ASTPreOrderIterator(Node* root = nullptr); + + // Dereference operator + reference operator*() const; + + // Pointer access operator + pointer operator->() const; + + // Increment operator (pre-order traversal) + ASTPreOrderIterator& operator++(); + + // Equality comparison + bool operator==(const ASTPreOrderIterator& other) const; + + // Inequality comparison + bool operator!=(const ASTPreOrderIterator& other) const; +}; + +// AST container class to expose begin/end iterators +class AST +{ + Node* root; + +public: + explicit AST(Node* rootNode); + + // Begin iterator + ASTPreOrderIterator begin(); + + // End iterator (indicating traversal is complete) + ASTPreOrderIterator end(); +}; +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/iterators/pre-order.cpp b/src/solver/expressions/iterators/pre-order.cpp new file mode 100644 index 0000000000..5e8a968b31 --- /dev/null +++ b/src/solver/expressions/iterators/pre-order.cpp @@ -0,0 +1,103 @@ +#include + +#include +#include + +namespace Antares::Solver::Nodes +{ +namespace +{ +// Children, left to right +std::vector childrenLeftToRight(Node* node) +{ + if (auto* bin = dynamic_cast(node)) + { + return {bin->left(), bin->right()}; + } + else if (auto* unary = dynamic_cast(node)) + { + return {unary->child()}; + } + return {}; +} +} // namespace + +// Constructor +ASTPreOrderIterator::ASTPreOrderIterator(Node* root) +{ + if (root) + { + nodeStack.push(root); + } +} + +// Dereference operator +ASTPreOrderIterator::reference ASTPreOrderIterator::operator*() const +{ + return *nodeStack.top(); +} + +// Pointer access operator +ASTPreOrderIterator::pointer ASTPreOrderIterator::operator->() const +{ + return nodeStack.top(); +} + +// Increment operator (pre-order traversal) +ASTPreOrderIterator& ASTPreOrderIterator::operator++() +{ + if (nodeStack.empty()) + { + return *this; + } + + Node* current = nodeStack.top(); + nodeStack.pop(); + + const auto children = childrenLeftToRight(current); + // Push children in reverse order to process them in left-to-right order + for (auto* it: children | std::views::reverse) + { + nodeStack.push(it); + } + + return *this; +} + +// Equality comparison +bool ASTPreOrderIterator::operator==(const ASTPreOrderIterator& other) const +{ + if (nodeStack.empty() && other.nodeStack.empty()) + { + return true; + } + if (nodeStack.empty() || other.nodeStack.empty()) + { + return false; + } + return nodeStack.top() == other.nodeStack.top(); +} + +// Inequality comparison +bool ASTPreOrderIterator::operator!=(const ASTPreOrderIterator& other) const +{ + return !(*this == other); +} + +AST::AST(Node* rootNode): + root(rootNode) +{ +} + +// Begin iterator +ASTPreOrderIterator AST::begin() +{ + return ASTPreOrderIterator(root); +} + +// End iterator (indicating traversal is complete) +ASTPreOrderIterator AST::end() +{ + return ASTPreOrderIterator(nullptr); +} +} // namespace Antares::Solver::Nodes diff --git a/src/tests/src/solver/expressions/CMakeLists.txt b/src/tests/src/solver/expressions/CMakeLists.txt index 5cdec566b7..f2166a71ad 100644 --- a/src/tests/src/solver/expressions/CMakeLists.txt +++ b/src/tests/src/solver/expressions/CMakeLists.txt @@ -12,12 +12,14 @@ target_sources(${EXECUTABLE_NAME} test_CompareVisitor.cpp test_CloneVisitor.cpp test_DeepWideTrees.cpp + test_Iterators.cpp ) target_link_libraries(${EXECUTABLE_NAME} PRIVATE Boost::unit_test_framework antares-solver-expressions + antares-solver-expressions-iterators ) # Storing tests-ts-numbers under the folder Unit-tests in the IDE diff --git a/src/tests/src/solver/expressions/test_Iterators.cpp b/src/tests/src/solver/expressions/test_Iterators.cpp new file mode 100644 index 0000000000..df0a4ddd18 --- /dev/null +++ b/src/tests/src/solver/expressions/test_Iterators.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN + +#include + +#include + +#include +#include +#include + +using namespace Antares::Solver; +using namespace Antares::Solver::Nodes; + +BOOST_AUTO_TEST_SUITE(_Iterator_) + +static Node* simpleExpression(Registry& registry) +{ + return registry.create(registry.create(2.), + registry.create(21.)); +} + +BOOST_FIXTURE_TEST_CASE(empty_ast_begin_is_end, Registry) +{ + AST ast(nullptr); + BOOST_CHECK(ast.begin() == ast.end()); +} + +BOOST_FIXTURE_TEST_CASE(simple_end_is_end, Registry) +{ + AST ast(create(32.)); + BOOST_CHECK(ast.end() == ast.end()); +} + +BOOST_FIXTURE_TEST_CASE(dereference_op, Registry) +{ + AST ast(create(21.)); + auto it = ast.begin(); + const std::string expected("LiteralNode"); + BOOST_CHECK_EQUAL(it->name(), expected); + BOOST_CHECK_EQUAL((*it).name(), expected); +} + +BOOST_FIXTURE_TEST_CASE(unary_dereference, Registry) +{ + AST ast(create(nullptr)); + auto it = ast.begin(); + BOOST_CHECK(!it->name().empty()); + BOOST_CHECK(!(*it).name().empty()); +} + +BOOST_FIXTURE_TEST_CASE(count_literal_nodes_for_loop, Registry) +{ + int count_lit = 0; + for (auto& node: AST(simpleExpression(*this))) + { + if (dynamic_cast(&node)) + { + count_lit++; + } + } + BOOST_CHECK_EQUAL(count_lit, 2); +} + +BOOST_FIXTURE_TEST_CASE(count_literal_nodes_count_if, Registry) +{ + AST ast(simpleExpression(*this)); + int count_lit = std::count_if(ast.begin(), + ast.end(), + [](Node& node) + { return dynamic_cast(&node) != nullptr; }); + + BOOST_CHECK_EQUAL(count_lit, 2); +} + +BOOST_FIXTURE_TEST_CASE(find_if_not_found, Registry) +{ + AST ast(simpleExpression(*this)); + auto it = std::find_if(ast.begin(), + ast.end(), + [](Node& node) + { return dynamic_cast(&node) != nullptr; }); + BOOST_CHECK(it == ast.end()); +} + +BOOST_FIXTURE_TEST_CASE(find_if_found, Registry) +{ + AST ast(simpleExpression(*this)); + auto it = std::find_if(ast.begin(), + ast.end(), + [](Node& node) { return dynamic_cast(&node) != nullptr; }); + BOOST_CHECK(it != ast.end()); + auto* res = dynamic_cast(&*it); + BOOST_REQUIRE(res); + BOOST_CHECK_EQUAL(res->value(), 2.); +} + +BOOST_FIXTURE_TEST_CASE(distance_is_3, Registry) +{ + AST ast(simpleExpression(*this)); + BOOST_CHECK_EQUAL(std::distance(ast.begin(), ast.end()), 3); +} + +BOOST_FIXTURE_TEST_CASE(distance_unary, Registry) +{ + AST ast(create(create(create(32.)))); + BOOST_CHECK_EQUAL(std::distance(ast.begin(), ast.end()), 3); +} + +BOOST_FIXTURE_TEST_CASE(distance_nullptr_is_3, Registry) +{ + AST ast(create(nullptr, create(2.))); + BOOST_CHECK_EQUAL(std::distance(ast.begin(), ast.end()), 3); +} + +BOOST_AUTO_TEST_SUITE_END()