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/.github/workflows/centos7.yml b/.github/workflows/centos7.yml index 5ba13ec5c6..330df8e719 100644 --- a/.github/workflows/centos7.yml +++ b/.github/workflows/centos7.yml @@ -43,8 +43,19 @@ 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-10-gcc* + yum install -y devtoolset-11-gcc* - name: Install cmake 3.28 run: pip3 install cmake==3.28.4 @@ -75,7 +86,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 @@ -89,12 +100,12 @@ 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: | - 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 +121,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 @@ -135,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: @@ -152,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/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/oracle8.yml b/.github/workflows/oracle8.yml index 01f040c5ac..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') }} @@ -74,7 +73,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: | @@ -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') }} diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 8dbf991635..e6f1cf608f 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -20,8 +20,21 @@ 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: + # 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 @@ -40,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_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 @@ -78,6 +91,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 @@ -92,15 +115,16 @@ 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 \ + -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 @@ -108,6 +132,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 @@ -116,7 +148,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/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 9f129f04f9..ecc3d2f51c 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 @@ -142,27 +142,31 @@ 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: Run named mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests - with: - simtest-tag: ${{ env.SIMTEST }} - batch-name: valid-named-mps - os: ${{ env.os }} - variant: "named-mps" + - 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 + # with: + # simtest-tag: ${{ env.SIMTEST }} + # batch-name: valid-named-mps + # os: ${{ env.os }} + # 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 +179,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 +187,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 +196,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 +204,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 +212,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 +220,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,23 +228,28 @@ 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 }} batch-name: short-tests os: ${{ env.os }} - - name: Run mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests + - name: Run cucumber on short-tests + uses: ./.github/workflows/cucumber-tests with: - simtest-tag: ${{ env.SIMTEST }} - batch-name: valid-mps - os: ${{ env.os }} + feature: "features/short_tests.feature" + + # - name: Run mps tests + # if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} + # uses: ./.github/workflows/run-tests + # with: + # simtest-tag: ${{ env.SIMTEST }} + # batch-name: valid-mps + # 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 +257,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 +266,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,15 +275,20 @@ 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 }} 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' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -282,7 +296,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 +304,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 bcd2ef9e5a..3923e18af7 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 @@ -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 @@ -148,23 +152,23 @@ jobs: 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: ${{ env.SIMTEST }} - batch-name: valid-named-mps - os: ${{ env.os }} - variant: "named-mps" + # - name: Run named mps tests + # if: ${{ env.RUN_SIMPLE_TESTS == 'true' && ! cancelled() }} + # uses: ./.github/workflows/run-tests + # with: + # simtest-tag: ${{ env.SIMTEST }} + # batch-name: valid-named-mps + # os: ${{ env.os }} + # 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 +181,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 +189,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 +197,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 +206,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 +214,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 +222,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 +230,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,23 +238,28 @@ 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 }} batch-name: short-tests os: ${{ env.os }} - - name: Run mps tests - if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} - uses: ./.github/workflows/run-tests + - name: Run cucumber on short-tests + uses: ./.github/workflows/cucumber-tests with: - simtest-tag: ${{ env.SIMTEST }} - batch-name: valid-mps - os: ${{ env.os }} + feature: "features/short_tests.feature" + + # - name: Run mps tests + # if: ${{ env.RUN_SIMPLE_TESTS == 'true' && !cancelled() }} + # uses: ./.github/workflows/run-tests + # with: + # simtest-tag: ${{ env.SIMTEST }} + # batch-name: valid-mps + # 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 +268,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,15 +277,20 @@ 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 }} 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' }} + if: ${{ env.RUN_EXTENDED_TESTS == 'true' && !cancelled() }} uses: ./.github/workflows/run-tests with: simtest-tag: ${{ env.SIMTEST }} @@ -284,7 +298,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 +306,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: | 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/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 ======= diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba7010934b..b79849439c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,55 +1,8 @@ # How to contribute to Antares Simulator ## Reporting a bug -- First, please make sure that the bug has not been already reported under [Issues](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues). - -- If not, [open a new one](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues/new). You must provide : - - a description of the bug and its unexpected behavior - - the expected behavior - - a small antares study to reproduce the unexpected behavior - - the version of Antares Simulator and OS used - +- First, please make sure that the bug has not been already reported under [Issues](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues). +- Then [open a bug here](https://github.com/AntaresSimulatorTeam/Antares_Simulator/issues/new?template=bug_report.md). ## Development -Antares Simulator team will be pleased to have developers join our project. - -You can find all the steps needed to build & install Antares Simulator in -the [documentation website](https://antares-simulator.readthedocs.io/) -or [its sources](docs/developer-guide/0-Introduction.md). - -### Branch names -Currently, CI is run only for specific branch names: -- `feature/*` -- `features/*` -- `fix/*` -- `release/*` -- `issue-*` -- `doc/*` - -If you create a branch with a different name, no CI will be run, but you will receive an email -indicating that your branch name is incorrect. - -In order to avoid pushing with invalid branch name, a git hook is provided for pre-commit check. -This hook is available in the `.githooks` directory. - -By default, git use hooks in `.git/hooks` directory which is not under version control. You can -define a new hooks directory with this command in Antares Simulator root directory : -``` -git config core.hooksPath .githooks -``` - -### Code formatting -We're using [clang-format](https://clang.llvm.org/docs/ClangFormat.html) to format code. Rules are defined in [.clang-format](src/.clang-format) file. - -### Pull Requests - -A pull request name must be self-explanatory: this will be the default commit title when merging. - -Please provide a description in the head comment of the PR. This description will be the details of the merge commit. -The description should be short but proportional to the length or complexity of the PR. Try to explain the motivation -of the PR (why) and the method employed (how). - -When a pull request is opened, please set it to draft if it is still being worked on or not ready for review. - -If your Pull Request changes a part of the code that is [documented](https://antares-simulator.readthedocs.io/), -please update the documentation also, in the ["docs"](docs) directory. \ No newline at end of file +See [here for more details](./docs/developer-guide/6-Contributing.md). 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 diff --git a/docs/developer-guide/0-Overview.md b/docs/developer-guide/0-Overview.md index 139f23d552..c974f85ac3 100644 --- a/docs/developer-guide/0-Overview.md +++ b/docs/developer-guide/0-Overview.md @@ -5,8 +5,6 @@ hide: # Overview -*ANTARES* is developed mainly in **C++** - This software suite has been tested under: * Ubuntu 20.04 [![Status][ubuntu_ci_svg]][ubuntu_ci_link] diff --git a/docs/developer-guide/6-Contributing.md b/docs/developer-guide/6-Contributing.md new file mode 100644 index 0000000000..977a2860b8 --- /dev/null +++ b/docs/developer-guide/6-Contributing.md @@ -0,0 +1,277 @@ +# C++ Style Guide + +In general, [Google's coding standard](https://google.github.io/styleguide/cppguide.html) is used, and we strongly encourage to read it. + +You can find all the steps needed to build & install Antares Simulator in the [documentation website](https://antares-simulator.readthedocs.io/) or [its sources](docs/developer-guide/0-Introduction.md). + +Below are our specific (but not all!) exceptions to the Google's coding standard: + +- All C++ code should conform to the C++20 standard. +- We use `.cpp` files and `.h` for headers, in UTF-8 encoding. +- For new files we use CamelCase, like `FileReader.cpp`. +- We use `#pragma once` instead of the `#define` Guard in header files. +- Includes are sorted and grouped by directory, there should be newlines between different directories. +- Order of directories in includes: "current_dir/current_file.h", includes from other dirs sorted by dependencies (e.g. indexer, then coding, then base), "defines.h", C++ standard library headers, boost headers. +- We ARE using C++ exceptions. Feel free to define your own exceptions, derived from `std::exception` or any child class. +- We are using all features of C++17 and C++20 +- We try to limit the usage of boost libraries which require linking (and prefer C++20 types over their boost counterparts). + +Naming and formatting + +- We ALWAYS use 4 spaces indent and don't use tabs. +- We don't have strict limits on line width, but keep it reasonable to fit on the screen. The advised width is that written in the [src/.clang-format](src/.clang-format) file (currently 100). +- Doxygen-style comments can be used. +- Use left-to-right order for variables/params: `const string& s` (reference to the const string). +- In one line `if`, `for`, `while` we use brackets. +- Space after the keyword in conditions and loops. Space after `;` in `for` loop. +- Space between binary operators: `x = y * y + z * z`. +- Space after double dash. +- We use `using` keyword instead of `typedef`. +- We do not use the Systems Hungarian Notation: do not add the "p" suffix to your pointer variable names and the "T" prefix or suffix to your type names. +- Compile-time constants must be named in CamelCase, starting with a lower-case `k`, e.g. `kCompileTimeConstant` and marked as `constexpr` when possible. +- Functions (free or member) should be named using `lowerCamelCase`, e.g `isPrime(unsigned int n)`. +- Values of enum classes must be named in CAPITAL, e.g. `enum class Color { RED, GREEN, LIGHT_BLUE };`. +- Macros and C-style enums should be avoided. If necessary, they must be named in UPPER_CASE, and enum values must be prefixed with a capitalized enum name. + + Note that macros complicate debugging, and old-style enums have dangerous implicit conversions to integers, and tend to clutter + containing namespaces. Avoid them when possible - use `const` or `constexpr` instead of macros, and enum classes instead of enums. + +**We write code without warnings on clang++, g++ and MSVC !** + +## Global/static variables +When using `static` variables, be aware that some of Antares Simulator's functions run on multiple threads. Please avoid introducing global variables. + +## Yuni + +Yuni is a C++ framework that fullfiled some of the lacking features pre-C++11. Even though you'll see it used widely through the existing code base, we recommend against using it for new code. It is namespaced under `Yuni`. + +## Branch names +Currently, CI is run only for specific branch names: +- `feature/*` +- `features/*` +- `fix/*` +- `release/*` +- `issue-*` +- `doc/*` + +If you create a branch with a different name, no CI will be run, but you will receive a notification indicating that your branch name is incorrect. + +In order to avoid pushing with invalid branch name, a git hook is provided for pre-commit check. +This hook is available in the `.githooks` directory. + +By default, git use hooks in `.git/hooks` directory which is not under version control. You can +define a new hooks directory with this command in Antares Simulator root directory : +``` +git config core.hooksPath .githooks +``` + +## Pull Requests +A pull request name must be self-explanatory: this will be the default commit title when merging. + +Please provide a description in the head comment of the PR. This description will be the details of the merge commit. +The description should be short but proportional to the length or complexity of the PR. Try to explain the motivation of the PR (why) and the method employed (how). + +When a pull request is opened, please set it to draft if it is still being worked on or not ready for review. + +If your Pull Request changes a part of the code that is [documented](https://antares-simulator.readthedocs.io/), +please update the documentation also, in the ["docs"](docs) directory. + +## ClangFormat + +Most of our coding style is specified in a configuration file for [ClangFormat](http://clang.llvm.org/docs/ClangFormat.html). +To automatically format a file, install `clang-format` and run: + + clang-format -i file.cpp file.hpp other_file.cpp + +clang-format 18.1.3 is the reference version, but any 18.x version should work as well. We strongly advise that you configure your IDE / text editor to automatically format code according to the clang-format style. Non-conforming code can't be merged to the develop branch. + +You may also use script [src/format-code.sh](src/format-code.sh) to format all the code. Generated code (ANTLR, etc.) won't be automatically formatted. + +## Formatting Example/Guide/Reference + +```cpp +#pragma once + +#include + +uint16_t constexpr kBufferSize = 255; + +// C-style enums are ALL_CAPS. But remember that C++11 enum classes are preferred. +enum Type +{ + TYPE_INTEGER, + TYPE_FLOAT, + TYPE_STRING +}; + +using TMyTypeStartsWithCapitalTLetter = double; + +class ComplexClass +{ +public: + Complex(double rePart, double imPart): + re(rePart), + im(imPart) + { + } + + double Modulus() const + { + const double rere = re * re; + const double imim = im * im; + return sqrt(rere + imim); + } + + double OneLineMethod() const + { + return re; + } + +private: + double re; + double im; +}; + +namespace +{ +void lowerCamelCaseFunctionName(int lowerCamelCaseVar) +{ + static int counter = 0; + counter += lowerCamelCaseVar; +} +} // namespace + +namespace lower_case +{ +template +void SomeFoo(int a, int b, TypenameWithoutAffixes /* We avoid compilation warnings. */) +{ + for (int i = 0; i < a; ++i) + { + // IMPORTANT! We DON'T use one-liners for if statements for easier debugging. + // The following syntax is invalid: if (i < b) Bar(i); + if (i < b) + { + Bar(i); + } + else + { + Bar(i); + Bar(b); + // Commented out the call. + // Bar(c); + } + } +} +} // namespace lower_case + +// Switch formatting. +int Foo(int a) +{ + switch (a) + { + case 1: + Bar(1); + break; + case 2: + { + Bar(2); + break; + } + case 3: + default: + Bar(3); + break; + } + return 0; +} + +// Loops formatting. + +if (condition) +{ + foo(); +} +else +{ + bar(); +} + +if (condition) +{ + if (condition) + { + foo(); + } + else + { + bar(); + } +} + +for (size_t i = 0; i < size; ++i) +{ + foo(i); +} + +while (true) +{ + if (condition) + { + break; + } +} + +// Space after the keyword. +if (condition) +{ +} + +for (size_t i = 0; i < 5; ++i) +{ +} + +while (condition) +{ +} + +switch (i) +{ +} + +// Space between operators, and don't use space between unary operator and expression. +x = 0; +x = -5; +++x; +x--; +x *= 5; +if (x && !y) +{ +} +v = w * x + y / z; +v = w * (x + z); + + +// Space after double dash. And full sentences in comments. +``` + +## Tips and Hints + +- If you see outdated code which can be improved, DO IT NOW (but in a separate pull request or commit)! +- Your code should work at least on [ubuntu|windows] platforms. +- Your code should compile with a C++20 compiler (currently supported clang++/g++/MSVC) +- Consult with the dev team before using any new 3party library +- Cover your code with unit tests. See examples for existing libraries +- Check Base and Coding libraries for most of the basic functions +- Ask your team if you have any questions +- Release builds contain debugging information (for profiling), production builds do not +- If you don't have enough time to make it right, leave a `// TODO(DeveloperName): need to fix it` comment + +## Logging functions: + +- Use `Antares::logs.[level]() << message` for logging, below is more detailed description for level: + - `logs.info() << msg` - always prints log message + - `logs.debug() << msg` - logs only in DEBUG + - `logs.warning() << msg` - the same as `logs.info()` but catches your attention + - `logs.error()` - the same as `logs.warning()`, but triggers an error when loading a study, with exceptions + - `logs.fatal()` - same as `logs.error()` diff --git a/docs/developer-guide/CHANGELOG.md b/docs/developer-guide/CHANGELOG.md index 7309cad241..880f5dc220 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) @@ -83,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) diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 729818c28f..eca0ef0fbe 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, @@ -23,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 @@ -193,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/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/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) $$ 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/mkdocs.yml b/mkdocs.yml index 23187934c1..129404222e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -77,6 +77,7 @@ nav: - 'Tests (user)': 'developer-guide/4-Tests-user.md' - 'Tests (developer)': 'developer-guide/4-Tests-dev.md' - 'Installer creation': 'developer-guide/5-Installer-creation.md' + - 'Contributing': 'developer-guide/6-Contributing.md' - 'Continuous Integration': 'developer-guide/continuous-integration.md' - 'OR-tools integration': 'developer-guide/ortools-integration.md' - 'Changelog': 'developer-guide/CHANGELOG.md' @@ -84,6 +85,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: diff --git a/ortools_tag b/ortools_tag index fdaa0174f8..88446ca998 100644 --- a/ortools_tag +++ b/ortools_tag @@ -1 +1 @@ -v9.8-rte1.0 \ No newline at end of file +v9.10-rte1.2 \ No newline at end of file diff --git a/simtest.json b/simtest.json index f5912ade9e..03ea9af205 100644 --- a/simtest.json +++ b/simtest.json @@ -1,3 +1,3 @@ { - "version": "v9.2.0b" + "version": "v9.2.0e" } 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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78adeffde1..43358fa472 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 4) set(ANTARES_VERSION_YEAR 2024) @@ -207,8 +207,8 @@ find_package(sirius_solver REQUIRED) 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" + FetchContent_Declare(ortools-rte + GIT_REPOSITORY "https://github.com/rte-france/or-tools-rte.git" GIT_TAG ${ORTOOLS_TAG} GIT_SHALLOW TRUE ) @@ -226,8 +226,11 @@ message(STATUS "OR-Tools tag ${ORTOOLS_TAG}") # In mode optimization error analysis, we call Sirius through or-tools # So we need to activate Sirius in or-tools configuration (OFF by default) set(USE_SIRIUS "ON" CACHE INTERNAL "") + set(ortools_REPO "https://github.com/google/or-tools.git") + string(REGEX MATCH "^[^-]+" OFFICIAL_TAG ${ORTOOLS_TAG}) + set(ortools_REF ${OFFICIAL_TAG}) - FetchContent_MakeAvailable(ortools) + FetchContent_MakeAvailable(ortools-rte) endif() find_package(minizip-ng QUIET) @@ -243,7 +246,7 @@ else () endif () #wxWidget not needed for all library find is done in ui CMakeLists.txt -if (VCPKG_TOOLCHAIN AND NOT BUILD_wxWidgets) +if (VCPKG_TOOLCHAIN AND NOT BUILD_wxWidgets) #Add cmake directory to CMAKE_MODULE_PATH to use specific FindwxWidgets package needed for vcpkg list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/wxWidgets") endif() @@ -294,7 +297,7 @@ OMESSAGE("") - + # Informations for NSIS if(WIN32 OR WIN64) if(MSVC) @@ -310,7 +313,7 @@ if(WIN32 OR WIN64) set(COMPILER_MARK "m") set(COMPILER_INCLUDE "mingw") endif(MSVC) - + set(CPACK_MODULE_PATH ${CMAKE_CURRENT_BINARY_DIR}/distrib/win32 ${CPACK_MODULE_PATH}) # Configure file with custom definitions for NSIS. @@ -318,17 +321,17 @@ if(WIN32 OR WIN64) ${PROJECT_SOURCE_DIR}/distrib/win32/version.cmake ${CMAKE_CURRENT_BINARY_DIR}/distrib/win32/version.nsh ) - + configure_file( ${PROJECT_SOURCE_DIR}/distrib/win32/build.template.cmake ${CMAKE_CURRENT_BINARY_DIR}/distrib/win32/build.nsh ) - + configure_file( ${PROJECT_SOURCE_DIR}/distrib/win32/make-zip-from-installer.cmake ${CMAKE_CURRENT_BINARY_DIR}/distrib/win32/make-zip-from-installer.bat ) - + SET(ANTARES_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}) # Define system libraries so NSIS can package these files @@ -349,7 +352,7 @@ if(WIN32 OR WIN64) ${CMAKE_CURRENT_BINARY_DIR}/distrib/win32/NSIS.template.in @ONLY ) - + #Define cpack install script to checkout examples configure_file( ${PROJECT_SOURCE_DIR}/distrib/CMakeLists.txt.in @@ -368,7 +371,7 @@ else() if(CMAKE_SYSTEM_NAME MATCHES "Linux") get_linux_lsb_release_information() message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}") - set(CPACK_SYSTEM_NAME "${LSB_RELEASE_ID_SHORT}-${LSB_RELEASE_VERSION_SHORT}") + set(CPACK_SYSTEM_NAME "${LSB_RELEASE_ID_SHORT}-${LSB_RELEASE_VERSION_SHORT}") endif() #For now only test deb, need to define several CPACK variable 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/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/api/API.cpp b/src/api/API.cpp index 38e9778eab..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/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 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/Doxygen.txt b/src/libs/antares/Doxygen.txt deleted file mode 100644 index aeb41cf864..0000000000 --- a/src/libs/antares/Doxygen.txt +++ /dev/null @@ -1,1478 +0,0 @@ -# Doxyfile 1.5.7.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = AntaresLibs - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = ../../docs/developer/doxygen/libs - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = YES - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, -# Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = YES - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = YES - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = YES - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = YES - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = YES - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = YES - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = YES - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = *.c \ - *.h \ - *.cc \ - *.hh \ - *.cpp \ - *.hxx - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = CMakeFiles - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = NO - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 4 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# Qt Help Project / Namespace. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# Qt Help Project / Virtual Folders. - -QHP_VIRTUAL_FOLDER = doc - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file . - -QHG_LOCATION = - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to FRAME, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. Other possible values -# for this tag are: HIERARCHIES, which will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list; -# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which -# disables this behavior completely. For backwards compatibility with previous -# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE -# respectively. - -GENERATE_TREEVIEW = NONE - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = verdana - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = /local/opt/usr/share/fonts/ttf - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = YES diff --git a/src/libs/antares/InfoCollection/StudyInfoCollector.cpp b/src/libs/antares/InfoCollection/StudyInfoCollector.cpp index fe72e57d10..6920167f9b 100644 --- a/src/libs/antares/InfoCollection/StudyInfoCollector.cpp +++ b/src/libs/antares/InfoCollection/StudyInfoCollector.cpp @@ -45,7 +45,6 @@ void StudyInfoCollector::toFileContent(FileContent& file_content) unitCommitmentModeToFileContent(file_content); maxNbYearsInParallelToFileContent(file_content); solverVersionToFileContent(file_content); - ORToolsUsed(file_content); ORToolsSolver(file_content); } @@ -144,21 +143,10 @@ void StudyInfoCollector::solverVersionToFileContent(FileContent& file_content) file_content.addItemToSection("study", "antares version", version); } -void StudyInfoCollector::ORToolsUsed(FileContent& file_content) -{ - const bool& ortoolsUsed = study_.parameters.optOptions.ortoolsUsed; - file_content.addItemToSection("study", "ortools used", ortoolsUsed ? "true" : "false"); -} - void StudyInfoCollector::ORToolsSolver(FileContent& file_content) { - const bool& ortoolsUsed = study_.parameters.optOptions.ortoolsUsed; - std::string ortoolsSolver = "none"; - if (ortoolsUsed) - { - ortoolsSolver = study_.parameters.optOptions.ortoolsSolver; - } - file_content.addItemToSection("study", "ortools solver", ortoolsSolver); + std::string solverName = study_.parameters.optOptions.ortoolsSolver; + file_content.addItemToSection("study", "ortools solver", solverName); } // Collecting data optimization problem diff --git a/src/libs/antares/InfoCollection/include/antares/infoCollection/StudyInfoCollector.h b/src/libs/antares/InfoCollection/include/antares/infoCollection/StudyInfoCollector.h index 6aca93a605..9449bde84b 100644 --- a/src/libs/antares/InfoCollection/include/antares/infoCollection/StudyInfoCollector.h +++ b/src/libs/antares/InfoCollection/include/antares/infoCollection/StudyInfoCollector.h @@ -51,7 +51,6 @@ class StudyInfoCollector void maxNbYearsInParallelToFileContent(FileContent& file_content); void solverVersionToFileContent(FileContent& file_content); - void ORToolsUsed(FileContent& file_content); void ORToolsSolver(FileContent& file_content); // Member data @@ -69,7 +68,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/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/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/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/checks/checkLoadedInputData.cpp b/src/libs/antares/checks/checkLoadedInputData.cpp index b62408b050..faf1515b0f 100644 --- a/src/libs/antares/checks/checkLoadedInputData.cpp +++ b/src/libs/antares/checks/checkLoadedInputData.cpp @@ -30,21 +30,12 @@ namespace Antares::Check { void checkOrtoolsUsage(Antares::Data::UnitCommitmentMode ucMode, - bool ortoolsUsed, const std::string& solverName) { using namespace Antares::Data; - if (ucMode == UnitCommitmentMode::ucMILP) + if (ucMode == UnitCommitmentMode::ucMILP && solverName == "sirius") { - if (!ortoolsUsed) - { - throw Error::IncompatibleMILPWithoutOrtools(); - } - - if (solverName == "sirius") - { - throw Error::IncompatibleMILPOrtoolsSolver(); - } + throw Error::IncompatibleMILPOrtoolsSolver(); } } diff --git a/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h b/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h index 62352390bc..4286bf78b1 100644 --- a/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h +++ b/src/libs/antares/checks/include/antares/checks/checkLoadedInputData.h @@ -25,7 +25,6 @@ namespace Antares::Check { void checkOrtoolsUsage(Antares::Data::UnitCommitmentMode ucMode, - bool ortoolsUsed, const std::string& solverName); void checkStudyVersion(const AnyString& optStudyFolder); 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/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/file-tree-study-loader/FileTreeStudyLoader.cpp b/src/libs/antares/file-tree-study-loader/FileTreeStudyLoader.cpp index 8ff1c2730d..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 @@ -34,36 +33,15 @@ 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); + constexpr unsigned int argc = 3; + // On Windows, std::filesystem::path::value_type is wchar_t + std::array argv{"", + reinterpret_cast(study_path_.c_str()), + "--parallel"}; application.prepare(argc, argv.data()); return application.acquireStudy(); 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/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 diff --git a/src/libs/antares/optimization-options/include/antares/optimization-options/options.h b/src/libs/antares/optimization-options/include/antares/optimization-options/options.h index 893c1b1c21..6edc4cec9f 100644 --- a/src/libs/antares/optimization-options/include/antares/optimization-options/options.h +++ b/src/libs/antares/optimization-options/include/antares/optimization-options/options.h @@ -27,8 +27,6 @@ namespace Antares::Solver::Optimization struct OptimizationOptions { - //! Force ortools use - bool ortoolsUsed = false; //! The solver name, sirius is the default std::string ortoolsSolver = "sirius"; bool solverLogs = false; 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/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 3ec77caaed..a3524a4b96 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 @@ -250,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 @@ -294,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/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 de3c2e9b1f..cee20dc5d5 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; } } @@ -946,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)) @@ -965,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 @@ -1332,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(); } }); } @@ -1347,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(); } }); } @@ -1362,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(); } }); } @@ -1377,7 +1364,7 @@ void AreaListEnsureDataHydroTimeSeries(AreaList* l) { if (!area.hydro.series) { - area.hydro.series = new DataSeriesHydro(); + area.hydro.series = std::make_unique(); } }); } @@ -1392,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/sets.hxx b/src/libs/antares/study/area/sets.cpp similarity index 56% rename from src/libs/antares/study/include/antares/study/sets.hxx rename to src/libs/antares/study/area/sets.cpp index 931e044ba0..f853c21c0c 100644 --- a/src/libs/antares/study/include/antares/study/sets.hxx +++ b/src/libs/antares/study/area/sets.cpp @@ -18,113 +18,72 @@ ** 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(): - pByIndex(NULL), - pNameByIndex(NULL), - pModified(false) -{ -} - -template -inline Sets::Sets(const Sets& rhs): +Sets::Sets(const Sets& rhs): pMap(rhs.pMap), - pOptions(rhs.pOptions), - pByIndex(NULL), - pNameByIndex(NULL), - pModified(false) + pOptions(rhs.pOptions) { - if (rhs.pByIndex) + if (rhs.pByIndex.size()) { rebuildIndexes(); } } -template -inline Sets::~Sets() -{ - delete[] pByIndex; -} - -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() { - if (pByIndex) - { - delete[] pByIndex; - pByIndex = NULL; - } - if (pNameByIndex) - { - delete[] pNameByIndex; - pNameByIndex = NULL; - } - + pByIndex.clear(); + pNameByIndex.clear(); pMap.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(); @@ -132,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()) { @@ -169,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)) { @@ -209,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; @@ -240,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; @@ -258,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") @@ -295,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 @@ -307,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); @@ -339,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; @@ -363,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: @@ -398,90 +340,125 @@ void Sets::rebuildFromRules(const IDType& id, HandlerT& handler) << " rules, got " << opts.resultSize << " items"; } -template -void Sets::rebuildIndexes() +void Sets::rebuildIndexes() { - delete[] pByIndex; - delete[] pNameByIndex; + pNameByIndex.clear(); + pNameByIndex.resize(pMap.size()); - if (!pMap.empty()) - { - pByIndex = new TypePtr[pMap.size()]; - pNameByIndex = new IDType[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; - } - } - else + pByIndex.clear(); + pByIndex.resize(pMap.size()); + + uint index = 0; + for (const auto& [setId, set]: pMap) { - pByIndex = NULL; - pNameByIndex = NULL; + 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/binding_constraint/BindingConstraint.cpp b/src/libs/antares/study/binding_constraint/BindingConstraint.cpp index 36acdb1a59..abdce0befb 100644 --- a/src/libs/antares/study/binding_constraint/BindingConstraint.cpp +++ b/src/libs/antares/study/binding_constraint/BindingConstraint.cpp @@ -32,7 +32,6 @@ #include "antares/study/study.h" #include "antares/utils/utils.h" -using namespace Yuni; using namespace Antares; #define SEP IO::Separator @@ -48,7 +47,7 @@ namespace Antares::Data BindingConstraint::Operator BindingConstraint::StringToOperator(const AnyString& text) { - ShortString16 l(text); + Yuni::ShortString16 l(text); l.toLower(); if (l == "both" || l == "<>" || l == "><" || l == "< and >") @@ -74,7 +73,7 @@ BindingConstraint::Type BindingConstraint::StringToType(const AnyString& text) { if (!text.empty()) { - ShortString16 l(text); + Yuni::ShortString16 l(text); l.toLower(); switch (l.first()) { @@ -441,7 +440,7 @@ bool BindingConstraint::contains(const Area* area) const return false; } -void BindingConstraint::buildFormula(String& s) const +void BindingConstraint::buildFormula(Yuni::String& s) const { char tmp[42]; bool first = true; 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/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..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 @@ -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: @@ -113,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; @@ -127,7 +106,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/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/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/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/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/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 bcdeca82ac..19c2be8c00 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); @@ -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/include/antares/study/runtime/runtime.h b/src/libs/antares/study/include/antares/study/runtime/runtime.h index 0ea07ce3bc..858719ab27 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, @@ -129,18 +131,22 @@ class StudyRuntimeInfos */ bool quadraticOptimizationHasFailed; + std::vector> transitMoyenInterconnexionsRecalculQuadratique; + private: void initializeRangeLimits(const Study& study, StudyRangeLimits& limits); - //! Prepare all thermal clusters in 'must-run' mode - void initializeThermalClustersInMustRunMode(Study& study) const; void removeDisabledShortTermStorageClustersFromSolverComputations(Study& study); void removeAllRenewableClustersFromSolverComputations(Study& study); void disableAllFilters(Study& study); 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/scenario-builder/hydroLevelsData.h b/src/libs/antares/study/include/antares/study/scenario-builder/hydroLevelsData.h index b5cb21073d..27652c0fc3 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 @@ -51,7 +51,7 @@ class hydroLevelsData final: public dataInterface /*! ** \brief Reset data from the study */ - bool reset(const Study& study); + bool reset(const Study& study) override; /*! ** \brief Export the data into a mere INI file @@ -68,9 +68,9 @@ class hydroLevelsData final: public dataInterface void setTSnumber(uint index, uint year, double value); //@} - uint width() const; + uint width() const override; - uint height() const; + uint height() const override; double get_value(uint x, uint y) const; diff --git a/src/libs/antares/study/include/antares/study/sets.h b/src/libs/antares/study/include/antares/study/sets.h index 0309916749..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,13 +130,13 @@ class Sets final /*! ** \brief Default constructor */ - Sets(); + Sets() = default; /*! ** \brief Copy constructor */ Sets(const Sets& rhs); //! Destructor - ~Sets(); + ~Sets() = default; //@} //! \name Iterators @@ -150,37 +152,6 @@ class Sets final */ void clear(); - /*! - ** - */ - TypePtr add(const IDType& name) - { - TypePtr p = new T(); - 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; //! - TypePtr* pByIndex; - IDType* pNameByIndex; - mutable bool pModified; - + std::vector pByIndex; + std::vector pNameByIndex; + 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 03e2df8bed..0a7dd0eb31 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__ @@ -31,6 +31,7 @@ #include #include +#include #include #include "antares/antares/antares.h" #include "antares/study/binding_constraint/BindingConstraintGroupRepository.h" @@ -65,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; @@ -362,8 +346,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 @@ -390,10 +372,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 @@ -411,7 +389,7 @@ class Study: public Yuni::NonCopyable, public LayerData *"max"). ** */ - std::map getRawNumberCoresPerLevel(); + unsigned getNumberOfCoresPerMode(unsigned nbLogicalCores, int ncMode); /*! ** \brief Computes number of cores @@ -578,14 +556,12 @@ class Study: public Yuni::NonCopyable, public LayerData //@{ //! Sets of areas SetsOfAreas setsOfAreas; - //! Sets of links - SetsOfLinks setsOfLinks; //@} //! \name Scenario Builder //@{ //! Rules for building scenarios (can be null) - ScenarioBuilder::Sets* scenarioRules = nullptr; + std::unique_ptr scenarioRules; //@} TimeSeries::TS scenarioInitialHydroLevels; @@ -596,7 +572,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 +666,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/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/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/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/parameters.cpp b/src/libs/antares/study/parameters.cpp index 628237bbef..2f56be31d4 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -1111,15 +1111,30 @@ static bool SGDIntLoadFamily_Legacy(Parameters& d, if (key == "initial-reservoir-levels") // ignored since 9.2 { - if (version >= StudyVersion(9, 2)) + if (value == "hot start") { logs.warning() << "Option initial-reservoir-levels is deprecated, please remove it from the study"; } - else if (value == "hot start") + return true; + } + + if (key == "set-to-null-ntc-between-physical-out-for-first-step") // ignored since 9.2 + { + if (value == "false") { - logs.warning() - << "Hydro hot start not supported with this solver, please use a version < 9.2"; + logs.warning() << "Parameter set-to-null-ntc-between-physical-out-for-first-step " + " is deprecated, please remove it from the study"; + } + return true; + } + + if (key == "enable-first-step") // ignored since 9.2 + { + if (value == "true") + { + logs.warning() << "Parameter enable-first-step is deprecated, please remove it from" + " the study"; } return true; } @@ -1215,7 +1230,6 @@ bool Parameters::loadFromINI(const IniFile& ini, const StudyVersion& version) void Parameters::handleOptimizationOptions(const StudyLoadOptions& options) { // Options only set from the command-line - optOptions.ortoolsUsed = options.optOptions.ortoolsUsed; optOptions.ortoolsSolver = options.optOptions.ortoolsSolver; optOptions.solverParameters = options.optOptions.solverParameters; @@ -1715,12 +1729,7 @@ void Parameters::prepareForSimulation(const StudyLoadOptions& options) logs.info() << " :: ignoring hurdle costs"; } - // Indicate ortools solver used - if (options.optOptions.ortoolsUsed) - { - logs.info() << " :: ortools solver " << options.optOptions.ortoolsSolver - << " used for problem resolution"; - } + logs.info() << " :: solver " << options.optOptions.ortoolsSolver << " is used for problem resolution"; // indicated that Problems will be named if (namedProblems) diff --git a/src/libs/antares/study/parameters/adq-patch-params.cpp b/src/libs/antares/study/parameters/adq-patch-params.cpp index 99d0d0db33..ebf6de321e 100644 --- a/src/libs/antares/study/parameters/adq-patch-params.cpp +++ b/src/libs/antares/study/parameters/adq-patch-params.cpp @@ -27,42 +27,6 @@ namespace Antares::Data::AdequacyPatch { -// ------------------- -// Local matching -// ------------------- - -void LocalMatching::reset() -{ - 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); - } - if (key == "enable-first-step") - { - return value.to(enabled); - } - 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 // ----------------------- @@ -71,7 +35,6 @@ void CurtailmentSharing::reset() priceTakingOrder = AdqPatchPTO::isDens; includeHurdleCost = false; checkCsrCostFunction = false; - recomputeDTGMRG = false; resetThresholds(); } @@ -122,11 +85,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") { @@ -162,7 +120,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); @@ -177,8 +134,8 @@ void AdqPatchParams::reset() { enabled = false; - localMatching.reset(); curtailmentSharing.reset(); + setToZeroOutsideInsideLinks = true; } void AdqPatchParams::addExcludedVariables(std::vector& out) const @@ -187,15 +144,9 @@ 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"); } - - // 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 +155,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/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/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/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/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/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/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..bef958919d 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" @@ -342,6 +343,12 @@ bool StudyRuntimeInfos::loadFromStudy(Study& study) // Check if some clusters request TS generation checkThermalTSGeneration(study); + transitMoyenInterconnexionsRecalculQuadratique.resize(interconnectionsCount()); + for (uint i = 0; i != interconnectionsCount(); i++) + { + transitMoyenInterconnexionsRecalculQuadratique[i].assign(HOURS_PER_YEAR, 0.); + } + if (not gd.geographicTrimming) { disableAllFilters(study); diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 5b1dde8c5f..29f22e9bf5 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 @@ -104,14 +105,11 @@ Study::~Study() void Study::clear() { - // Releasing runtime infos - FreeAndNil(runtime); - FreeAndNil(scenarioRules); + scenarioRules.reset(); FreeAndNil(uiinfo); // areas setsOfAreas.clear(); - setsOfLinks.clear(); preproLoadCorrelation.clear(); preproSolarCorrelation.clear(); @@ -151,9 +149,7 @@ void Study::createAsNew() // Sets setsOfAreas.defaultForAreas(); - setsOfLinks.clear(); setsOfAreas.markAsModified(); - setsOfLinks.markAsModified(); // Binding constraints bindingConstraints.clear(); @@ -211,112 +207,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) @@ -327,33 +243,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) @@ -504,9 +395,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() @@ -1090,34 +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); }); -} - -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([](Data::Area& area) { area.wind.prepro.reset(); }); } void Study::ensureDataAreLoadedForAllBindingConstraints() @@ -1164,25 +1041,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 +1067,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 +1076,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 +1085,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 +1095,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 +1125,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) { @@ -1292,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; } @@ -1308,7 +1183,6 @@ void Study::markAsModified() const bindingConstraints.markAsModified(); setsOfAreas.markAsModified(); - setsOfLinks.markAsModified(); } void Study::relocate(const std::string& newFolder) @@ -1326,6 +1200,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/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/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/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/CMakeLists.txt b/src/solver/CMakeLists.txt index 13ab3bfa6c..37d0f4c003 100644 --- a/src/solver/CMakeLists.txt +++ b/src/solver/CMakeLists.txt @@ -19,6 +19,8 @@ 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/Doxygen.txt b/src/solver/Doxygen.txt deleted file mode 100644 index 6832b18589..0000000000 --- a/src/solver/Doxygen.txt +++ /dev/null @@ -1,1473 +0,0 @@ -# Doxyfile 1.5.7.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = AntaresSolver - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = ../../docs/developer/doxygen/solver - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = YES - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, -# Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = French - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = YES - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = YES - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = YES - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = YES - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = YES - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = YES - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = YES - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = *.c *.h *.cc *.hh *.cpp *.hxx - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = CMakeFiles - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 4 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# Qt Help Project / Namespace. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# Qt Help Project / Virtual Folders. - -QHP_VIRTUAL_FOLDER = doc - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file . - -QHG_LOCATION = - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to FRAME, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. Other possible values -# for this tag are: HIERARCHIES, which will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list; -# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which -# disables this behavior completely. For backwards compatibility with previous -# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE -# respectively. - -GENERATE_TREEVIEW = NONE - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = verdana - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = /local/opt/usr/share/fonts/ttf - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = YES - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 70 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = YES 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..f28078bf01 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; @@ -224,7 +220,6 @@ void Application::readDataForTheStudy(Data::StudyLoadOptions& options) writeComment(study); } - // Runtime data dedicated for the solver if (!study.initializeRuntimeInfos()) { throw Error::RuntimeInfoInitialization(); @@ -234,9 +229,6 @@ void Application::readDataForTheStudy(Data::StudyLoadOptions& options) study.performTransformationsBeforeLaunchingSimulation(); ScenarioBuilderOwner(study).callScenarioBuilder(); - - // alloc global vectors - SIM_AllocationTableaux(study); } void Application::startSimulation(Data::StudyLoadOptions& options) @@ -286,7 +278,6 @@ void Application::postParametersChecks() const { // Some more checks require the existence of pParameters, hence of a study. // Their execution is delayed up to this point. checkOrtoolsUsage(pParameters->unitCommitment.ucMode, - pParameters->optOptions.ortoolsUsed, pParameters->optOptions.ortoolsSolver); checkSimplexRangeHydroPricing(pParameters->simplexOptimizationRange, @@ -314,7 +305,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; @@ -388,23 +379,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(); @@ -413,28 +393,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 be114f2d88..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 { @@ -56,7 +57,7 @@ class Application final: public Yuni::IEventObserver. -*/ + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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/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/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/expressions/CMakeLists.txt b/src/solver/expressions/CMakeLists.txt new file mode 100644 index 0000000000..df56047769 --- /dev/null +++ b/src/solver/expressions/CMakeLists.txt @@ -0,0 +1,95 @@ +project(Expressions) + + +set(SRC_Expressions + nodes/PortFieldNode.cpp + nodes/PortFieldSumNode.cpp + nodes/ComponentNode.cpp + nodes/BinaryNode.cpp + nodes/UnaryNode.cpp + nodes/SumNode.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/PortFieldSubstitutionVisitor.cpp + visitors/PortFieldSumSubstitutionVisitor.cpp + visitors/AstDOTStyleVisitor.cpp + visitors/InvalidNode.cpp + + hashable.cpp + + include/antares/solver/expressions/nodes/SumNode.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/PortFieldSumNode.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/PortFieldSubstitutionVisitor.h + include/antares/solver/expressions/visitors/PortFieldSumSubstitutionVisitor.h + include/antares/solver/expressions/visitors/AstDOTStyleVisitor.h + include/antares/solver/expressions/visitors/InvalidNode.h + + include/antares/solver/expressions/Registry.hxx + include/antares/solver/expressions/IName.h + include/antares/solver/expressions/hashable.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 + Boost::headers +) + + +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/hashable.cpp b/src/solver/expressions/hashable.cpp new file mode 100644 index 0000000000..3757ed4547 --- /dev/null +++ b/src/solver/expressions/hashable.cpp @@ -0,0 +1,49 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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 +{ + +Hashable::Hashable(const std::string& s1, const std::string& s2): + s1(s1), + s2(s2) +{ +} + +bool Hashable::operator==(const Hashable& other) const +{ + return s1 == other.s1 && s2 == other.s2; +} + +std::size_t PortFieldHash::operator()(const Hashable& n) const +{ + std::size_t seed = 0; + + boost::hash_combine(seed, boost::hash_value(n.s1)); + boost::hash_combine(seed, boost::hash_value(n.s2)); + + return seed; +} + +} // namespace Antares::Solver 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/hashable.h b/src/solver/expressions/include/antares/solver/expressions/hashable.h new file mode 100644 index 0000000000..1548d6be65 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/hashable.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 + +namespace Antares::Solver +{ +class Hashable +{ +public: + Hashable(const std::string& s1, const std::string& s2); + ~Hashable() = default; + + bool operator==(const Hashable& other) const; + + const std::string& s1; + const std::string& s2; +}; + +struct PortFieldHash +{ + std::size_t operator()(const Hashable& n) const; +}; + +} // namespace Antares::Solver 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/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/simulation/sim_spread_generator.cpp b/src/solver/expressions/include/antares/solver/expressions/nodes/ComparisonNode.h similarity index 74% rename from src/solver/simulation/sim_spread_generator.cpp rename to src/solver/expressions/include/antares/solver/expressions/nodes/ComparisonNode.h index 734cb92da6..7fd6ac9cb2 100644 --- a/src/solver/simulation/sim_spread_generator.cpp +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/ComparisonNode.h @@ -18,23 +18,18 @@ ** 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_spread_generator.h" +#include -namespace SIM +namespace Antares::Solver::Nodes { -SpreadGenerator::SpreadGenerator(double range): - range_(range) +/** + * @brief Represents a comparison node in a syntax tree. + */ +class ComparisonNode: public BinaryNode { -} - -void SpreadGenerator::reset(unsigned int seed) -{ - mt_.reset(seed); -} - -double SpreadGenerator::generate() -{ - return mt_.next() * range_; -} -} // namespace SIM +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/simulation/sim_allocation_tableaux.cpp b/src/solver/expressions/include/antares/solver/expressions/nodes/DivisionNode.h similarity index 64% rename from src/solver/simulation/sim_allocation_tableaux.cpp rename to src/solver/expressions/include/antares/solver/expressions/nodes/DivisionNode.h index 4b8674639d..989324756e 100644 --- a/src/solver/simulation/sim_allocation_tableaux.cpp +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/DivisionNode.h @@ -18,21 +18,23 @@ ** 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/simulation/sim_extern_variables_globales.h" -#include "antares/study/simulation.h" - -using namespace Antares; - -void SIM_AllocationTableaux(const Data::Study& study) +namespace Antares::Solver::Nodes +{ +/** + * @brief Represents a division node in a syntax tree. + */ +class DivisionNode: public BinaryNode { - transitMoyenInterconnexionsRecalculQuadratique.resize(study.runtime->interconnectionsCount()); +public: + using BinaryNode::BinaryNode; - for (uint i = 0; i != study.runtime->interconnectionsCount(); i++) + std::string name() const override { - transitMoyenInterconnexionsRecalculQuadratique[i].assign(HOURS_PER_YEAR, 0.); + 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..7909f5ffb6 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/ExpressionsNodes.h @@ -0,0 +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 . +*/ +#pragma once +#include +#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..f9124c3d91 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/NodesForwardDeclaration.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 + +namespace Antares::Solver::Nodes +{ +class Node; +class BinaryNode; +class SumNode; +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; +class PortFieldSumNode; +} // 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..762f37a1c3 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/PortFieldNode.h @@ -0,0 +1,68 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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::Nodes +{ +/** + * @brief Represents a port field node in a syntax tree. + */ +class PortFieldNode: public Node, public Hashable +{ +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/PortFieldSumNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/PortFieldSumNode.h new file mode 100644 index 0000000000..eda6372e0f --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/PortFieldSumNode.h @@ -0,0 +1,68 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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::Nodes +{ +/** + * @brief Represents a port field node where the expression is a sum. + */ +class PortFieldSumNode: public Node, public Hashable +{ +public: + /** + * @brief Constructs a port field sum node with the specified port and field names. + * + * @param port_name The port name. + * @param field_name The field name. + */ + explicit PortFieldSumNode(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 PortFieldSumNode& other) const = default; + + std::string name() const override + { + return "PortFieldSumNode"; + } + +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/SumNode.h b/src/solver/expressions/include/antares/solver/expressions/nodes/SumNode.h new file mode 100644 index 0000000000..25a3ae5091 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/nodes/SumNode.h @@ -0,0 +1,88 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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/nodes/Node.h" + +namespace Antares::Solver::Nodes +{ + +template +concept NodePtr = std::same_as; + +template +requires(std::convertible_to && ...) +std::vector createVector(T first, Args... args) +{ + return std::vector{first, args...}; +} + +class SumNode: public Node +{ +public: + template + explicit SumNode(NodePtr... operands) + { + if constexpr (sizeof...(NodePtr)) + { + operands_ = createVector(static_cast(operands)...); + } + } + + /** + * @brief Constructs a sum node with the specified operands. + * + * @param operands The operands, collected in a vector + */ + explicit SumNode(const std::vector& operands); + + /** + * @brief Constructs a sum node with the specified operands. Vector is moved. + * + * @param operands The operands, collected in a vector + */ + explicit SumNode(std::vector&& operands): + operands_(std::move(operands)) + { + } + + /** + * @brief Retrieves the operands of the sum. + * + * @return A vector of pointers to the operands of the sum. + */ + const std::vector& getOperands() const; + + Node* operator[](std::size_t idx) const; + + size_t size() const; + + std::string name() const override + { + return "SumNode"; + } + +private: + std::vector operands_ = {}; +}; +} // 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/AstDOTStyleVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/AstDOTStyleVisitor.h new file mode 100644 index 0000000000..a8e4e1ff43 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/AstDOTStyleVisitor.h @@ -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 . +*/ +#pragma once + +#include +#include + +#include "antares/solver/expressions/visitors/NodeVisitor.h" + +namespace Antares::Solver::Visitors +{ +/** + * @struct BoxStyle + * @brief Represents the style attributes for a box in a graph. + * + * This structure defines the visual properties of a box, such as its color, + * shape, and style, which are used to customize the appearance of nodes in a graph. + */ +struct BoxStyle +{ + /** + * @brief The color of the box. + * + * This attribute specifies the color of the box. It is a string view that + * should contain a valid color name or code. + */ + std::string_view color; + + /** + * @brief The shape of the box. + * + * This attribute specifies the shape of the box. It is a string view that + * should contain a valid shape description (e.g., "circle", "rectangle"). + */ + std::string_view shape; + + /** + * @brief The style of the box. + * + * This attribute specifies the style of the box. It is a string view that + * should contain a valid style description (e.g., "filled", "dotted"). + */ + std::string_view style; +}; + +/** + * @class AstDOTStyleVisitor + * @brief A visitor class for generating DOT style output for ASTs (Abstract Syntax Trees). + * + * This class extends the `NodeVisitor` template class to produce a DOT representation + * of a given AST. The DOT format is commonly used for graph visualization tools, + * such as Graphviz. The visitor generates the graph structure, including nodes and + * edges, and outputs it to a stream. + * + * @tparam NodeVisitor A base class template for visiting nodes. + * @tparam std::ostream& The type of the output stream where the DOT representation is written. + * */ +class AstDOTStyleVisitor: public NodeVisitor +{ +public: + /** + * @brief Default constructor. + */ + AstDOTStyleVisitor() = default; + + /** + * @brief Begins a new tree graph. + * + * Initializes the DOT graph representation and sets the tree name. + * + * @param os The output stream to which the DOT representation is written. + * @param tree_name The name of the tree graph. Defaults to "ExpressionTree". + */ + void NewTreeGraph(std::ostream& os, const std::string& tree_name = "ExpressionTree"); + + /** + * @brief Ends the current tree graph. + * + * Finalizes the DOT graph representation. + * + * @param os The output stream to which the DOT representation is written. + */ + void EndTreeGraph(std::ostream& os); + + /** + * @brief Returns the name of this visitor. + * + * @return A string representing the name of the visitor. + */ + std::string name() const override; + + /** + * @brief Outputs the DOT representation of a node to a stream. + * + * This operator overload facilitates the use of the `AstDOTStyleVisitor` with a node + * for direct streaming of the DOT representation. + * + * @param os The output stream to which the DOT representation is written. + * @param root The root of the expression to be output. + */ + void operator()(std::ostream& os, Nodes::Node* root); + +private: + void visit(const Nodes::SumNode* node, std::ostream& os) override; + void visit(const Nodes::SubtractionNode* node, std::ostream& os) override; + void visit(const Nodes::MultiplicationNode* node, std::ostream& os) override; + void visit(const Nodes::DivisionNode* node, std::ostream& os) override; + void visit(const Nodes::EqualNode* node, std::ostream& os) override; + void visit(const Nodes::LessThanOrEqualNode* node, std::ostream& os) override; + void visit(const Nodes::GreaterThanOrEqualNode* node, std::ostream& os) override; + void visit(const Nodes::NegationNode* node, std::ostream& os) override; + void visit(const Nodes::VariableNode* node, std::ostream& os) override; + void visit(const Nodes::ParameterNode* node, std::ostream& os) override; + void visit(const Nodes::LiteralNode* node, std::ostream& os) override; + void visit(const Nodes::PortFieldNode* node, std::ostream& os) override; + void visit(const Nodes::PortFieldSumNode* node, std::ostream& os) override; + void visit(const Nodes::ComponentVariableNode* node, std::ostream& os) override; + void visit(const Nodes::ComponentParameterNode* node, std::ostream& os) override; + + void computeNumberNodesPerType(); + void makeLegend(std::ostream& os); + + /** + * @brief Retrieves a unique ID for a given node. + * + * Generates or retrieves a unique identifier for the specified node. + * + * @param node The node for which to get the ID. + * @return An integer representing the unique ID of the node. + */ + unsigned int getNodeID(const Nodes::Node* node); + + /** + * @brief Emits a node to the output stream. + * + * Writes the DOT representation of a node to the output stream with its associated label + * and style. + * + * @param id The unique ID of the node. + * @param label The label to be used for the node. + * @param box_style The style to be applied to the node's box. + * @param os The output stream to which the node representation is written. + */ + void emitNode(unsigned int id, + const std::string& label, + const BoxStyle& box_style, + std::ostream& os); + + /** + * @brief Processes a binary operation node. + * + * Handles the specific case of binary operation nodes by emitting the appropriate + * DOT representation. + * + * @param node The binary operation node to be processed. + * @param label The label to be used for the node. + * @param box_style The style to be applied to the node's box. + * @param os The output stream to which the node representation is written. + */ + void processBinaryOperation(const Nodes::BinaryNode* node, + const std::string& label, + const BoxStyle& box_style, + std::ostream& os); + + /** + * @brief A map of nodes to their unique IDs. + * + * This map is used to keep track of assigned IDs for each node in the AST. + */ + std::map nodeIds_; + + /** + * @brief A map associating a number of instances to a type name. + * + * This map is used to keep track of assigned IDs for each node in the AST. + */ + std::map nbNodesPerType_; + + /** + * @brief Counter for generating unique node IDs. + * + * This counter is incremented each time a new node ID is needed. + */ + unsigned int nodeCount_ = 0; +}; +} // namespace Antares::Solver::Visitors 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..ff5ac538a2 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/CloneVisitor.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 "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::SumNode* 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::PortFieldSumNode* 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..ec19095b02 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/CompareVisitor.h @@ -0,0 +1,55 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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::SumNode* 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::PortFieldSumNode* 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..5dbc1c06ed --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/EvalVisitor.h @@ -0,0 +1,78 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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::SumNode* 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::PortFieldSumNode* 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..8355d27734 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/LinearityVisitor.h @@ -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 "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::SumNode* 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::PortFieldSumNode* 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..9b88019376 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/NodeVisitor.h @@ -0,0 +1,273 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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::SumNode, + Nodes::SubtractionNode, + Nodes::MultiplicationNode, + Nodes::DivisionNode, + Nodes::EqualNode, + Nodes::LessThanOrEqualNode, + Nodes::GreaterThanOrEqualNode, + Nodes::NegationNode, + Nodes::ParameterNode, + Nodes::VariableNode, + Nodes::LiteralNode, + Nodes::PortFieldNode, + Nodes::PortFieldSumNode, + 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 a SumNode and processes its children. + * + * @param node A pointer to the SumNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the SumNode. + */ + virtual R visit(const Nodes::SumNode*, 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 PortFieldSumNode. + * + * @param node A pointer to the PortFieldSumNode to be visited. + * @param args Additional arguments to be passed to the visitor's methods. + * + * @return The result of processing the PortFieldSumNode. + */ + virtual R visit(const Nodes::PortFieldSumNode*, 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/PortFieldSubstitutionVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/PortFieldSubstitutionVisitor.h new file mode 100644 index 0000000000..ce897945ea --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/PortFieldSubstitutionVisitor.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/CloneVisitor.h" + +namespace Antares::Solver::Visitors +{ + +/** + * @brief Represents the context for performing substitutions in a syntax tree. + */ +struct PortFieldSubstitutionContext +{ + std::unordered_map portfield; +}; + +/** + * @brief Represents a visitor for substituting portfield nodes in a syntax tree. + */ +class PortFieldSubstitutionVisitor: public CloneVisitor +{ +public: + PortFieldSubstitutionVisitor(Registry& registry, + PortFieldSubstitutionContext& ctx); + + PortFieldSubstitutionContext& ctx_; + std::string name() const override; + +private: + // Only override visit method for PortField, clone the rest + Nodes::Node* visit(const Nodes::PortFieldNode* node) override; +}; +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/include/antares/solver/expressions/visitors/PortFieldSumSubstitutionVisitor.h b/src/solver/expressions/include/antares/solver/expressions/visitors/PortFieldSumSubstitutionVisitor.h new file mode 100644 index 0000000000..4444da94e6 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/PortFieldSumSubstitutionVisitor.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 + +#include "antares/solver/expressions/visitors/CloneVisitor.h" + +namespace Antares::Solver::Visitors +{ + +/** + * @brief Represents the context for performing substitutions in a syntax tree. + */ +struct PortFieldSumSubstitutionContext +{ + std::unordered_map, PortFieldHash> + portfieldSum; +}; + +/** + * @brief Represents a visitor for substituting portfield sum nodes in a syntax tree. + */ +class PortFieldSumSubstitutionVisitor: public CloneVisitor +{ +public: + PortFieldSumSubstitutionVisitor(Registry& registry, + PortFieldSumSubstitutionContext& ctx); + + std::string name() const override; + +private: + // Only override visit method for PortFieldSum, clone the rest + Nodes::Node* visit(const Nodes::PortFieldSumNode* node) override; + + Registry& registry_; + PortFieldSumSubstitutionContext& ctx_; +}; +} // 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..dfcca80823 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/PrintVisitor.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/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::SumNode* 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::PortFieldSumNode* 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..a52fd45e04 --- /dev/null +++ b/src/solver/expressions/include/antares/solver/expressions/visitors/TimeIndexVisitor.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 "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::SumNode* 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::PortFieldSumNode* 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/iterators/pre-order.cpp b/src/solver/expressions/iterators/pre-order.cpp new file mode 100644 index 0000000000..57d27203a0 --- /dev/null +++ b/src/solver/expressions/iterators/pre-order.cpp @@ -0,0 +1,107 @@ +#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()}; + } + else if (auto* sum = dynamic_cast(node)) + { + return sum->getOperands(); + } + 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/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..15ca1ff39c --- /dev/null +++ b/src/solver/expressions/nodes/PortFieldNode.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 +{ +PortFieldNode::PortFieldNode(const std::string& port_name, const std::string& field_name): + Hashable(port_name_, 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/PortFieldSumNode.cpp b/src/solver/expressions/nodes/PortFieldSumNode.cpp new file mode 100644 index 0000000000..b396ebfbb6 --- /dev/null +++ b/src/solver/expressions/nodes/PortFieldSumNode.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 +{ +PortFieldSumNode::PortFieldSumNode(const std::string& port_name, const std::string& field_name): + Hashable(port_name_, field_name_), + port_name_(port_name), + field_name_(field_name) +{ +} + +const std::string& PortFieldSumNode::getPortName() const +{ + return port_name_; +} + +const std::string& PortFieldSumNode::getFieldName() const +{ + return field_name_; +} +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/nodes/SumNode.cpp b/src/solver/expressions/nodes/SumNode.cpp new file mode 100644 index 0000000000..ab1050a7da --- /dev/null +++ b/src/solver/expressions/nodes/SumNode.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 + +namespace Antares::Solver::Nodes +{ + +SumNode::SumNode(const std::vector& operands): + operands_(operands) +{ +} + +const std::vector& SumNode::getOperands() const +{ + return operands_; +} + +size_t SumNode::size() const +{ + return operands_.size(); +} + +Node* SumNode::operator[](std::size_t idx) const +{ + return operands_[idx]; +} + +} // namespace Antares::Solver::Nodes diff --git a/src/solver/simulation/sim_variables_globales.cpp b/src/solver/expressions/nodes/UnaryNode.cpp similarity index 79% rename from src/solver/simulation/sim_variables_globales.cpp rename to src/solver/expressions/nodes/UnaryNode.cpp index 252c937631..c52b2d973b 100644 --- a/src/solver/simulation/sim_variables_globales.cpp +++ b/src/solver/expressions/nodes/UnaryNode.cpp @@ -18,8 +18,17 @@ ** 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/sim_structure_donnees.h" -#include "antares/solver/simulation/sim_structure_probleme_economique.h" +namespace Antares::Solver::Nodes +{ +UnaryNode::UnaryNode(Node* n): + child_(n) +{ +} -std::vector> transitMoyenInterconnexionsRecalculQuadratique; +Node* UnaryNode::child() const +{ + return child_; +} +} // namespace Antares::Solver::Nodes diff --git a/src/solver/expressions/visitors/AstDOTStyleVisitor.cpp b/src/solver/expressions/visitors/AstDOTStyleVisitor.cpp new file mode 100644 index 0000000000..fb74a129df --- /dev/null +++ b/src/solver/expressions/visitors/AstDOTStyleVisitor.cpp @@ -0,0 +1,267 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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/AstDOTStyleVisitor.h" + +#include + +#include "antares/solver/expressions/nodes/ExpressionsNodes.h" + +namespace Antares::Solver::Visitors +{ +namespace NodeStyle +{ +static constexpr BoxStyle SumStyle{"aqua", "hexagon", "filled, solid"}; +static constexpr BoxStyle BinaryStyle{"aqua", "oval", "filled, rounded"}; +static constexpr BoxStyle ComparisonStyle{"yellow", "diamond", "filled"}; +static constexpr BoxStyle NegationStyle{"tomato", "invtriangle", "filled, solid"}; +static constexpr BoxStyle LiteralStyle{"lightgray", "box", "filled, solid"}; +static constexpr BoxStyle VariableStyle{"gold", "box", "filled, solid"}; +static constexpr BoxStyle ParameterStyle{"wheat", "box", "filled, solid"}; +static constexpr BoxStyle ComponentParameterStyle{"springgreen", "octagon", "filled, solid"}; +static constexpr BoxStyle ComponentVariableStyle{"goldenrod", "octagon", "filled, solid"}; +static constexpr BoxStyle PortFieldStyle{"olive", "component", "filled, solid"}; +} // namespace NodeStyle + +void makeLegendTitle(std::ostream& os) +{ + os << "subgraph cluster_legend {\n" + << "label = \"Legend\";\n" + << "style = dashed;\n" + << "fontsize = 16;\n" + << "color = lightgrey;\n" + << "node [shape=plaintext];\n\n"; +} + +void ProcessElementLegend(const std::string& element_name, size_t size, std::ostream& os) +{ + os << "legend_" << element_name << " [ label =\" " << element_name << ": " << size << "\"]\n"; +} + +void AddFiliation(std::ostream& os, const std::string& parent_id, const std::string& child_id) +{ + os << "legend_" << parent_id << " -> " << "legend_" << child_id << " [style=invis];\n"; +} + +void AstDOTStyleVisitor::makeLegend(std::ostream& os) +{ + if (nbNodesPerType_.empty()) + { + return; + } + + ProcessElementLegend(nbNodesPerType_.begin()->first, nbNodesPerType_.begin()->second, os); + for (auto it = std::next(nbNodesPerType_.begin()); it != nbNodesPerType_.end(); ++it) + { + auto prev_it = std::prev(it); + AddFiliation(os, prev_it->first, it->first); + ProcessElementLegend(it->first, it->second, os); + } + os << "}\n"; +} + +void AstDOTStyleVisitor::visit(const Nodes::SumNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, "+", NodeStyle::SumStyle, os); + for (auto* child: node->getOperands()) + { + auto childId = getNodeID(child); + os << " " << id << " -> " << childId << ";\n"; + dispatch(child, os); + } +} + +void AstDOTStyleVisitor::visit(const Nodes::SubtractionNode* node, std::ostream& os) +{ + processBinaryOperation(node, "-", NodeStyle::BinaryStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::MultiplicationNode* node, std::ostream& os) +{ + processBinaryOperation(node, "*", NodeStyle::BinaryStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::DivisionNode* node, std::ostream& os) +{ + processBinaryOperation(node, "/", NodeStyle::BinaryStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::EqualNode* node, std::ostream& os) +{ + processBinaryOperation(node, "==", NodeStyle::ComparisonStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::LessThanOrEqualNode* node, std::ostream& os) +{ + processBinaryOperation(node, "<=", NodeStyle::ComparisonStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::GreaterThanOrEqualNode* node, std::ostream& os) +{ + processBinaryOperation(node, ">=", NodeStyle::ComparisonStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::VariableNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, "Var(" + node->value() + ")", NodeStyle::VariableStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::ParameterNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, "Param(" + node->value() + ")", NodeStyle::ParameterStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::LiteralNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, std::to_string(node->value()), NodeStyle::LiteralStyle, os); +} + +void AstDOTStyleVisitor::visit(const Nodes::NegationNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, "-", NodeStyle::NegationStyle, os); + auto childId = getNodeID(node->child()); + os << " " << id << " -> " << childId << ";\n"; + dispatch(node->child(), os); +} + +void AstDOTStyleVisitor::visit(const Nodes::PortFieldNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, + "PF(" + node->getPortName() + "," + node->getFieldName() + ")", + NodeStyle::PortFieldStyle, + os); +} + +void AstDOTStyleVisitor::visit(const Nodes::PortFieldSumNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, + "PFSUM(" + node->getPortName() + "," + node->getFieldName() + ")", + NodeStyle::PortFieldStyle, + os); +} + +void AstDOTStyleVisitor::visit(const Nodes::ComponentVariableNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, + "CV(" + node->getComponentId() + "," + node->getComponentName() + ")", + NodeStyle::ComponentVariableStyle, + os); +} + +void AstDOTStyleVisitor::visit(const Nodes::ComponentParameterNode* node, std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, + "CP(" + node->getComponentId() + "," + node->getComponentName() + ")", + NodeStyle::ComponentParameterStyle, + os); +} + +std::string AstDOTStyleVisitor::name() const +{ + return "AstDOTStyleVisitor"; +} + +unsigned int AstDOTStyleVisitor::getNodeID(const Nodes::Node* node) +{ + if (nodeIds_.find(node) == nodeIds_.end()) + { + nodeIds_[node] = ++nodeCount_; + } + return nodeIds_[node]; +} + +void AstDOTStyleVisitor::computeNumberNodesPerType() +{ + for (const auto& [node, _]: nodeIds_) + { + ++nbNodesPerType_[node->name()]; + } +} + +void AstDOTStyleVisitor::emitNode(unsigned int id, + const std::string& label, + const BoxStyle& box_style, + std::ostream& os) +{ + os << " " << id << " [label=\"" << label << "\", shape=\"" << box_style.shape << "\", style=\"" + << box_style.style << "\", color=\"" << box_style.color << "\"];\n"; +} + +// Process binary operation nodes like Add, Subtract, etc. +void AstDOTStyleVisitor::processBinaryOperation(const Nodes::BinaryNode* node, + const std::string& label, + const BoxStyle& box_style, + std::ostream& os) +{ + auto id = getNodeID(node); + emitNode(id, label, box_style, os); + + const Nodes::Node* left = node->left(); + const Nodes::Node* right = node->right(); + + auto leftId = getNodeID(left); + auto rightId = getNodeID(right); + + os << " " << id << " -> " << leftId << ";\n"; + os << " " << id << " -> " << rightId << ";\n"; + + dispatch(left, os); + dispatch(right, os); +} + +void AstDOTStyleVisitor::NewTreeGraph(std::ostream& os, const std::string& tree_name) +{ + os << "digraph " + tree_name + " {\n"; + os << "node[style = filled]\n"; +} + +void AstDOTStyleVisitor::EndTreeGraph(std::ostream& os) +{ + computeNumberNodesPerType(); + + // Graph title showing the total number of nodes + os << "label=\"AST Diagram(Total nodes : " << nodeCount_ << ")\"\n"; + os << "labelloc = \"t\"\n"; + + makeLegendTitle(os); + makeLegend(os); + os << "}\n"; + + nodeCount_ = 0; + nodeIds_.clear(); + nbNodesPerType_.clear(); +} + +void AstDOTStyleVisitor::operator()(std::ostream& os, Nodes::Node* root) +{ + NewTreeGraph(os); + dispatch(root, os); + EndTreeGraph(os); +} +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/CloneVisitor.cpp b/src/solver/expressions/visitors/CloneVisitor.cpp new file mode 100644 index 0000000000..7d538c0800 --- /dev/null +++ b/src/solver/expressions/visitors/CloneVisitor.cpp @@ -0,0 +1,128 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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::SumNode* node) +{ + std::vector clonedOperands; + clonedOperands.reserve(node->size()); + for (auto* operand: node->getOperands()) + { + clonedOperands.push_back(dispatch(operand)); + } + // Give ownership of clonedOperands to the caller + return registry_.create(std::move(clonedOperands)); +} + +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* portfieldNode) +{ + return registry_.create(portfieldNode->getPortName(), + portfieldNode->getFieldName()); +} + +Nodes::Node* CloneVisitor::visit(const Nodes::PortFieldSumNode* portfieldSumNode) +{ + return registry_.create(portfieldSumNode->getPortName(), + portfieldSumNode->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..5fa4a090e6 --- /dev/null +++ b/src/solver/expressions/visitors/CompareVisitor.cpp @@ -0,0 +1,157 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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::SumNode* node, const Nodes::Node* other) +{ + if (const auto* other_node = dynamic_cast(other)) + { + if (node->size() != other_node->size()) + { + return false; + } + for (std::size_t i = 0; i < node->size(); ++i) + { + if (!dispatch(node->getOperands()[i], other_node->getOperands()[i])) + { + return false; + } + } + return true; + } + return false; +} + +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::PortFieldSumNode* 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..4d0b45e119 --- /dev/null +++ b/src/solver/expressions/visitors/EvalVisitor.cpp @@ -0,0 +1,148 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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 + +#include + +namespace Antares::Solver::Visitors +{ +EvalVisitor::EvalVisitor(EvaluationContext context): + context_(std::move(context)) +{ +} + +double EvalVisitor::visit(const Nodes::SumNode* node) +{ + auto operands = node->getOperands(); + return std::accumulate(std::begin(operands), + std::end(operands), + 0, + [this](double sum, Nodes::Node* operand) + { return sum + dispatch(operand); }); +} + +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::PortFieldSumNode* 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..51fddfaffd --- /dev/null +++ b/src/solver/expressions/visitors/LinearityVisitor.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 "antares/solver/expressions/visitors/LinearityVisitor.h" + +#include + +#include +#include + +namespace Antares::Solver::Visitors +{ + +LinearStatus LinearityVisitor::visit(const Nodes::SumNode* node) +{ + auto operands = node->getOperands(); + return std::accumulate(std::begin(operands), + std::end(operands), + LinearStatus::CONSTANT, + [this](LinearStatus sum, Nodes::Node* operand) + { return sum + dispatch(operand); }); +} + +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(const Nodes::PortFieldSumNode*) +{ + 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/PortFieldSubstitutionVisitor.cpp b/src/solver/expressions/visitors/PortFieldSubstitutionVisitor.cpp new file mode 100644 index 0000000000..d7dc95c5f1 --- /dev/null +++ b/src/solver/expressions/visitors/PortFieldSubstitutionVisitor.cpp @@ -0,0 +1,50 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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 +{ + +PortFieldSubstitutionVisitor::PortFieldSubstitutionVisitor(Registry& registry, + PortFieldSubstitutionContext& ctx): + CloneVisitor(registry), + ctx_(ctx) +{ +} + +Nodes::Node* PortFieldSubstitutionVisitor::visit(const Nodes::PortFieldNode* node) +{ + if (auto it = ctx_.portfield.find(*node); it != ctx_.portfield.end()) + { + return it->second; + } + + return CloneVisitor::visit(node); +} + +std::string PortFieldSubstitutionVisitor::name() const +{ + return "PortFieldSubstitutionVisitor"; +} + +} // namespace Antares::Solver::Visitors diff --git a/src/solver/expressions/visitors/PortFieldSumSubstitutionVisitor.cpp b/src/solver/expressions/visitors/PortFieldSumSubstitutionVisitor.cpp new file mode 100644 index 0000000000..cc984e1a43 --- /dev/null +++ b/src/solver/expressions/visitors/PortFieldSumSubstitutionVisitor.cpp @@ -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 . +*/ +#include +#include + +namespace Antares::Solver::Visitors +{ + +PortFieldSumSubstitutionVisitor::PortFieldSumSubstitutionVisitor( + Registry& registry, + PortFieldSumSubstitutionContext& ctx): + CloneVisitor(registry), + registry_(registry), + ctx_(ctx) +{ +} + +Nodes::Node* PortFieldSumSubstitutionVisitor::visit(const Nodes::PortFieldSumNode* node) +{ + if (auto it = ctx_.portfieldSum.find(*node); it != ctx_.portfieldSum.end()) + { + return registry_.create(it->second); + } + + return CloneVisitor::visit(node); +} + +std::string PortFieldSumSubstitutionVisitor::name() const +{ + return "PortFieldSumSubstitutionVisitor"; +} + +} // 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..6e3a2992b3 --- /dev/null +++ b/src/solver/expressions/visitors/PrintVisitor.cpp @@ -0,0 +1,118 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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::Visitors +{ +std::string PrintVisitor::visit(const Nodes::SumNode* node) +{ + auto operands = node->getOperands(); + if (operands.empty()) + { + return "()"; + } + return std::accumulate(std::next(std::begin(operands)), + std::end(operands), + "(" + dispatch(operands[0]), + [this](std::string sum, Nodes::Node* operand) + { return sum + "+" + dispatch(operand); }) + + ")"; +} + +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::PortFieldSumNode* 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..c81430e67d --- /dev/null +++ b/src/solver/expressions/visitors/TimeIndexVisitor.cpp @@ -0,0 +1,120 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.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 +{ + +TimeIndex TimeIndexVisitor::visit(const Nodes::SumNode* node) +{ + auto operands = node->getOperands(); + return std::accumulate(std::begin(operands), + std::end(operands), + TimeIndex::CONSTANT_IN_TIME_AND_SCENARIO, + [this](TimeIndex sum, Nodes::Node* operand) + { return sum | dispatch(operand); }); +} + +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::PortFieldSumNode* 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/solver/hydro/daily/h2o_j_resoudre_le_probleme_lineaire.cpp b/src/solver/hydro/daily/h2o_j_resoudre_le_probleme_lineaire.cpp index 1786428cef..549fc1878a 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 @@ -19,17 +19,11 @@ ** along with Antares_Simulator. If not, see . */ +#include + #include "antares/solver/hydro/daily/h2o_j_donnees_mensuelles.h" #include "antares/solver/hydro/daily/h2o_j_fonctions.h" -#ifdef _MSC_VER -#define SNPRINTF sprintf_s -#else -#define SNPRINTF snprintf -#endif - -#include - void H2O_J_ResoudreLeProblemeLineaire(DONNEES_MENSUELLES* DonneesMensuelles, int NumeroDeProbleme) { PROBLEME_HYDRAULIQUE& ProblemeHydraulique = DonneesMensuelles->ProblemeHydraulique; 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 a0366dce53..80060310d3 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 @@ -22,12 +22,6 @@ #include "antares/solver/hydro/daily2/h2o2_j_donnees_mensuelles.h" #include "antares/solver/hydro/daily2/h2o2_j_fonctions.h" -#ifdef _MSC_VER -#define SNPRINTF sprintf_s -#else -#define SNPRINTF snprintf -#endif - void H2O2_J_ResoudreLeProblemeLineaire(DONNEES_MENSUELLES_ETENDUES& DonneesMensuelles, int NumeroDeProbleme) { 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 8f4cf12d01..63c20bd263 100644 --- a/src/solver/hydro/include/antares/solver/hydro/management/management.h +++ b/src/solver/hydro/include/antares/solver/hydro/management/management.h @@ -23,13 +23,11 @@ #include -#include - #include #include #include +#include #include "antares/date/date.h" -#include "antares/solver/simulation/sim_structure_donnees.h" #include "antares/writer/i_writer.h" namespace Antares @@ -113,7 +111,6 @@ class HydroManagement final const Data::AreaList& areas_; const Date::Calendar& calendar_; const Data::Parameters& parameters_; - unsigned int maxNbYearsInParallel_ = 0; Solver::IResultWriter& resultWriter_; HYDRO_VENTILATION_RESULTS ventilationResults_; diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index 254ab2b1b2..8bf59df763 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -21,29 +21,20 @@ #include #include +#include #include -#include #include -#include -#include -#include - #include #include -#include -#include #include #include "antares/solver/hydro/daily/h2o_j_donnees_mensuelles.h" #include "antares/solver/hydro/daily/h2o_j_fonctions.h" #include "antares/solver/hydro/daily2/h2o2_j_donnees_mensuelles.h" #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" - -using namespace Yuni; -#define SEP IO::Separator +namespace fs = std::filesystem; namespace { @@ -137,8 +128,8 @@ struct DebugData void writeTurb(const std::string filename, uint y) const { - std::ostringstream buffer, path; - path << "debug" << SEP << "solver" << SEP << (1 + y) << SEP << filename; + std::ostringstream buffer; + auto path = fs::path("debug") / "solver" / std::to_string(1 + y) / filename; buffer << "\tTurbine\t\t\tOPP\t\t\t\tTurbine Cible\tDLE\t\t\t\tDLN\n"; for (uint day = 0; day != 365; ++day) @@ -150,7 +141,7 @@ struct DebugData buffer << '\n'; } auto buffer_str = buffer.str(); - pWriter.addEntryFromBuffer(path.str(), buffer_str); + pWriter.addEntryFromBuffer(path.string(), buffer_str); } void writeDailyDebugData(const Date::Calendar& calendar, @@ -158,9 +149,9 @@ struct DebugData uint y, const Data::AreaName& areaName) const { - std::ostringstream buffer, path; - path << "debug" << SEP << "solver" << SEP << (1 + y) << SEP << "daily." << areaName.c_str() - << ".txt"; + std::ostringstream buffer; + auto path = fs::path("debug") / "solver" / std::to_string(1 + y) / "daily." + / areaName.c_str() / ".txt"; buffer << "\tNiveau init : " << hydro_specific.monthly[initReservoirLvlMonth].MOL << "\n"; for (uint month = 0; month != MONTHS_PER_YEAR; ++month) @@ -219,7 +210,7 @@ struct DebugData } } auto buffer_str = buffer.str(); - pWriter.addEntryFromBuffer(path.str(), buffer_str); + pWriter.addEntryFromBuffer(path.string(), buffer_str); } }; diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 0ad4d4a357..b4327deee3 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -23,15 +23,8 @@ #include #include -#include -#include - -#include #include -#include -#include -#include "antares/solver/simulation/sim_extern_variables_globales.h" namespace Antares { diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index 8afcd0e26f..62658e277d 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -18,31 +18,22 @@ ** 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 -#include -#include - #include -#include -#include #include "antares/solver/hydro/management/management.h" #include "antares/solver/hydro/monthly/h2o_m_donnees_annuelles.h" #include "antares/solver/hydro/monthly/h2o_m_fonctions.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" - -using namespace Yuni; -#define SEP IO::Separator +namespace fs = std::filesystem; namespace Antares { -template static void CheckHydroAllocationProblem(Data::Area& area, - ProblemT& problem, + DONNEES_ANNUELLES& problem, int initLevelMonth, double lvi) { @@ -207,10 +198,9 @@ void HydroManagement::prepareMonthlyOptimalGenerations(const double* random_rese { case OUI: { - if (Logs::Verbosity::Debug::enabled) - { - CheckHydroAllocationProblem(area, problem, initReservoirLvlMonth, lvi); - } +#ifndef NDEBUG + CheckHydroAllocationProblem(area, problem, initReservoirLvlMonth, lvi); +#endif for (uint month = 0; month != MONTHS_PER_YEAR; ++month) { @@ -270,9 +260,9 @@ void HydroManagement::prepareMonthlyOptimalGenerations(const double* random_rese #endif if (parameters_.hydroDebug) { - std::ostringstream buffer, path; - path << "debug" << SEP << "solver" << SEP << (1 + y) << SEP << "monthly." << area.name - << ".txt"; + std::ostringstream buffer; + auto path = fs::path("debug") / "solver" / std::to_string(1 + y) / "monthly." + / area.name.c_str() / ".txt"; if (area.hydro.reservoirManagement) buffer << "Initial Reservoir Level\t" << lvi << "\n"; @@ -314,7 +304,7 @@ void HydroManagement::prepareMonthlyOptimalGenerations(const double* random_rese buffer << '\n'; } auto content = buffer.str(); - resultWriter_.addEntryFromBuffer(path.str(), content); + resultWriter_.addEntryFromBuffer(path.string(), content); } indexArea++; }); 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 f65ec03e6e..62dfb84121 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 @@ -19,17 +19,11 @@ ** along with Antares_Simulator. If not, see . */ +#include + #include "antares/solver/hydro/monthly/h2o_m_donnees_annuelles.h" #include "antares/solver/hydro/monthly/h2o_m_fonctions.h" -#ifdef _MSC_VER -#define SNPRINTF sprintf_s -#else -#define SNPRINTF snprintf -#endif - -#include - void H2O_M_ResoudreLeProblemeLineaire(DONNEES_ANNUELLES& DonneesAnnuelles, int NumeroDeReservoir) { PROBLEME_HYDRAULIQUE& ProblemeHydraulique = DonneesAnnuelles.ProblemeHydraulique; 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..a323b30be2 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( @@ -51,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) @@ -69,8 +72,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 +80,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/solver/main.cpp b/src/solver/main.cpp index 169b29321a..a0f012a9ef 100644 --- a/src/solver/main.cpp +++ b/src/solver/main.cpp @@ -105,7 +105,7 @@ void logAbortion() /*! ** \brief main */ -int main(int argc, char** argv) +int main(int argc, const char** argv) { try { 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/misc/include/antares/solver/misc/write-command-line.h b/src/solver/misc/include/antares/solver/misc/write-command-line.h index fa779ac257..b561d55efb 100644 --- a/src/solver/misc/include/antares/solver/misc/write-command-line.h +++ b/src/solver/misc/include/antares/solver/misc/write-command-line.h @@ -22,5 +22,5 @@ namespace Antares::Solver { -void WriteCommandLineIntoLogs(int argc, char** argv); +void WriteCommandLineIntoLogs(int argc, const char** argv); } diff --git a/src/solver/misc/options.cpp b/src/solver/misc/options.cpp index 960b0dda6c..49193b59b0 100644 --- a/src/solver/misc/options.cpp +++ b/src/solver/misc/options.cpp @@ -76,19 +76,11 @@ std::unique_ptr CreateParser(Settings& settings, StudyLoad "force-parallel", "Override the max number of years computed simultaneously"); - // add option for ortools use - // --use-ortools - parser->addFlag(options.optOptions.ortoolsUsed, - ' ', - "use-ortools", - "Use ortools library to launch solver"); - //--ortools-solver parser->add(options.optOptions.ortoolsSolver, ' ', - "ortools-solver", - "Ortools solver used for simulation (only available with use-ortools " - "option)\nAvailable solver list : " + "solver", + "Solver used for simulation\nAvailable solver list : " + availableOrToolsSolversString()); //--xpress-parameters @@ -266,18 +258,15 @@ void checkAndCorrectSettingsAndOptions(Settings& settings, Data::StudyLoadOption void checkOrtoolsSolver(const Antares::Solver::Optimization::OptimizationOptions& optOptions) { - if (optOptions.ortoolsUsed) - { - const std::string& solverName = optOptions.ortoolsSolver; - const std::list availableSolverList = getAvailableOrtoolsSolverName(); + const std::string& solverName = optOptions.ortoolsSolver; + const std::list availableSolverList = getAvailableOrtoolsSolverName(); - // Check if solver is available - bool found = (std::find(availableSolverList.begin(), availableSolverList.end(), solverName) - != availableSolverList.end()); - if (!found) - { - throw Error::InvalidSolver(optOptions.ortoolsSolver, availableOrToolsSolversString()); - } + // Check if solver is available + bool found = (std::find(availableSolverList.begin(), availableSolverList.end(), solverName) + != availableSolverList.end()); + if (!found) + { + throw Error::InvalidSolver(optOptions.ortoolsSolver, availableOrToolsSolversString()); } } diff --git a/src/solver/misc/write-command-line.cpp b/src/solver/misc/write-command-line.cpp index 420999a51b..593c170657 100644 --- a/src/solver/misc/write-command-line.cpp +++ b/src/solver/misc/write-command-line.cpp @@ -24,7 +24,7 @@ namespace Antares::Solver { -void WriteCommandLineIntoLogs(int argc, char** argv) +void WriteCommandLineIntoLogs(int argc, const char** argv) { std::ostringstream buffer; for (int arg = 0; arg < argc; ++arg) 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..41789ae9cb --- /dev/null +++ b/src/solver/modeler/api/CMakeLists.txt @@ -0,0 +1,28 @@ +set(PROJ modeler_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 + linearProblemBuilder.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/simulation/include/antares/solver/simulation/adequacy_mode.h b/src/solver/modeler/api/include/antares/solver/modeler/api/hasBounds.h similarity index 58% rename from src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h rename to src/solver/modeler/api/include/antares/solver/modeler/api/hasBounds.h index 66734027b9..474a34d74f 100644 --- a/src/solver/simulation/include/antares/solver/simulation/adequacy_mode.h +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/hasBounds.h @@ -1,4 +1,3 @@ - /* * Copyright 2007-2024, RTE (https://www.rte-france.com) * See AUTHORS.txt @@ -22,17 +21,22 @@ #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::Modeler::Api +{ -namespace Antares::Solver +/// Used to handle bounds for IMipVariable and IMipConstraint +class IHasBounds { -void runSimulationInAdequacyMode(Antares::Data::Study& study, - const Settings& settings, - Benchmarking::DurationCollector& durationCollector, - IResultWriter& resultWriter, - Benchmarking::OptimizationInfo& info, - Simulation::ISimulationObserver& simulationObserver); -} +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/libs/antares/study/include/antares/study/runtime/runtime.hxx b/src/solver/modeler/api/include/antares/solver/modeler/api/hasName.h similarity index 73% rename from src/libs/antares/study/include/antares/study/runtime/runtime.hxx rename to src/solver/modeler/api/include/antares/solver/modeler/api/hasName.h index 0e04ed3b93..0003dd6843 100644 --- a/src/libs/antares/study/include/antares/study/runtime/runtime.hxx +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/hasName.h @@ -18,20 +18,20 @@ * 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 +#pragma once + +#include + +namespace Antares::Solver::Modeler::Api { -} -#endif -} // namespace Data -} // namespace Antares +/// Inherited by IMipVariable and IMipConstraint +class IHasName +{ +public: + virtual ~IHasName() = default; + virtual const std::string& getName() const = 0; +}; -#endif // __ANTARES_LIBS_STUDY_RUNTIME_RUNTIME_INFOS_HXX__ +} // 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..38006291e0 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblem.h @@ -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 . + */ + +#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; + virtual int variableCount() 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; + virtual int constraintCount() 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..c5b4419113 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemBuilder.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 "linearProblemFiller.h" + +namespace Antares::Solver::Modeler::Api +{ + +class LinearProblemBuilder +{ +public: + explicit LinearProblemBuilder(const std::vector& fillers); + void build(ILinearProblem& pb, LinearProblemData& data); + +private: + const std::vector& fillers_; +}; + +} // 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..aad1fa3ce6 --- /dev/null +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/linearProblemFiller.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 +#include + +namespace Antares::Solver::Modeler::Api +{ + +class LinearProblemFiller +{ +public: + virtual void addVariables(ILinearProblem& pb, LinearProblemData& data) = 0; + virtual void addConstraints(ILinearProblem& pb, LinearProblemData& data) = 0; + virtual void addObjective(ILinearProblem& pb, LinearProblemData& data) = 0; + virtual ~LinearProblemFiller() = default; +}; + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h b/src/solver/modeler/api/include/antares/solver/modeler/api/mipConstraint.h similarity index 73% rename from src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h rename to src/solver/modeler/api/include/antares/solver/modeler/api/mipConstraint.h index c28ec9a75a..71baf95cd8 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/mipConstraint.h @@ -21,21 +21,17 @@ #pragma once -#include +#include "mipVariable.h" -namespace SIM +namespace Antares::Solver::Modeler::Api { -class SpreadGenerator -{ - static constexpr double rangeDefault = 1.e-3; +class IMipConstraint: public IHasBounds, public IHasName +{ public: - explicit SpreadGenerator(double range = rangeDefault); - void reset(unsigned int seed); - double generate(); + virtual void setCoefficient(IMipVariable* var, double coefficient) = 0; -private: - Antares::MersenneTwister mt_; - const double range_; + virtual double getCoefficient(IMipVariable* var) = 0; }; -} // namespace SIM + +} // 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/simulation/include/antares/solver/simulation/sim_extern_variables_globales.h b/src/solver/modeler/api/include/antares/solver/modeler/api/mipVariable.h similarity index 69% rename from src/solver/simulation/include/antares/solver/simulation/sim_extern_variables_globales.h rename to src/solver/modeler/api/include/antares/solver/modeler/api/mipVariable.h index d6c526b37e..1caac002bf 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_extern_variables_globales.h +++ b/src/solver/modeler/api/include/antares/solver/modeler/api/mipVariable.h @@ -18,17 +18,17 @@ * 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__ -#include "antares/solver/simulation/sim_structure_probleme_economique.h" +#pragma once -#include "sim_structure_donnees.h" +#include "hasBounds.h" +#include "hasName.h" -/* Valeurs generees de maniere aleatoire */ +namespace Antares::Solver::Modeler::Api +{ -/* Resultats */ -/*-Economique-*/ -extern std::vector> transitMoyenInterconnexionsRecalculQuadratique; +class IMipVariable: public IHasBounds, public IHasName +{ +}; -#endif /* __SOLVER_SIMULATION_EXTERN_H__ */ +} // namespace Antares::Solver::Modeler::Api diff --git a/src/solver/modeler/api/linearProblemBuilder.cpp b/src/solver/modeler/api/linearProblemBuilder.cpp new file mode 100644 index 0000000000..f9d6103152 --- /dev/null +++ b/src/solver/modeler/api/linearProblemBuilder.cpp @@ -0,0 +1,21 @@ +#include +#include + +#include + +namespace Antares::Solver::Modeler::Api +{ + +LinearProblemBuilder::LinearProblemBuilder(const std::vector& fillers): + fillers_(fillers) +{ +} + +void LinearProblemBuilder::build(ILinearProblem& pb, LinearProblemData& data) +{ + std::ranges::for_each(fillers_, [&](const auto& filler) { filler->addVariables(pb, data); }); + std::ranges::for_each(fillers_, [&](const auto& filler) { filler->addConstraints(pb, data); }); + std::ranges::for_each(fillers_, [&](const auto& filler) { filler->addObjective(pb, data); }); +} + +} // 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..309fb67fa8 --- /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::modeler_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..d4e6e52c02 --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/include/antares/solver/modeler/ortoolsImpl/linearProblem.h @@ -0,0 +1,78 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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; + int variableCount() const override; + + OrtoolsMipConstraint* addConstraint(double lb, double ub, const std::string& name) override; + OrtoolsMipConstraint* getConstraint(const std::string& name) const override; + int constraintCount() 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..1d8bf981bc --- /dev/null +++ b/src/solver/modeler/ortoolsImpl/linearProblem.cpp @@ -0,0 +1,188 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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(); +} + +int OrtoolsLinearProblem::variableCount() const +{ + return mpSolver_->NumVariables(); +} + +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(); +} + +int OrtoolsLinearProblem::constraintCount() const +{ + return mpSolver_->NumConstraints(); +} + +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/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt index a6c6f01e66..a0d74288e7 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 @@ -50,9 +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 - include/antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h - adequacy_patch_local_matching/adq_patch_local_matching.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 @@ -209,4 +205,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_csr/adq_patch_post_process_list.cpp b/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp index 1ed1e80371..ca3a31ecb0 100644 --- a/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp +++ b/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp @@ -50,10 +50,7 @@ AdqPatchPostProcessList::AdqPatchPostProcessList(const AdqPatchParams& adqPatchP thread_number)); // Here a post process particular to adq patch post_process_list.push_back( - std::make_unique(adqPatchParams, - problemeHebdo_, - areas, - thread_number)); + std::make_unique(problemeHebdo_, areas, thread_number)); post_process_list.push_back( std::make_unique(problemeHebdo_, areas, true, false)); post_process_list.push_back( 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..bc946a3c57 --- /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/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/QuadraticProblemMatrix.h b/src/solver/optimisation/include/antares/solver/optimisation/QuadraticProblemMatrix.h index 31563498a3..417a20a064 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/QuadraticProblemMatrix.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/QuadraticProblemMatrix.h @@ -21,11 +21,7 @@ #pragma once -#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_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "ProblemMatrixEssential.h" #include "constraints/ExchangeBalanceGroup.h" 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_csr/post_processing.h similarity index 68% rename from src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_local_matching/adq_patch_local_matching.h rename to src/solver/optimisation/include/antares/solver/optimisation/adequacy_patch_csr/post_processing.h index eff8842d7b..3ae5ee2d91 100644 --- 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_csr/post_processing.h @@ -21,19 +21,9 @@ #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); - +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/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/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/opt_fonctions.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h index 4be6b8e1d7..f215ae5dd1 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_fonctions.h @@ -36,7 +36,6 @@ using OptimizationOptions = Antares::Solver::Optimization::OptimizationOptions; void OPT_OptimisationHebdomadaire(const OptimizationOptions& options, PROBLEME_HEBDO* pProblemeHebdo, - const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, Solver::Simulation::ISimulationObserver& simulationObserver); void OPT_NumeroDeJourDuPasDeTemps(PROBLEME_HEBDO*); @@ -47,7 +46,6 @@ void OPT_InitialiserLesPminHebdo(PROBLEME_HEBDO*); void OPT_InitialiserLesContrainteDEnergieHydrauliqueParIntervalleOptimise(PROBLEME_HEBDO*); void OPT_MaxDesPmaxHydrauliques(PROBLEME_HEBDO*); void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO*, - const AdqPatchParams&, const int, const int, const int); @@ -56,7 +54,6 @@ void OPT_InitialiserLeSecondMembreDuProblemeLineaire(PROBLEME_HEBDO*, int, int, void OPT_InitialiserLeSecondMembreDuProblemeQuadratique(PROBLEME_HEBDO*, int); void OPT_InitialiserLesCoutsLineaire(PROBLEME_HEBDO*, const int, const int); void OPT_InitialiserLesCoutsQuadratiques(PROBLEME_HEBDO*, int); -void OPT_ControleDesPminPmaxThermiques(PROBLEME_HEBDO*); bool OPT_AppelDuSolveurQuadratique(PROBLEME_ANTARES_A_RESOUDRE*, const int); using namespace Antares::Data::AdequacyPatch; @@ -68,7 +65,6 @@ bool ADQ_PATCH_CSR(PROBLEME_ANTARES_A_RESOUDRE&, bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, Solver::Simulation::ISimulationObserver& simulationObserver); void OPT_VerifierPresenceReserveJmoins1(PROBLEME_HEBDO*); @@ -89,7 +85,6 @@ void OPT_LiberationProblemesSimplexe(const OptimizationOptions& options, const P bool OPT_OptimisationLineaire(const OptimizationOptions& options, 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/post_process_commands.h b/src/solver/optimisation/include/antares/solver/optimisation/post_process_commands.h index 652ab48132..5bf5ecf314 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/post_process_commands.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/post_process_commands.h @@ -74,15 +74,13 @@ class DTGmarginForAdqPatchPostProcessCmd: public basePostProcessCommand using AdqPatchParams = Antares::Data::AdequacyPatch::AdqPatchParams; public: - DTGmarginForAdqPatchPostProcessCmd(const AdqPatchParams& adqPatchParams, - PROBLEME_HEBDO* problemeHebdo, + DTGmarginForAdqPatchPostProcessCmd(PROBLEME_HEBDO* problemeHebdo, AreaList& areas, unsigned int thread_number); void execute(const optRuntimeData& opt_runtime_data) override; private: - const AdqPatchParams& adqPatchParams_; const AreaList& area_list_; unsigned int thread_number_ = 0; }; 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..5521bb8751 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,23 @@ #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, + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver); + ~WeeklyOptimization() = default; + void solve(); + +private: + Antares::Solver::Optimization::OptimizationOptions options_; + PROBLEME_HEBDO* const problemeHebdo_ = nullptr; + IResultWriter& writer_; + std::reference_wrapper simulationObserver_; }; } // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/opt_alloc_probleme_a_optimiser.cpp b/src/solver/optimisation/opt_alloc_probleme_a_optimiser.cpp index d7e812e32d..20b448bde7 100644 --- a/src/solver/optimisation/opt_alloc_probleme_a_optimiser.cpp +++ b/src/solver/optimisation/opt_alloc_probleme_a_optimiser.cpp @@ -20,17 +20,10 @@ */ #include -#include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" -using namespace Antares; - -#ifdef _MSC_VER -#define SNPRINTF sprintf_s -#else -#define SNPRINTF snprintf -#endif +int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO*); void OPT_AllocateFromNumberOfVariableConstraints(PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre, int NbTermes) diff --git a/src/solver/optimisation/opt_appel_solveur_lineaire.cpp b/src/solver/optimisation/opt_appel_solveur_lineaire.cpp index 2dd81809da..02658175c4 100644 --- a/src/solver/optimisation/opt_appel_solveur_lineaire.cpp +++ b/src/solver/optimisation/opt_appel_solveur_lineaire.cpp @@ -19,35 +19,23 @@ * along with Antares_Simulator. If not, see . */ -#include - -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" -#include "antares/solver/simulation/sim_structure_probleme_economique.h" -#include "antares/solver/simulation/simulation.h" -#include "antares/solver/utils/basis_status.h" - -extern "C" -{ -#include "spx_definition_arguments.h" -#include "spx_fonctions.h" -#include "srs_api.h" -} - #include +#include +#include #include #include +#include "antares/optimization-options/options.h" #include "antares/solver/infeasible-problem-analysis/unfeasible-pb-analyzer.h" +#include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "antares/solver/utils/filename.h" #include "antares/solver/utils/mps_utils.h" using namespace operations_research; -using namespace Antares; -using namespace Antares::Data; -using namespace Yuni; using Antares::Solver::IResultWriter; +using Antares::Solver::Optimization::OptimizationOptions; class TimeMeasurement { @@ -97,8 +85,7 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options, IResultWriter& writer) { const auto& ProblemeAResoudre = problemeHebdo->ProblemeAResoudre; - auto ProbSpx = (PROBLEME_SPX*)(ProblemeAResoudre->ProblemesSpx[(int)NumIntervalle]); - auto solver = (MPSolver*)(ProblemeAResoudre->ProblemesSpx[(int)NumIntervalle]); + auto solver = (MPSolver*)(ProblemeAResoudre->ProblemesSpx[NumIntervalle]); const int opt = optimizationNumber - 1; assert(opt >= 0 && opt < 2); @@ -106,11 +93,10 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options, TIME_MEASURE timeMeasure; if (!PremierPassage) { - ProbSpx = nullptr; solver = nullptr; } - if (ProbSpx == nullptr && solver == nullptr) + if (solver == nullptr) { Probleme.Contexte = SIMPLEXE_SEUL; Probleme.BaseDeDepartFournie = NON_SPX; @@ -119,17 +105,13 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options, { if (problemeHebdo->ReinitOptimisation) { - if (options.ortoolsUsed && solver) + if (solver != nullptr) { ORTOOLS_LibererProbleme(solver); } - else if (ProbSpx != nullptr) - { - SPX_LibererProbleme(ProbSpx); - } + ProblemeAResoudre->ProblemesSpx[NumIntervalle] = nullptr; - ProbSpx = nullptr; solver = nullptr; Probleme.Contexte = SIMPLEXE_SEUL; Probleme.BaseDeDepartFournie = NON_SPX; @@ -140,31 +122,19 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options, Probleme.BaseDeDepartFournie = UTILISER_LA_BASE_DU_PROBLEME_SPX; TimeMeasurement updateMeasure; - if (options.ortoolsUsed) - { - ORTOOLS_ModifierLeVecteurCouts(solver, - ProblemeAResoudre->CoutLineaire.data(), - ProblemeAResoudre->NombreDeVariables); - ORTOOLS_ModifierLeVecteurSecondMembre(solver, - ProblemeAResoudre->SecondMembre.data(), - ProblemeAResoudre->Sens.data(), - ProblemeAResoudre->NombreDeContraintes); - ORTOOLS_CorrigerLesBornes(solver, - ProblemeAResoudre->Xmin.data(), - ProblemeAResoudre->Xmax.data(), - ProblemeAResoudre->TypeDeVariable.data(), - ProblemeAResoudre->NombreDeVariables); - } - else - { - SPX_ModifierLeVecteurCouts(ProbSpx, - ProblemeAResoudre->CoutLineaire.data(), - ProblemeAResoudre->NombreDeVariables); - SPX_ModifierLeVecteurSecondMembre(ProbSpx, - ProblemeAResoudre->SecondMembre.data(), - ProblemeAResoudre->Sens.data(), - ProblemeAResoudre->NombreDeContraintes); - } + + ORTOOLS_ModifierLeVecteurCouts( + solver, ProblemeAResoudre->CoutLineaire.data(), ProblemeAResoudre->NombreDeVariables); + ORTOOLS_ModifierLeVecteurSecondMembre(solver, + ProblemeAResoudre->SecondMembre.data(), + ProblemeAResoudre->Sens.data(), + ProblemeAResoudre->NombreDeContraintes); + ORTOOLS_CorrigerLesBornes(solver, + ProblemeAResoudre->Xmin.data(), + ProblemeAResoudre->Xmax.data(), + ProblemeAResoudre->TypeDeVariable.data(), + ProblemeAResoudre->NombreDeVariables); + updateMeasure.tick(); timeMeasure.updateTime = updateMeasure.duration_ms(); optimizationStatistics.addUpdateTime(timeMeasure.updateTime); @@ -213,40 +183,27 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options, Probleme.NombreDeContraintesCoupes = 0; - if (options.ortoolsUsed) - { - solver = ORTOOLS_ConvertIfNeeded(options.ortoolsSolver, &Probleme, solver); - } + solver = ORTOOLS_ConvertIfNeeded(options.ortoolsSolver, &Probleme, solver); const std::string filename = createMPSfilename(optPeriodStringGenerator, optimizationNumber); mpsWriterFactory mps_writer_factory(problemeHebdo->ExportMPS, problemeHebdo->exportMPSOnError, optimizationNumber, &Probleme, - options.ortoolsUsed, solver); auto mps_writer = mps_writer_factory.create(); mps_writer->runIfNeeded(writer, filename); TimeMeasurement measure; - if (options.ortoolsUsed) - { - const bool keepBasis = (optimizationNumber == PREMIERE_OPTIMISATION); - solver = ORTOOLS_Simplexe(&Probleme, solver, keepBasis, options); - if (solver != nullptr) - { - ProblemeAResoudre->ProblemesSpx[NumIntervalle] = (void*)solver; - } - } - else + + const bool keepBasis = (optimizationNumber == PREMIERE_OPTIMISATION); + solver = ORTOOLS_Simplexe(&Probleme, solver, keepBasis, options); + if (solver != nullptr) { - ProbSpx = SPX_Simplexe(&Probleme, ProbSpx); - if (ProbSpx != nullptr) - { - ProblemeAResoudre->ProblemesSpx[NumIntervalle] = (void*)ProbSpx; - } + ProblemeAResoudre->ProblemesSpx[NumIntervalle] = (void*)solver; } + measure.tick(); timeMeasure.solveTime = measure.duration_ms(); optimizationStatistics.addSolveTime(timeMeasure.solveTime); @@ -256,22 +213,15 @@ static SimplexResult OPT_TryToCallSimplex(const OptimizationOptions& options, { if (ProblemeAResoudre->ExistenceDUneSolution != SPX_ERREUR_INTERNE) { - if (options.ortoolsUsed && solver) + if (solver != nullptr) { ORTOOLS_LibererProbleme(solver); } - else if (ProbSpx != nullptr) - { - SPX_LibererProbleme(ProbSpx); - } logs.info() << " Solver: Standard resolution failed"; logs.info() << " Solver: Retry in safe mode"; // second trial w/o scaling + logs.debug() << " solver: resetting"; - if (Logs::Verbosity::Debug::enabled) - { - logs.info() << " solver: resetting"; - } return {.success = false, .timeMeasure = timeMeasure, .mps_writer_factory = mps_writer_factory}; diff --git a/src/solver/optimisation/opt_appel_solveur_quadratique.cpp b/src/solver/optimisation/opt_appel_solveur_quadratique.cpp index a491294a06..d59c6d8779 100644 --- a/src/solver/optimisation/opt_appel_solveur_quadratique.cpp +++ b/src/solver/optimisation/opt_appel_solveur_quadratique.cpp @@ -21,24 +21,22 @@ #include -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" - /* pi_define.h doesn't include this header, yet it uses struct jmp_buf. It would be nice to remove this include, but would require to change pi_define.h, which isn't part of Antares */ -#include +#include extern "C" { -#include "pi_define.h" -#include "pi_definition_arguments.h" -#include "pi_fonctions.h" +#include +#include +#include } #include +#include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" using namespace Antares; diff --git a/src/solver/optimisation/opt_calcul_des_pmin_MUT_MDT.cpp b/src/solver/optimisation/opt_calcul_des_pmin_MUT_MDT.cpp index 16212e0bfd..1e07bbcbd7 100644 --- a/src/solver/optimisation/opt_calcul_des_pmin_MUT_MDT.cpp +++ b/src/solver/optimisation/opt_calcul_des_pmin_MUT_MDT.cpp @@ -19,13 +19,7 @@ ** along with Antares_Simulator. If not, see . */ -#include - -#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_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" constexpr double ZERO_PMIN = 1.e-2; diff --git a/src/solver/optimisation/opt_chainage_intercos.cpp b/src/solver/optimisation/opt_chainage_intercos.cpp index 8d1f362ffd..d7298d77dd 100644 --- a/src/solver/optimisation/opt_chainage_intercos.cpp +++ b/src/solver/optimisation/opt_chainage_intercos.cpp @@ -19,9 +19,7 @@ ** along with Antares_Simulator. If not, see . */ -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_ChainagesDesIntercoPartantDUnNoeud(PROBLEME_HEBDO* problemeHebdo) { diff --git a/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp b/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp index 98a259540d..35fa3faa2e 100644 --- a/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp +++ b/src/solver/optimisation/opt_construction_variables_couts_demarrages.cpp @@ -19,12 +19,11 @@ * along with Antares_Simulator. If not, see . */ -#include "antares/solver/optimisation/opt_fonctions.h" +#include + #include "antares/solver/optimisation/opt_rename_problem.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_structure_probleme_economique.h" -#include "spx_constantes_externes.h" #include "variables/VariableManagerUtils.h" void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaireCoutsDeDemarrage( diff --git a/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp b/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp index 40736b5428..c1aa0e2991 100644 --- a/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp +++ b/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp @@ -20,13 +20,14 @@ */ #include -#include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/optimisation/opt_rename_problem.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_structure_probleme_economique.h" #include "variables/VariableManagerUtils.h" +void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaireCoutsDeDemarrage(PROBLEME_HEBDO*, + bool); + void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaire(PROBLEME_HEBDO* problemeHebdo) { const auto& ProblemeAResoudre = problemeHebdo->ProblemeAResoudre; diff --git a/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp b/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp index 10018bf29d..068ca7d878 100644 --- a/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp +++ b/src/solver/optimisation/opt_construction_variables_optimisees_quadratique.cpp @@ -19,11 +19,7 @@ ** 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_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "pi_constantes_externes.h" #include "variables/VariableManagerUtils.h" diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp index 1f773bb9ea..1df4f0b3df 100644 --- a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp +++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp @@ -20,14 +20,12 @@ */ #include -#include -#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/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" using namespace Antares; +void OPT_DecompteDesVariablesEtDesContraintesCoutsDeDemarrage(PROBLEME_HEBDO*); + int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* problemeHebdo) { const auto& ProblemeAResoudre = problemeHebdo->ProblemeAResoudre; diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes_couts_demarrage.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes_couts_demarrage.cpp index ed4216b8a3..22b10d3440 100644 --- a/src/solver/optimisation/opt_decompte_variables_et_contraintes_couts_demarrage.cpp +++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes_couts_demarrage.cpp @@ -21,9 +21,6 @@ #include "antares/solver/optimisation/LinearProblemMatrixStartUpCosts.h" #include "antares/solver/optimisation/constraints/constraint_builder_utils.h" -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/simulation.h" void OPT_DecompteDesVariablesEtDesContraintesCoutsDeDemarrage(PROBLEME_HEBDO* problemeHebdo) { @@ -38,6 +35,4 @@ void OPT_DecompteDesVariablesEtDesContraintesCoutsDeDemarrage(PROBLEME_HEBDO* pr OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaireCoutsDeDemarrage(problemeHebdo, true); - - return; } diff --git a/src/solver/optimisation/opt_export_structure.cpp b/src/solver/optimisation/opt_export_structure.cpp index 78f39cca47..c0f5a14b4c 100644 --- a/src/solver/optimisation/opt_export_structure.cpp +++ b/src/solver/optimisation/opt_export_structure.cpp @@ -21,7 +21,7 @@ #include "antares/solver/optimisation/opt_export_structure.h" -#include +#include #include "antares/solver/simulation/sim_structure_probleme_economique.h" 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..50c63133fc 100644 --- a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp @@ -20,21 +20,17 @@ */ #include +#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" #include "antares/solver/simulation/sim_structure_probleme_economique.h" -#include "spx_constantes_externes.h" #include "variables/VariableManagement.h" #include "variables/VariableManagerUtils.h" -using namespace Antares; -using namespace Antares::Data; - -using namespace Yuni; +void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaireCoutsDeDemarrage(PROBLEME_HEBDO*, + const int, + const int); void OPT_MaxDesPmaxHydrauliques(PROBLEME_HEBDO* problemeHebdo) { @@ -58,8 +54,6 @@ void OPT_MaxDesPmaxHydrauliques(PROBLEME_HEBDO* problemeHebdo) problemeHebdo->CaracteristiquesHydrauliques[pays].MaxDesPmaxHydrauliques = pmaxHyd; } - - return; } double OPT_SommeDesPminThermiques(const PROBLEME_HEBDO* problemeHebdo, int Pays, uint pdtHebdo) @@ -80,7 +74,6 @@ double OPT_SommeDesPminThermiques(const PROBLEME_HEBDO* problemeHebdo, int Pays, } void setBoundsForUnsuppliedEnergy(PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams, const int PremierPdtDeLIntervalle, const int DernierPdtDeLIntervalle, const int optimizationNumber) @@ -133,17 +126,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; @@ -217,7 +199,6 @@ static void setBoundsForShortTermStorage(PROBLEME_HEBDO* problemeHebdo, } void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams, const int PremierPdtDeLIntervalle, const int DernierPdtDeLIntervalle, const int optimizationNumber) @@ -249,12 +230,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) { @@ -475,7 +452,6 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob } setBoundsForUnsuppliedEnergy(problemeHebdo, - adqPatchParams, PremierPdtDeLIntervalle, DernierPdtDeLIntervalle, optimizationNumber); @@ -524,6 +500,4 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob PremierPdtDeLIntervalle, DernierPdtDeLIntervalle); } - - return; } diff --git a/src/solver/optimisation/opt_gestion_des_bornes_cas_quadratique.cpp b/src/solver/optimisation/opt_gestion_des_bornes_cas_quadratique.cpp index e48672d22a..6cdafb3638 100644 --- a/src/solver/optimisation/opt_gestion_des_bornes_cas_quadratique.cpp +++ b/src/solver/optimisation/opt_gestion_des_bornes_cas_quadratique.cpp @@ -18,21 +18,14 @@ ** 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/sim_structure_probleme_economique.h" -#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/simulation.h" - -#include "pi_constantes_externes.h" #include "variables/VariableManagerUtils.h" #define ZERO_POUR_LES_VARIABLES_FIXES 1.e-6 -using namespace Yuni; - void OPT_InitialiserLesBornesDesVariablesDuProblemeQuadratique(PROBLEME_HEBDO* problemeHebdo, int PdtHebdo) { diff --git a/src/solver/optimisation/opt_gestion_des_bornes_couts_demarrage.cpp b/src/solver/optimisation/opt_gestion_des_bornes_couts_demarrage.cpp index e73cb62779..04359e1109 100644 --- a/src/solver/optimisation/opt_gestion_des_bornes_couts_demarrage.cpp +++ b/src/solver/optimisation/opt_gestion_des_bornes_couts_demarrage.cpp @@ -19,17 +19,11 @@ ** 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" #include "antares/solver/simulation/sim_structure_probleme_economique.h" -#include "antares/solver/simulation/simulation.h" #include "variables/VariableManagement.h" #include "variables/VariableManagerUtils.h" -using namespace Yuni; - void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaireCoutsDeDemarrage( PROBLEME_HEBDO* problemeHebdo, const int PremierPdtDeLIntervalle, 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..893575110d 100644 --- a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp @@ -19,17 +19,12 @@ ** along with Antares_Simulator. If not, see . */ -#include - -#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" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "variables/VariableManagerUtils.h" +void OPT_InitialiserLesCoutsLineaireCoutsDeDemarrage(PROBLEME_HEBDO*, const int, const int); + static void shortTermStorageCost( int PremierPdtDeLIntervalle, int DernierPdtDeLIntervalle, @@ -38,7 +33,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 +46,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 +62,7 @@ static void shortTermStorageCost( pdtJour); varWithdrawal >= 0) { - linearCost[varWithdrawal] = storage.injectionEfficiency * cost; + linearCost[varWithdrawal] = storage.series->costWithdrawal[pdtHebdo]; } } } @@ -347,6 +340,4 @@ void OPT_InitialiserLesCoutsLineaire(PROBLEME_HEBDO* problemeHebdo, PremierPdtDeLIntervalle, DernierPdtDeLIntervalle); } - - return; } diff --git a/src/solver/optimisation/opt_gestion_des_couts_cas_quadratique.cpp b/src/solver/optimisation/opt_gestion_des_couts_cas_quadratique.cpp index 4e3c137cf7..1aed52c0cb 100644 --- a/src/solver/optimisation/opt_gestion_des_couts_cas_quadratique.cpp +++ b/src/solver/optimisation/opt_gestion_des_couts_cas_quadratique.cpp @@ -21,8 +21,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/simulation.h" #include "variables/VariableManagerUtils.h" diff --git a/src/solver/optimisation/opt_gestion_des_couts_couts_demarrage.cpp b/src/solver/optimisation/opt_gestion_des_couts_couts_demarrage.cpp index 3112f70e68..7d1d128a4a 100644 --- a/src/solver/optimisation/opt_gestion_des_couts_couts_demarrage.cpp +++ b/src/solver/optimisation/opt_gestion_des_couts_couts_demarrage.cpp @@ -19,11 +19,7 @@ ** 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_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "variables/VariableManagerUtils.h" diff --git a/src/solver/optimisation/opt_gestion_des_pmin.cpp b/src/solver/optimisation/opt_gestion_des_pmin.cpp index 921371b0e3..4989520e28 100644 --- a/src/solver/optimisation/opt_gestion_des_pmin.cpp +++ b/src/solver/optimisation/opt_gestion_des_pmin.cpp @@ -18,10 +18,8 @@ ** 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/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" + +#include "antares/solver/simulation/sim_structure_probleme_economique.h" #define ZERO 1.e-2 diff --git a/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp index 3818f73e38..a824066209 100644 --- a/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp @@ -19,13 +19,10 @@ ** 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_extern_variables_globales.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" -using namespace Antares; -using namespace Antares::Data; -using namespace Yuni; +double OPT_SommeDesPminThermiques(const PROBLEME_HEBDO*, int, uint); +void OPT_InitialiserLeSecondMembreDuProblemeLineaireCoutsDeDemarrage(PROBLEME_HEBDO*, int, int); static void shortTermStorageLevelsRHS( const std::vector<::ShortTermStorage::AREA_INPUT>& shortTermStorageInput, diff --git a/src/solver/optimisation/opt_gestion_second_membre_cas_quadratique.cpp b/src/solver/optimisation/opt_gestion_second_membre_cas_quadratique.cpp index 44d6486041..b9b0b19162 100644 --- a/src/solver/optimisation/opt_gestion_second_membre_cas_quadratique.cpp +++ b/src/solver/optimisation/opt_gestion_second_membre_cas_quadratique.cpp @@ -19,10 +19,7 @@ ** 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_extern_variables_globales.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_InitialiserLeSecondMembreDuProblemeQuadratique(PROBLEME_HEBDO* problemeHebdo, int PdtHebdo) { diff --git a/src/solver/optimisation/opt_gestion_second_membre_couts_demarrage.cpp b/src/solver/optimisation/opt_gestion_second_membre_couts_demarrage.cpp index 215532e83e..48003b697d 100644 --- a/src/solver/optimisation/opt_gestion_second_membre_couts_demarrage.cpp +++ b/src/solver/optimisation/opt_gestion_second_membre_couts_demarrage.cpp @@ -19,15 +19,7 @@ ** along with Antares_Simulator. If not, see . */ -#include -#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_structure_donnees.h" - -using namespace Antares; -using namespace Antares::Data; -using namespace Yuni; +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_InitialiserLeSecondMembreDuProblemeLineaireCoutsDeDemarrage(PROBLEME_HEBDO* problemeHebdo, int PremierPdtDeLIntervalle, @@ -105,6 +97,4 @@ void OPT_InitialiserLeSecondMembreDuProblemeLineaireCoutsDeDemarrage(PROBLEME_HE } } } - - return; } diff --git a/src/solver/optimisation/opt_init_contraintes_hydrauliques.cpp b/src/solver/optimisation/opt_init_contraintes_hydrauliques.cpp index c9f25e418f..13a780192b 100644 --- a/src/solver/optimisation/opt_init_contraintes_hydrauliques.cpp +++ b/src/solver/optimisation/opt_init_contraintes_hydrauliques.cpp @@ -19,10 +19,7 @@ ** along with Antares_Simulator. If not, see . */ -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_InitialiserLesContrainteDEnergieHydrauliqueParIntervalleOptimise( PROBLEME_HEBDO* problemeHebdo) @@ -139,6 +136,4 @@ void OPT_InitialiserLesContrainteDEnergieHydrauliqueParIntervalleOptimise( InflowForTimeInterval[intervalle] = InflowSum; } } - - return; } diff --git a/src/solver/optimisation/opt_init_minmax_groupes_couts_demarrage.cpp b/src/solver/optimisation/opt_init_minmax_groupes_couts_demarrage.cpp index 1ca75d33d2..1ec2ddcc2e 100644 --- a/src/solver/optimisation/opt_init_minmax_groupes_couts_demarrage.cpp +++ b/src/solver/optimisation/opt_init_minmax_groupes_couts_demarrage.cpp @@ -19,10 +19,7 @@ ** along with Antares_Simulator. If not, see . */ -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_InitialiserNombreMinEtMaxDeGroupesCoutsDeDemarrage(PROBLEME_HEBDO* problemeHebdo) { @@ -71,6 +68,4 @@ void OPT_InitialiserNombreMinEtMaxDeGroupesCoutsDeDemarrage(PROBLEME_HEBDO* prob } } } - - return; } diff --git a/src/solver/optimisation/opt_liberation_problemes_simplexe.cpp b/src/solver/optimisation/opt_liberation_problemes_simplexe.cpp index df0a9b4e37..9278d0f2a0 100644 --- a/src/solver/optimisation/opt_liberation_problemes_simplexe.cpp +++ b/src/solver/optimisation/opt_liberation_problemes_simplexe.cpp @@ -19,19 +19,13 @@ ** 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_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" -#include "antares/solver/utils/ortools_utils.h" +#include -extern "C" -{ -#include "spx_fonctions.h" -} +#include "antares/optimization-options/options.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" +#include "antares/solver/utils/ortools_utils.h" -using namespace Antares; +using namespace Antares::Solver::Optimization; void OPT_LiberationProblemesSimplexe(const OptimizationOptions& options, const PROBLEME_HEBDO* problemeHebdo) @@ -58,21 +52,13 @@ void OPT_LiberationProblemesSimplexe(const OptimizationOptions& options, { for (int numIntervalle = 0; numIntervalle < nbIntervalles; numIntervalle++) { - auto ProbSpx = (PROBLEME_SPX*)(ProblemeAResoudre->ProblemesSpx[numIntervalle]); auto solver = (MPSolver*)(ProblemeAResoudre->ProblemesSpx[numIntervalle]); - if (options.ortoolsUsed && solver) + if (solver != NULL) { ORTOOLS_LibererProbleme(solver); solver = nullptr; } - else if (ProbSpx) - { - SPX_LibererProbleme(ProbSpx); - ProbSpx = nullptr; - } } } - - return; } diff --git a/src/solver/optimisation/opt_nombre_min_groupes_demarres_couts_demarrage.cpp b/src/solver/optimisation/opt_nombre_min_groupes_demarres_couts_demarrage.cpp index 705fd63290..ec0e7e9bd2 100644 --- a/src/solver/optimisation/opt_nombre_min_groupes_demarres_couts_demarrage.cpp +++ b/src/solver/optimisation/opt_nombre_min_groupes_demarres_couts_demarrage.cpp @@ -18,28 +18,10 @@ ** 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" -#include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" +#include -extern "C" -{ -#include "spx_definition_arguments.h" -#include "spx_fonctions.h" -} - -using namespace Antares; -using namespace Antares::Data; -using namespace Yuni; - -#ifdef _MSC_VER -#define SNPRINTF sprintf_s -#else -#define SNPRINTF snprintf -#endif +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_PbLineairePourAjusterLeNombreMinDeGroupesDemarresCoutsDeDemarrage(PROBLEME_HEBDO*, std::vector&, @@ -658,6 +640,4 @@ void OPT_PbLineairePourAjusterLeNombreMinDeGroupesDemarresCoutsDeDemarrage( printf("Pas de solution au probleme auxiliaire\n"); #endif } - - return; } diff --git a/src/solver/optimisation/opt_numero_de_jour_du_pas_de_temps.cpp b/src/solver/optimisation/opt_numero_de_jour_du_pas_de_temps.cpp index 122c3a36d2..95e5ed50ad 100644 --- a/src/solver/optimisation/opt_numero_de_jour_du_pas_de_temps.cpp +++ b/src/solver/optimisation/opt_numero_de_jour_du_pas_de_temps.cpp @@ -19,11 +19,7 @@ ** along with Antares_Simulator. If not, see . */ -#include - -#include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_NumeroDeJourDuPasDeTemps(PROBLEME_HEBDO* problemeHebdo) { @@ -34,7 +30,6 @@ void OPT_NumeroDeJourDuPasDeTemps(PROBLEME_HEBDO* problemeHebdo) double X = pdtHebdo / problemeHebdo->NombreDePasDeTempsDUneJournee; problemeHebdo->NumeroDeJourDuPasDeTemps[pdtHebdo] = (int)floor(X); } - return; } void OPT_NumeroDIntervalleOptimiseDuPasDeTemps(PROBLEME_HEBDO* problemeHebdo) @@ -44,5 +39,4 @@ void OPT_NumeroDIntervalleOptimiseDuPasDeTemps(PROBLEME_HEBDO* problemeHebdo) double X = pdtHebdo / problemeHebdo->NombreDePasDeTempsPourUneOptimisation; problemeHebdo->NumeroDIntervalleOptimiseDuPasDeTemps[pdtHebdo] = (int)floor(X); } - return; } diff --git a/src/solver/optimisation/opt_optimisation_hebdo.cpp b/src/solver/optimisation/opt_optimisation_hebdo.cpp index 0abed9ff13..8317514098 100644 --- a/src/solver/optimisation/opt_optimisation_hebdo.cpp +++ b/src/solver/optimisation/opt_optimisation_hebdo.cpp @@ -22,34 +22,28 @@ #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" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" -extern "C" -{ -#include "spx_fonctions.h" -} - -using namespace Antares; using namespace Antares::Data; using Antares::Solver::Optimization::OptimizationOptions; +bool OPT_PilotageOptimisationLineaire(const OptimizationOptions&, + PROBLEME_HEBDO*, + Solver::IResultWriter&, + Solver::Simulation::ISimulationObserver&); +bool OPT_PilotageOptimisationQuadratique(PROBLEME_HEBDO*); +void OPT_LiberationProblemesSimplexe(const OptimizationOptions&, const PROBLEME_HEBDO*); + void OPT_OptimisationHebdomadaire(const OptimizationOptions& options, PROBLEME_HEBDO* pProblemeHebdo, - const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, Solver::Simulation::ISimulationObserver& simulationObserver) { if (pProblemeHebdo->TypeDOptimisation == OPTIMISATION_LINEAIRE) { - if (!OPT_PilotageOptimisationLineaire(options, - pProblemeHebdo, - adqPatchParams, - writer, - simulationObserver)) + if (!OPT_PilotageOptimisationLineaire(options, pProblemeHebdo, 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 b3ca1a3daa..99669ad1ea 100644 --- a/src/solver/optimisation/opt_optimisation_lineaire.cpp +++ b/src/solver/optimisation/opt_optimisation_lineaire.cpp @@ -20,8 +20,6 @@ */ #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" @@ -29,8 +27,8 @@ #include "antares/solver/simulation/ISimulationObserver.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "antares/solver/utils/filename.h" -using namespace Antares; -using namespace Yuni; + +using namespace Antares::Solver; using Antares::Solver::Optimization::OptimizationOptions; namespace @@ -80,7 +78,6 @@ void notifyProblemHebdo(const PROBLEME_HEBDO* problemeHebdo, bool runWeeklyOptimization(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, int optimizationNumber, Solver::Simulation::ISimulationObserver& simulationObserver) @@ -96,7 +93,6 @@ bool runWeeklyOptimization(const OptimizationOptions& options, DernierPdtDeLIntervalle = pdtHebdo + NombreDePasDeTempsPourUneOptimisation; OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(problemeHebdo, - adqPatchParams, PremierPdtDeLIntervalle, DernierPdtDeLIntervalle, optimizationNumber); @@ -190,7 +186,6 @@ void resizeProbleme(PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre, bool OPT_OptimisationLineaire(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, Solver::Simulation::ISimulationObserver& simulationObserver) { @@ -226,7 +221,6 @@ bool OPT_OptimisationLineaire(const OptimizationOptions& options, bool ret = runWeeklyOptimization(options, problemeHebdo, - adqPatchParams, writer, PREMIERE_OPTIMISATION, simulationObserver); @@ -240,7 +234,6 @@ bool OPT_OptimisationLineaire(const OptimizationOptions& options, runThermalHeuristic(problemeHebdo); return runWeeklyOptimization(options, problemeHebdo, - adqPatchParams, writer, DEUXIEME_OPTIMISATION, simulationObserver); diff --git a/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp b/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp index 7d6bff0d80..8c95462332 100644 --- a/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp +++ b/src/solver/optimisation/opt_pilotage_optimisation_lineaire.cpp @@ -21,15 +21,13 @@ #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" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" using Antares::Solver::Optimization::OptimizationOptions; bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, PROBLEME_HEBDO* problemeHebdo, - const AdqPatchParams& adqPatchParams, Solver::IResultWriter& writer, Solver::Simulation::ISimulationObserver& simulationObserver) { @@ -37,11 +35,6 @@ bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, { if (problemeHebdo->TypeDOptimisation == OPTIMISATION_LINEAIRE) { - for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) - { - problemeHebdo->CoutDeDefaillanceEnReserve[pays] = 1.e+6; - } - problemeHebdo->NombreDeJours = (int)(problemeHebdo->NombreDePasDeTemps / problemeHebdo->NombreDePasDeTempsDUneJournee); @@ -77,9 +70,5 @@ bool OPT_PilotageOptimisationLineaire(const OptimizationOptions& options, OPT_InitialiserNombreMinEtMaxDeGroupesCoutsDeDemarrage(problemeHebdo); } - return OPT_OptimisationLineaire(options, - problemeHebdo, - adqPatchParams, - writer, - simulationObserver); + return OPT_OptimisationLineaire(options, problemeHebdo, writer, simulationObserver); } diff --git a/src/solver/optimisation/opt_pilotage_optimisation_quadratique.cpp b/src/solver/optimisation/opt_pilotage_optimisation_quadratique.cpp index 4f2d37bf96..1337fb763b 100644 --- a/src/solver/optimisation/opt_pilotage_optimisation_quadratique.cpp +++ b/src/solver/optimisation/opt_pilotage_optimisation_quadratique.cpp @@ -19,16 +19,9 @@ ** along with Antares_Simulator. If not, see . */ -#include - #include "antares/solver/optimisation/QuadraticProblemMatrix.h" #include "antares/solver/optimisation/constraints/constraint_builder_utils.h" #include "antares/solver/optimisation/opt_fonctions.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" -extern "C" -{ -#include "spx_fonctions.h" -} bool OPT_PilotageOptimisationQuadratique(PROBLEME_HEBDO* problemeHebdo) { diff --git a/src/solver/optimisation/opt_rename_problem.cpp b/src/solver/optimisation/opt_rename_problem.cpp index 85edf581b8..1324c54fd8 100644 --- a/src/solver/optimisation/opt_rename_problem.cpp +++ b/src/solver/optimisation/opt_rename_problem.cpp @@ -22,7 +22,7 @@ #include "antares/solver/optimisation/opt_rename_problem.h" #include -#include +#include const std::string HOUR("hour"); const std::string DAY("day"); diff --git a/src/solver/optimisation/opt_restaurer_les_donnees.cpp b/src/solver/optimisation/opt_restaurer_les_donnees.cpp index ec701b1202..bd058e88d2 100644 --- a/src/solver/optimisation/opt_restaurer_les_donnees.cpp +++ b/src/solver/optimisation/opt_restaurer_les_donnees.cpp @@ -19,11 +19,7 @@ ** 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_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_RestaurerLesDonnees(PROBLEME_HEBDO* problemeHebdo) { @@ -133,6 +129,4 @@ void OPT_RestaurerLesDonnees(PROBLEME_HEBDO* problemeHebdo) } } } - - return; } diff --git a/src/solver/optimisation/opt_verification_presence_reserve_jmoins1.cpp b/src/solver/optimisation/opt_verification_presence_reserve_jmoins1.cpp index 52f3c92f19..6216b6fa1d 100644 --- a/src/solver/optimisation/opt_verification_presence_reserve_jmoins1.cpp +++ b/src/solver/optimisation/opt_verification_presence_reserve_jmoins1.cpp @@ -19,13 +19,7 @@ ** 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_extern_variables_globales.h" -#include "antares/solver/simulation/sim_structure_donnees.h" -#include "antares/solver/simulation/simulation.h" - -#include "spx_fonctions.h" +#include "antares/solver/simulation/sim_structure_probleme_economique.h" void OPT_VerifierPresenceReserveJmoins1(PROBLEME_HEBDO* problemeHebdo) { @@ -46,6 +40,4 @@ void OPT_VerifierPresenceReserveJmoins1(PROBLEME_HEBDO* problemeHebdo) } } } - - return; } diff --git a/src/solver/optimisation/post_process_commands.cpp b/src/solver/optimisation/post_process_commands.cpp index 3ced34ba4a..7ca5a4b0d5 100644 --- a/src/solver/optimisation/post_process_commands.cpp +++ b/src/solver/optimisation/post_process_commands.cpp @@ -22,7 +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_local_matching/adequacy_patch_weekly_optimization.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" @@ -122,12 +122,10 @@ void RemixHydroPostProcessCmd::execute(const optRuntimeData& opt_runtime_data) using namespace Antares::Data::AdequacyPatch; DTGmarginForAdqPatchPostProcessCmd::DTGmarginForAdqPatchPostProcessCmd( - const AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemeHebdo, AreaList& areas, unsigned int thread_number): basePostProcessCommand(problemeHebdo), - adqPatchParams_(adqPatchParams), area_list_(areas), thread_number_(thread_number) { @@ -148,32 +146,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); } } } @@ -261,7 +250,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 @@ -273,11 +262,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/optimisation/variables/VariableManagement.h b/src/solver/optimisation/variables/VariableManagement.h index 1c3144aa0a..b5054a121c 100644 --- a/src/solver/optimisation/variables/VariableManagement.h +++ b/src/solver/optimisation/variables/VariableManagement.h @@ -1,6 +1,5 @@ #pragma once -#include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" namespace VariableManagement diff --git a/src/solver/optimisation/variables/VariableManagerUtils.h b/src/solver/optimisation/variables/VariableManagerUtils.h index 1597fac34b..7c06f72a43 100644 --- a/src/solver/optimisation/variables/VariableManagerUtils.h +++ b/src/solver/optimisation/variables/VariableManagerUtils.h @@ -2,4 +2,4 @@ #include "VariableManagement.h" -VariableManagement::VariableManager VariableManagerFromProblemHebdo(PROBLEME_HEBDO* problemeHebdo); +VariableManagement::VariableManager VariableManagerFromProblemHebdo(PROBLEME_HEBDO*); diff --git a/src/solver/optimisation/weekly_optimization.cpp b/src/solver/optimisation/weekly_optimization.cpp index 8f36d762d2..1def21d921 100644 --- a/src/solver/optimisation/weekly_optimization.cpp +++ b/src/solver/optimisation/weekly_optimization.cpp @@ -25,29 +25,20 @@ 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, + IResultWriter& writer, + Simulation::ISimulationObserver& simulationObserver): + options_(options), + problemeHebdo_(problemeHebdo), + writer_(writer), + simulationObserver_(simulationObserver) { } -void DefaultWeeklyOptimization::solve() +void WeeklyOptimization::solve() { - OPT_OptimisationHebdomadaire(options_, - problemeHebdo_, - adqPatchParams_, - writer_, - simulationObserver_.get()); + OPT_OptimisationHebdomadaire(options_, problemeHebdo_, writer_, simulationObserver_.get()); } } // namespace Antares::Solver::Optimization diff --git a/src/solver/simulation/CMakeLists.txt b/src/solver/simulation/CMakeLists.txt index fbfeb17f6a..17e511fac5 100644 --- a/src/solver/simulation/CMakeLists.txt +++ b/src/solver/simulation/CMakeLists.txt @@ -4,15 +4,10 @@ set(SRC_SIMULATION sim_alloc_probleme_hebdo.cpp include/antares/solver/simulation/sim_alloc_probleme_hebdo.h - sim_allocation_tableaux.cpp sim_calcul_economique.cpp - include/antares/solver/simulation/sim_extern_variables_globales.h include/antares/solver/simulation/sim_structure_donnees.h 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 @@ -29,6 +24,8 @@ set(SRC_SIMULATION include/antares/solver/simulation/solver.hxx include/antares/solver/simulation/solver.data.h solver.data.cpp + include/antares/solver/simulation/simulation-run.h + simulation-run.cpp include/antares/solver/simulation/common-eco-adq.h common-eco-adq.cpp common-hydro-remix.cpp @@ -45,12 +42,8 @@ set(SRC_SIMULATION adequacy_patch_runtime_data.cpp include/antares/solver/simulation/ITimeSeriesNumbersWriter.h TimeSeriesNumbersWriter.cpp - include/antares/solver/simulation/BindingConstraintsTimeSeriesNumbersWriter.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 + include/antares/solver/simulation/BindingConstraintsTimeSeriesNumbersWriter.h + include/antares/solver/simulation/ISimulationObserver.h ) source_group("simulation" FILES ${SRC_SIMULATION}) @@ -58,6 +51,7 @@ source_group("simulation" FILES ${SRC_SIMULATION}) # --- Library VARIABLES --- # add_library(antares-solver-simulation) +add_library(Antares::antares-solver-simulation ALIAS antares-solver-simulation) target_sources(antares-solver-simulation PRIVATE ${SRC_SIMULATION}) 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/adequacy.cpp b/src/solver/simulation/adequacy.cpp index f4759a0ab1..e0ef154020 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -211,7 +211,6 @@ bool Adequacy::year(Progression::Task& progression, { OPT_OptimisationHebdomadaire(createOptimizationOptions(study), ¤tProblem, - study.parameters.adqPatchParams, resultWriter, simulationObserver_.get()); @@ -258,7 +257,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 +398,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/adequacy_mode.cpp b/src/solver/simulation/adequacy_mode.cpp deleted file mode 100644 index c0dd81b176..0000000000 --- a/src/solver/simulation/adequacy_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/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/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index 27d2cdae6c..5b46e35cce 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, @@ -94,13 +94,12 @@ static void RecalculDesEchangesMoyens(Data::Study& study, NullSimulationObserver simulationObserver; OPT_OptimisationHebdomadaire(createOptimizationOptions(study), &problem, - study.parameters.adqPatchParams, resultWriter, simulationObserver); } catch (Data::UnfeasibleProblemError&) { - study.runtime->quadraticOptimizationHasFailed = true; + study.runtime.quadraticOptimizationHasFailed = true; } for (uint i = 0; i < (uint)problem.NombreDePasDeTemps; ++i) @@ -108,9 +107,11 @@ 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]; + study.runtime.transitMoyenInterconnexionsRecalculQuadratique[j][indx] = ntcValues + .ValeurDuFlux + [j]; } } } @@ -123,9 +124,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 +163,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) { @@ -170,7 +171,7 @@ void ComputeFlowQuad(Data::Study& study, for (uint i = 0; i < (uint)problem.NombreDePasDeTemps; ++i) { const uint indx = i + PasDeTempsDebut; - transitMoyenInterconnexionsRecalculQuadratique[j][indx] = 0; + study.runtime.transitMoyenInterconnexionsRecalculQuadratique[j][indx] = 0; } } } @@ -360,7 +361,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..b6edbc4f6f 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,12 @@ 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], + resultWriter, + simulationObserver_.get()); + postProcessesList_[numSpace] = interfacePostProcessList::create( study.parameters.adqPatchParams, &pProblemesHebdo[numSpace], @@ -163,7 +161,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); @@ -263,7 +261,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/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/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/common-eco-adq.h b/src/solver/simulation/include/antares/solver/simulation/common-eco-adq.h index 0bf24cd71d..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 @@ -63,7 +60,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/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/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..aa46e5962d 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" @@ -412,10 +411,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; @@ -494,7 +493,6 @@ struct PROBLEME_HEBDO std::vector CoutDeDefaillancePositive; std::vector CoutDeDefaillanceNegative; - std::vector CoutDeDefaillanceEnReserve; std::vector PaliersThermiquesDuPays; std::vector CaracteristiquesHydrauliques; diff --git a/src/solver/simulation/include/antares/solver/simulation/economy_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/economy_mode.h rename to src/solver/simulation/include/antares/solver/simulation/simulation-run.h index e26ebbb7e0..379959af05 100644 --- a/src/solver/simulation/include/antares/solver/simulation/economy_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 runSimulationInEconomicMode(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/include/antares/solver/simulation/simulation.h b/src/solver/simulation/include/antares/solver/simulation/simulation.h index bf214beff6..296e3bab82 100644 --- a/src/solver/simulation/include/antares/solver/simulation/simulation.h +++ b/src/solver/simulation/include/antares/solver/simulation/simulation.h @@ -29,10 +29,6 @@ struct PROBLEME_HEBDO; -// TODO remove when global variables have been removed (looking at you, -// transitMoyenInterconnexionsRecalculQuadratique) -void SIM_AllocationTableaux(const Antares::Data::Study& study); - /*! ** \brief Alloue toutes les donnees d'un probleme hebdo */ 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 1aa04cb38f..9fe8f55691 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 @@ -54,7 +51,7 @@ public: randomNumbers& pRandomForParallelYears, bool pPerformCalculations, Data::Study& pStudy, - Variable::State& pState, + std::vector& pStates, bool pYearByYear, Benchmarking::DurationCollector& durationCollector, IResultWriter& resultWriter, @@ -68,14 +65,13 @@ public: randomForParallelYears(pRandomForParallelYears), performCalculations(pPerformCalculations), study(pStudy), - state(pState), + states(pStates), yearByYear(pYearByYear), pDurationCollector(durationCollector), pResultWriter(resultWriter), simulationObserver_(simulationObserver), hydroManagement(study.areas, study.parameters, study.calendar, resultWriter) { - scratchmap = study.areas.buildScratchMap(numSpace); } yearJob(const yearJob&) = delete; @@ -92,13 +88,12 @@ private: randomNumbers& randomForParallelYears; bool performCalculations; Data::Study& study; - Variable::State& state; + std::vector& states; bool yearByYear; Benchmarking::DurationCollector& pDurationCollector; IResultWriter& pResultWriter; std::reference_wrapper simulationObserver_; HydroManagement hydroManagement; - Antares::Data::Area::ScratchMap scratchmap; private: /* @@ -146,22 +141,22 @@ 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 + // Getting the scratchMap associated to the current year + Antares::Data::Area::ScratchMap scratchmap = study.areas.buildScratchMap(numSpace); // 3 - Preparing data related to Clusters in 'must-run' mode simulation_->prepareClustersInMustRunMode(scratchmap, y); // 4 - Hydraulic ventilation - pDurationCollector("hydro_ventilation") << [this, &randomReservoirLevel] - { hydroManagement.makeVentilation(randomReservoirLevel, y, scratchmap); }; + pDurationCollector("hydro_ventilation") << [this, &scratchmap, &randomReservoirLevel] + { hydroManagement.makeVentilation(randomReservoirLevel.data(), y, scratchmap); }; // Updating the state + auto& state = states[numSpace]; state.year = y; // 5 - Resetting all variables for the output @@ -326,9 +321,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 +333,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 +451,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 +507,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 +601,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 +656,6 @@ void ISimulation::computeRandomNumbers( std::map& isYearPerformed, MersenneTwister& randomHydroGenerator) { - auto& runtime = *study.runtime; - uint indexYear = 0; std::vector::iterator ity; @@ -687,7 +680,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 +739,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 +780,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 +796,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) { @@ -1022,20 +1015,20 @@ void ISimulation::loopThroughYears(uint firstYear, // continue; auto task = std::make_shared>( - this, - y, - batch.yearFailed, - batch.isFirstPerformedYearOfASet, - pFirstSetParallelWithAPerformedYearWasRun, - numSpace, - randomForParallelYears, - performCalculations, - study, - state[numSpace], - pYearByYear, - pDurationCollector, - pResultWriter, - simulationObserver_.get()); + this, + y, + batch.yearFailed, + batch.isFirstPerformedYearOfASet, + pFirstSetParallelWithAPerformedYearWasRun, + numSpace, + randomForParallelYears, + performCalculations, + study, + state, + pYearByYear, + pDurationCollector, + 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/simulation/include/antares/solver/simulation/solver_utils.h b/src/solver/simulation/include/antares/solver/simulation/solver_utils.h index 363b7839f8..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 @@ -118,52 +114,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) { @@ -177,19 +131,19 @@ class yearRandomNumbers void reset() { - // General - memset(pNbClustersByArea, 0, pNbAreas * sizeof(size_t)); - // Thermal noises for (uint a = 0; a != pNbAreas; a++) { - memset(pThermalNoisesByArea[a], 0, pNbClustersByArea[a] * sizeof(double)); + pThermalNoisesByArea[a].assign(pThermalNoisesByArea[a].size(), 0); } + // General + pNbClustersByArea.assign(pNbAreas, 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 +152,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 +160,7 @@ class yearRandomNumbers case Data::lssMinimizeRamping: case Data::lssMinimizeExcursions: { - memset(pHydroCosts_rampingOrExcursion, 0, pNbAreas * sizeof(double)); + pHydroCosts_rampingOrExcursion.assign(pNbAreas, 0); break; } @@ -220,19 +174,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 +196,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 +205,7 @@ class randomNumbers } } - ~randomNumbers() - { - delete[] pYears; - } + ~randomNumbers() = default; void reset() { @@ -267,7 +218,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/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 03126fa752..df829e70df 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -20,11 +20,8 @@ */ #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" #include "antares/solver/simulation/sim_structure_donnees.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "antares/study/simulation.h" @@ -39,7 +36,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 +52,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); @@ -86,7 +83,6 @@ void SIM_AllocationProblemeDonneesGenerales(PROBLEME_HEBDO& problem, problem.CoutDeDefaillancePositive.assign(nbPays, 0); problem.CoutDeDefaillanceNegative.assign(nbPays, 0); - problem.CoutDeDefaillanceEnReserve.assign(nbPays, 0); problem.NumeroDeContrainteEnergieHydraulique.assign(nbPays, 0); problem.NumeroDeContrainteMinEnergieHydraulique.assign(nbPays, 0); @@ -132,8 +128,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 +155,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 +168,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 +201,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 +274,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()) { @@ -365,12 +361,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/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 2402ddd548..79e6635613 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -19,20 +19,17 @@ ** along with Antares_Simulator. If not, see . */ -#include +#include #include #include -#include #include #include #include #include "antares/solver/simulation/adequacy_patch_runtime_data.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" #include "antares/solver/simulation/simulation.h" #include "antares/study/fwd.h" -#include "antares/study/simulation.h" using namespace Antares; using namespace Antares::Data; @@ -87,7 +84,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 +98,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(); @@ -152,8 +149,6 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, problem.CoutDeDefaillanceNegative[i] = area.thermal.spilledEnergyCost; - problem.CoutDeDefaillanceEnReserve[i] = area.thermal.unsuppliedEnergyCost; - problem.DefaillanceNegativeUtiliserPMinThermique[i] = (anoOtherDispatchPower & area.nodalOptimization) != 0; @@ -219,9 +214,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 +406,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); @@ -521,7 +516,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 +643,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 +668,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); @@ -837,6 +832,12 @@ 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) 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 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/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/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/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 2d31f08b22..dd5af1a25e 100644 --- a/src/solver/ts-generator/hydro.cpp +++ b/src/solver/ts-generator/hydro.cpp @@ -1,32 +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 +#include #include #include #include "antares/solver/misc/cholesky.h" #include "antares/solver/misc/matrix-dp-make.h" -#include "antares/solver/simulation/sim_extern_variables_globales.h" using namespace Antares; @@ -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); @@ -80,11 +80,11 @@ 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(), - QCHOLTemp, + QCHOLTemp.data(), true)) { throw FatalError("TS Generator: Hydro: Invalid correlation matrix"); @@ -96,16 +96,16 @@ 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]; - auto& annualCorrAreaI = (*study.preproHydroCorrelation.annual)[areaIndexI]; + auto& annualCorrAreaI = study.preproHydroCorrelation.annual[areaIndexI]; 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.); @@ -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/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/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/studydata.cpp b/src/solver/ts-generator/xcast/studydata.cpp index 217f61fe14..9cf7e641ba 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" @@ -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 56f7234119..2c8a391a22 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); } } @@ -432,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) { @@ -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) { diff --git a/src/solver/utils/include/antares/solver/utils/mps_utils.h b/src/solver/utils/include/antares/solver/utils/mps_utils.h index 0afe5901ff..abd9ba2451 100644 --- a/src/solver/utils/include/antares/solver/utils/mps_utils.h +++ b/src/solver/utils/include/antares/solver/utils/mps_utils.h @@ -57,6 +57,9 @@ class I_MPS_writer uint current_optim_number_ = 0; }; +// Caution : this class should be removed if we want Sirius behind or-tools +// But we want to keep the way we write MPS files for a named problem, +// so we keep it for now. class fullMPSwriter final: public I_MPS_writer { public: @@ -98,7 +101,6 @@ class mpsWriterFactory bool exportMPSOnError, const int current_optim_number, PROBLEME_SIMPLEXE_NOMME* named_splx_problem, - bool ortoolsUsed, MPSolver* solver); std::unique_ptr create(); @@ -113,7 +115,6 @@ class mpsWriterFactory Data::mpsExportStatus export_mps_; bool export_mps_on_error_; PROBLEME_SIMPLEXE_NOMME* named_splx_problem_ = nullptr; - bool ortools_used_; MPSolver* solver_ = nullptr; uint current_optim_number_; }; diff --git a/src/solver/utils/mps_utils.cpp b/src/solver/utils/mps_utils.cpp index 6780b84922..02d023c5f5 100644 --- a/src/solver/utils/mps_utils.cpp +++ b/src/solver/utils/mps_utils.cpp @@ -26,15 +26,6 @@ using namespace Antares; using namespace Antares::Data; -using namespace Yuni; - -#ifdef _MSC_VER -#define SNPRINTF sprintf_s -#else -#define SNPRINTF snprintf -#endif - -constexpr size_t OPT_APPEL_SOLVEUR_BUFFER_SIZE = 256; /* ** Copyright 2007-2023 RTE @@ -71,10 +62,6 @@ constexpr size_t OPT_APPEL_SOLVEUR_BUFFER_SIZE = 256; #include "antares/solver/utils/filename.h" #include "antares/solver/utils/name_translator.h" -using namespace Yuni; - -#define SEP IO::Separator - class ProblemConverter { public: @@ -176,12 +163,10 @@ mpsWriterFactory::mpsWriterFactory(Data::mpsExportStatus exportMPS, bool exportMPSOnError, const int current_optim_number, PROBLEME_SIMPLEXE_NOMME* named_splx_problem, - bool ortoolsUsed, MPSolver* solver): export_mps_(exportMPS), export_mps_on_error_(exportMPSOnError), named_splx_problem_(named_splx_problem), - ortools_used_(ortoolsUsed), solver_(solver), current_optim_number_(current_optim_number) { @@ -224,12 +209,5 @@ std::unique_ptr mpsWriterFactory::createOnOptimizationError() std::unique_ptr mpsWriterFactory::createFullmpsWriter() { - if (ortools_used_) - { - return std::make_unique(solver_, current_optim_number_); - } - else - { - return std::make_unique(named_splx_problem_, current_optim_number_); - } + return std::make_unique(solver_, current_optim_number_); } 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/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/hydro.h b/src/solver/variable/include/antares/solver/variable/commons/hydro.h index e0ebdd41e5..46f45aebf3 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/hydro.h +++ b/src/solver/variable/include/antares/solver/variable/commons/hydro.h @@ -21,7 +21,6 @@ #ifndef __SOLVER_VARIABLE_ECONOMY_TimeSeriesValuesHydro_H__ #define __SOLVER_VARIABLE_ECONOMY_TimeSeriesValuesHydro_H__ -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/variable/variable.h" namespace Antares diff --git a/src/solver/variable/include/antares/solver/variable/commons/join.h b/src/solver/variable/include/antares/solver/variable/commons/join.h index de27416213..37f048ec83 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/join.h +++ b/src/solver/variable/include/antares/solver/variable/commons/join.h @@ -21,7 +21,6 @@ #ifndef __SOLVER_VARIABLE_ECONOMY_Join_H__ #define __SOLVER_VARIABLE_ECONOMY_Join_H__ -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/variable/variable.h" namespace Antares diff --git a/src/solver/variable/include/antares/solver/variable/commons/load.h b/src/solver/variable/include/antares/solver/variable/commons/load.h index 3080f2f44a..46b7681e55 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/load.h +++ b/src/solver/variable/include/antares/solver/variable/commons/load.h @@ -21,8 +21,6 @@ #ifndef __SOLVER_VARIABLE_ECONOMY_TimeSeriesValuesLoad_H__ #define __SOLVER_VARIABLE_ECONOMY_TimeSeriesValuesLoad_H__ -#include "antares/solver/simulation/sim_extern_variables_globales.h" - #include "../variable.h" namespace Antares diff --git a/src/solver/variable/include/antares/solver/variable/commons/miscGenMinusRowPSP.h b/src/solver/variable/include/antares/solver/variable/commons/miscGenMinusRowPSP.h index acb74f7d9f..cd7f7d6ba5 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/miscGenMinusRowPSP.h +++ b/src/solver/variable/include/antares/solver/variable/commons/miscGenMinusRowPSP.h @@ -22,7 +22,6 @@ #define __SOLVER_VARIABLE_ECONOMY_MiscGenMinusRowPSP_H__ #include -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/variable/variable.h" namespace Antares diff --git a/src/solver/variable/include/antares/solver/variable/commons/psp.h b/src/solver/variable/include/antares/solver/variable/commons/psp.h index 06814e1800..856a4ac529 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/psp.h +++ b/src/solver/variable/include/antares/solver/variable/commons/psp.h @@ -22,7 +22,6 @@ #define __SOLVER_VARIABLE_ECONOMY_PSP_H__ #include -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/variable/variable.h" namespace Antares diff --git a/src/solver/variable/include/antares/solver/variable/commons/rowBalance.h b/src/solver/variable/include/antares/solver/variable/commons/rowBalance.h index 503d11f981..2dd2d31729 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/rowBalance.h +++ b/src/solver/variable/include/antares/solver/variable/commons/rowBalance.h @@ -22,7 +22,6 @@ #define __SOLVER_VARIABLE_ECONOMY_RowBalance_H__ #include -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/variable/variable.h" namespace Antares diff --git a/src/solver/variable/include/antares/solver/variable/commons/solar.h b/src/solver/variable/include/antares/solver/variable/commons/solar.h index c5ab16422d..ad5f6ca679 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/solar.h +++ b/src/solver/variable/include/antares/solver/variable/commons/solar.h @@ -21,7 +21,6 @@ #ifndef __SOLVER_VARIABLE_ECONOMY_TimeSeriesValuesSolar_H__ #define __SOLVER_VARIABLE_ECONOMY_TimeSeriesValuesSolar_H__ -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/variable/variable.h" namespace Antares 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/commons/wind.h b/src/solver/variable/include/antares/solver/variable/commons/wind.h index 3e0fda355b..d545311fef 100644 --- a/src/solver/variable/include/antares/solver/variable/commons/wind.h +++ b/src/solver/variable/include/antares/solver/variable/commons/wind.h @@ -21,7 +21,6 @@ #ifndef __SOLVER_VARIABLE_ECONOMY_TimeSeriesValuesWind_H__ #define __SOLVER_VARIABLE_ECONOMY_TimeSeriesValuesWind_H__ -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/variable/variable.h" namespace Antares 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/balance.h b/src/solver/variable/include/antares/solver/variable/economy/balance.h index 8547c075ae..6dda7c7b5c 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/balance.h +++ b/src/solver/variable/include/antares/solver/variable/economy/balance.h @@ -21,7 +21,6 @@ #ifndef __SOLVER_VARIABLE_ECONOMY_BALANCE_H__ #define __SOLVER_VARIABLE_ECONOMY_BALANCE_H__ -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/variable/variable.h" namespace Antares 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..a15d662293 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,8 @@ 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; + transitMoyenInterco_ = &study.runtime.transitMoyenInterconnexionsRecalculQuadratique; AncestorType::pResults.initializeFromStudy(study); AncestorType::pResults.reset(); @@ -166,7 +167,7 @@ class FlowQuad: public Variable::IVariable, NextT, VCardFlowQuad { // Flow assessed over all MC years (linear) (void)::memcpy(pValuesForTheCurrentYear.hour, - transitMoyenInterconnexionsRecalculQuadratique[pLinkGlobalIndex].data(), + (*transitMoyenInterco_)[pLinkGlobalIndex].data(), sizeof(double) * pNbHours); // Compute all statistics for the current year (daily,weekly,monthly) @@ -268,6 +269,8 @@ class FlowQuad: public Variable::IVariable, NextT, VCardFlowQuad private: uint pLinkGlobalIndex; uint pNbHours; + std::vector>* transitMoyenInterco_; + //! Intermediate values for each year typename VCardType::IntermediateValuesType pValuesForTheCurrentYear; 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/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/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/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 diff --git a/src/solver/variable/include/antares/solver/variable/state.h b/src/solver/variable/include/antares/solver/variable/state.h index eb3edda98c..cbd55f4949 100644 --- a/src/solver/variable/include/antares/solver/variable/state.h +++ b/src/solver/variable/include/antares/solver/variable/state.h @@ -28,7 +28,6 @@ #include #include -#include "antares/solver/simulation/sim_extern_variables_globales.h" #include "antares/solver/simulation/sim_structure_donnees.h" #include "antares/solver/simulation/sim_structure_probleme_economique.h" 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/CMakeLists.txt b/src/tests/CMakeLists.txt index fcbc5cd6b2..881a346514 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 @@ -68,7 +67,7 @@ if(Python3_Interpreter_FOUND) add_test( NAME milp-cbc - COMMAND Python3::Interpreter -m pytest -m json --solver-path=$ --use-ortools --ortools-solver coin + COMMAND Python3::Interpreter -m pytest -m json --solver-path=$ --solver coin WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/run-study-tests" ) 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/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index 2664dc97d0..dbc29c2ae4 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -201,7 +201,6 @@ BOOST_FIXTURE_TEST_CASE(milp_two_mc_single_unit_single_scenario, StudyFixture) // Use OR-Tools / COIN for MILP auto& p = study->parameters; p.unitCommitment.ucMode = ucMILP; - p.optOptions.ortoolsUsed = true; p.optOptions.ortoolsSolver = "coin"; simulation->create(); @@ -230,7 +229,6 @@ BOOST_FIXTURE_TEST_CASE(milp_two_mc_two_unit_single_scenario, StudyFixture) // Use OR-Tools / COIN for MILP auto& p = study->parameters; p.unitCommitment.ucMode = ucMILP; - p.optOptions.ortoolsUsed = true; p.optOptions.ortoolsSolver = "coin"; simulation->create(); diff --git a/src/tests/inmemory-study/in-memory-study.cpp b/src/tests/inmemory-study/in-memory-study.cpp index 30efd246bf..d889ed66c9 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); } } } @@ -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"); @@ -196,8 +196,6 @@ void SimulationHandler::create() resultWriter_, observer_); Antares::Solver::ScenarioBuilderOwner(study_).callScenarioBuilder(); - - SIM_AllocationTableaux(study_); } // ========================= 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..a174149bd3 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 @@ -4,11 +4,10 @@ from utils.assertions import check class study_run: - def __init__(self, study_path, solver_path, use_ortools, ortools_solver, named_mps_problems, parallel): + def __init__(self, study_path, solver_path, solver_name, named_mps_problems, parallel): self.study_path = study_path self.solver_path = solver_path - self.use_ortools = use_ortools - self.ortools_solver = ortools_solver + self.solverName = solver_name self.named_mps_problems = named_mps_problems self.parallel = parallel self.raise_exception_on_failure = True @@ -23,9 +22,7 @@ def run(self): solver_full_path = str(Path(self.solver_path).resolve()) command = [solver_full_path, "-i", str(self.study_path)] - if self.use_ortools: - command.append('--use-ortools') - command.append('--ortools-solver=' + self.ortools_solver) + command.append('--solver=' + self.solverName) if self.named_mps_problems: command.append('--named-mps-problems') if self.parallel: @@ -39,7 +36,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): diff --git a/src/tests/run-study-tests/conftest.py b/src/tests/run-study-tests/conftest.py index f38b048ca0..f6ff052810 100644 --- a/src/tests/run-study-tests/conftest.py +++ b/src/tests/run-study-tests/conftest.py @@ -1,20 +1,15 @@ import pytest def pytest_addoption(parser): - parser.addoption("--use-ortools", action="store_true", default=False) - parser.addoption("--ortools-solver", action="store", default="sirius") + parser.addoption("--solver", action="store", default="sirius") parser.addoption("--solver-path", action="store") parser.addoption("--named-mps-problems", action="store_true", default=False) parser.addoption("--force-parallel", action="store_true", default=False) parser.addoption("--ts-generator", action="store_true", default=False) @pytest.fixture() -def ortools_solver(request): - return request.config.getoption("--ortools-solver") - -@pytest.fixture() -def use_ortools(request): - return request.config.getoption("--use-ortools") +def solver_name(request): + return request.config.getoption("--solver") @pytest.fixture() def solver_path(request): diff --git a/src/tests/run-study-tests/fixtures.py b/src/tests/run-study-tests/fixtures.py index 5f4945f379..7245fe09c7 100644 --- a/src/tests/run-study-tests/fixtures.py +++ b/src/tests/run-study-tests/fixtures.py @@ -40,8 +40,8 @@ def resultsRemover(study_path): return results_remover(study_path) @pytest.fixture -def simulation(study_path, solver_path, use_ortools, ortools_solver, named_mps_problems, parallel): - return study_run(study_path, solver_path, use_ortools, ortools_solver, named_mps_problems, parallel) +def simulation(study_path, solver_path, solver_name, named_mps_problems, parallel): + return study_run(study_path, solver_path, solver_name, named_mps_problems, parallel) @pytest.fixture(autouse=True) def check_runner(simulation, resultsRemover): diff --git a/src/tests/run-study-tests/readme.md b/src/tests/run-study-tests/readme.md index 5701d722d7..3eb4d27ebb 100644 --- a/src/tests/run-study-tests/readme.md +++ b/src/tests/run-study-tests/readme.md @@ -5,8 +5,11 @@ Here is an automatic testing python script system. This program performs the following : 1. Searches for all studies in a given directory 2. From each study, retrieves the specifications to make checks on the simulation results of that study (see items below) -3. Runs a simlulation on each study -4. Given the results of the simulation on a study, makes the checks retrieved at step 2 on these results (for instance : make sure current results and reference resuts are identical, check for existence or content of output files,...) +3. Runs a simulation on each study +4. Given the results of the simulation on a study, makes the checks retrieved at step 2 on these results. + Examples : + - make sure current results and reference resuts are identical + - check for existence or even content of output files Note that each study found is supposed to contain the definition of checks performed by scripts after the simulation on the study is completed. So, each study is supposed to contain a file **check-config.json** for that purpose. This file is build manually for each study. @@ -42,7 +45,7 @@ In the following, we comment the content of this script. Lines of this scripts a ## Fixtures **pytest** comes with the notion of **fixture**. Fixtures allow executing a piece of code just before a test runs. -To take bebefit of a fixture, a test needs to be given this fixture as argument. +To take benefit of a fixture, a test needs to be given this fixture as argument. Fixture themselves can also be given arguments, we'll see how we do it (in the context of the current testing system) when we talk about **parametrization**. Fixtures return a result to be used in the test. Let's look at a simple test : @@ -212,7 +215,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 diff --git a/src/tests/src/api_internal/test_api.cpp b/src/tests/src/api_internal/test_api.cpp index d60f6315d5..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 { @@ -44,8 +46,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/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 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/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 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(); diff --git a/src/tests/src/libs/antares/study/test_study.cpp b/src/tests/src/libs/antares/study/test_study.cpp index 104b304c0e..fa0348467d 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()); @@ -291,4 +291,37 @@ 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_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 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()); diff --git a/src/tests/src/solver/CMakeLists.txt b/src/tests/src/solver/CMakeLists.txt index e301a13a77..bf920cb80b 100644 --- a/src/tests/src/solver/CMakeLists.txt +++ b/src/tests/src/solver/CMakeLists.txt @@ -1,6 +1,7 @@ - add_subdirectory(simulation) 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/expressions/CMakeLists.txt b/src/tests/src/solver/expressions/CMakeLists.txt new file mode 100644 index 0000000000..319e961a8d --- /dev/null +++ b/src/tests/src/solver/expressions/CMakeLists.txt @@ -0,0 +1,31 @@ +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 + test_Iterators.cpp + test_AstDOTStyleVisitor.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 +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_AstDOTStyleVisitor.cpp b/src/tests/src/solver/expressions/test_AstDOTStyleVisitor.cpp new file mode 100644 index 0000000000..c227cda025 --- /dev/null +++ b/src/tests/src/solver/expressions/test_AstDOTStyleVisitor.cpp @@ -0,0 +1,173 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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; +using namespace Antares::Solver::Visitors; + +BOOST_AUTO_TEST_SUITE(_AstGraphVisitor_) + +class Fixture +{ +public: + Fixture() + { + } + + Node* makeExpression() + { + Node* literalNode = registry_.create(-40.); + Node* negationNode = registry_.create(literalNode); + Node* parameterNode = registry_.create("avogadro_constant"); + Node* multiplicationNode = registry_.create(negationNode, + parameterNode); + Node* variableNode = registry_.create("atoms_count"); + Node* divisionNode = registry_.create(variableNode, multiplicationNode); + Node* portFieldNode = registry_.create("gasStation", "1149"); + Node* portFieldSumNode = registry_.create("portfield", "sum"); + Node* sumNode = registry_.create(divisionNode, portFieldNode, portFieldSumNode); + Node* componentVariableNode = registry_.create("1150", + "otherStation"); + Node* componentParameterNode = registry_.create("1151", + "otherConstant"); + Node* subtractionNode = registry_.create(componentVariableNode, + componentParameterNode); + Node* equalNode = registry_.create(subtractionNode, sumNode); + Node* literalNode2 = registry_.create(53.); + Node* lessThanOrEqualNode = registry_.create(literalNode2, equalNode); + Node* literalNode3 = registry_.create(54.); + Node* greaterThanOrEqualNode = registry_.create( + literalNode3, + lessThanOrEqualNode); + + return greaterThanOrEqualNode; + } + + static std::string expectedDotContent() + { + return R"raw(digraph ExpressionTree { +node[style = filled] + 1 [label=">=", shape="diamond", style="filled", color="yellow"]; + 1 -> 2; + 1 -> 3; + 2 [label="54.000000", shape="box", style="filled, solid", color="lightgray"]; + 3 [label="<=", shape="diamond", style="filled", color="yellow"]; + 3 -> 4; + 3 -> 5; + 4 [label="53.000000", shape="box", style="filled, solid", color="lightgray"]; + 5 [label="==", shape="diamond", style="filled", color="yellow"]; + 5 -> 6; + 5 -> 7; + 6 [label="-", shape="oval", style="filled, rounded", color="aqua"]; + 6 -> 8; + 6 -> 9; + 8 [label="CV(1150,otherStation)", shape="octagon", style="filled, solid", color="goldenrod"]; + 9 [label="CP(1151,otherConstant)", shape="octagon", style="filled, solid", color="springgreen"]; + 7 [label="+", shape="hexagon", style="filled, solid", color="aqua"]; + 7 -> 10; + 10 [label="/", shape="oval", style="filled, rounded", color="aqua"]; + 10 -> 11; + 10 -> 12; + 11 [label="Var(atoms_count)", shape="box", style="filled, solid", color="gold"]; + 12 [label="*", shape="oval", style="filled, rounded", color="aqua"]; + 12 -> 13; + 12 -> 14; + 13 [label="-", shape="invtriangle", style="filled, solid", color="tomato"]; + 13 -> 15; + 15 [label="-40.000000", shape="box", style="filled, solid", color="lightgray"]; + 14 [label="Param(avogadro_constant)", shape="box", style="filled, solid", color="wheat"]; + 7 -> 16; + 16 [label="PF(gasStation,1149)", shape="component", style="filled, solid", color="olive"]; + 7 -> 17; + 17 [label="PFSUM(portfield,sum)", shape="component", style="filled, solid", color="olive"]; +label="AST Diagram(Total nodes : 17)" +labelloc = "t" +subgraph cluster_legend { +label = "Legend"; +style = dashed; +fontsize = 16; +color = lightgrey; +node [shape=plaintext]; + +legend_ComponentParameterNode [ label =" ComponentParameterNode: 1"] +legend_ComponentParameterNode -> legend_ComponentVariableNode [style=invis]; +legend_ComponentVariableNode [ label =" ComponentVariableNode: 1"] +legend_ComponentVariableNode -> legend_DivisionNode [style=invis]; +legend_DivisionNode [ label =" DivisionNode: 1"] +legend_DivisionNode -> legend_EqualNode [style=invis]; +legend_EqualNode [ label =" EqualNode: 1"] +legend_EqualNode -> legend_GreaterThanOrEqualNode [style=invis]; +legend_GreaterThanOrEqualNode [ label =" GreaterThanOrEqualNode: 1"] +legend_GreaterThanOrEqualNode -> legend_LessThanOrEqualNode [style=invis]; +legend_LessThanOrEqualNode [ label =" LessThanOrEqualNode: 1"] +legend_LessThanOrEqualNode -> legend_LiteralNode [style=invis]; +legend_LiteralNode [ label =" LiteralNode: 3"] +legend_LiteralNode -> legend_MultiplicationNode [style=invis]; +legend_MultiplicationNode [ label =" MultiplicationNode: 1"] +legend_MultiplicationNode -> legend_NegationNode [style=invis]; +legend_NegationNode [ label =" NegationNode: 1"] +legend_NegationNode -> legend_ParameterNode [style=invis]; +legend_ParameterNode [ label =" ParameterNode: 1"] +legend_ParameterNode -> legend_PortFieldNode [style=invis]; +legend_PortFieldNode [ label =" PortFieldNode: 1"] +legend_PortFieldNode -> legend_PortFieldSumNode [style=invis]; +legend_PortFieldSumNode [ label =" PortFieldSumNode: 1"] +legend_PortFieldSumNode -> legend_SubtractionNode [style=invis]; +legend_SubtractionNode [ label =" SubtractionNode: 1"] +legend_SubtractionNode -> legend_SumNode [style=invis]; +legend_SumNode [ label =" SumNode: 1"] +legend_SumNode -> legend_VariableNode [style=invis]; +legend_VariableNode [ label =" VariableNode: 1"] +} +} +)raw"; + } + + Registry registry_; +}; + +BOOST_FIXTURE_TEST_CASE( + dot_visitor_is_run_on_complex_expression___resulting_dot_content_as_expected, + Fixture) +{ + std::ostringstream dotContentStream; + + AstDOTStyleVisitor astGraphVisitor; + astGraphVisitor(dotContentStream, makeExpression()); + + BOOST_CHECK_EQUAL(dotContentStream.str(), expectedDotContent()); +} + +BOOST_FIXTURE_TEST_CASE(AstDOTStyleVisitor_name, Registry) +{ + AstDOTStyleVisitor astGraphVisitor; + BOOST_CHECK_EQUAL(astGraphVisitor.name(), "AstDOTStyleVisitor"); +} + +BOOST_AUTO_TEST_SUITE_END() 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..c251662b5a --- /dev/null +++ b/src/tests/src/solver/expressions/test_CloneVisitor.cpp @@ -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 . + */ + +#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., num3 = 77.; + // (num1+num2) + Node* edge = create(create(num1), + create(num2), + create(num3)); + // -((num1+num2+num3)) + Node* negative_edge = create(edge); + // (-((num1+num2+num3))+id1.var) + Node* add_node = create(negative_edge, &cpv); + // (-((-((num1+num2+num3))+id1.var))+id2.par) == + // (-((-((22.000000+8.000000+77.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+77.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..b0da099b80 --- /dev/null +++ b/src/tests/src/solver/expressions/test_CompareVisitor.cpp @@ -0,0 +1,193 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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, neg); + Node* sub = registry_.create(add, neg); + Node* cmp = registry_.create(sub, add); + Node* pf = registry_.create("port", "field"); + Node* pfsum = registry_.create("port", "sum"); + Node* addf = registry_.create(pf, pfsum, 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_FIXTURE_TEST_CASE(compare_empty_sums, ComparisonFixture) +{ + CompareVisitor compareVisitor; + Node* expr1 = registry_.create(); + Node* expr2 = registry_.create(); + BOOST_CHECK(compareVisitor.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(compare_different_size_sums, ComparisonFixture) +{ + CompareVisitor compareVisitor; + Node* literal1 = registry_.create(1.); + Node* literal2 = registry_.create(2.); + Node* expr1 = registry_.create(literal1, literal2); + Node* expr2 = registry_.create(literal1); + BOOST_CHECK(!compareVisitor.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(compare_different_sums, ComparisonFixture) +{ + CompareVisitor compareVisitor; + Node* literal1 = registry_.create(1.); + Node* literal2 = registry_.create(2.); + Node* literal3 = registry_.create(3.); + Node* expr1 = registry_.create(literal1, literal2); + Node* expr2 = registry_.create(literal1, literal3); + BOOST_CHECK(!compareVisitor.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(compare_same_sums, ComparisonFixture) +{ + CompareVisitor compareVisitor; + Node* literal1 = registry_.create(1.); + Node* literal2 = registry_.create(2.); + Node* literal3 = registry_.create(3.); + Node* expr1 = registry_.create(literal1, literal2, literal3); + Node* expr2 = registry_.create(literal1, literal2, literal3); + BOOST_CHECK(compareVisitor.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(compare_same_sums_different_nodes, ComparisonFixture) +{ + CompareVisitor compareVisitor; + Node* literal1 = registry_.create(1.); + Node* literal2 = registry_.create(2.); + Node* literal3 = registry_.create(2.); + Node* expr1 = registry_.create(literal1, literal2); + Node* expr2 = registry_.create(literal1, literal3); + BOOST_CHECK(compareVisitor.dispatch(expr1, expr2)); +} + +BOOST_FIXTURE_TEST_CASE(compare_sum_to_literal, ComparisonFixture) +{ + CompareVisitor compareVisitor; + Node* literal1 = registry_.create(1.); + Node* expr1 = registry_.create(literal1); + BOOST_CHECK(!compareVisitor.dispatch(expr1, literal1)); +} +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..cf3fabd84d --- /dev/null +++ b/src/tests/src/solver/expressions/test_DeepWideTrees.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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, SumNode* 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) +{ + // SumNode's children are not mutable, so we'll replace this empty root with an actual one + SumNode* 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_FIXTURE_TEST_CASE(wide_sum_tree, Registry) +{ + const int nb_operands = 1'000; + std::vector operands(nb_operands); + for (auto& op: operands) + { + op = create(1.); + } + SumNode root(std::move(operands)); + EvalVisitor evalVisitor; + BOOST_CHECK_EQUAL(evalVisitor.dispatch(&root), nb_operands * 1.); +} + +BOOST_AUTO_TEST_SUITE_END() 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..9460f5e465 --- /dev/null +++ b/src/tests/src/solver/expressions/test_Iterators.cpp @@ -0,0 +1,134 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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(_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() 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..590a6e4e85 --- /dev/null +++ b/src/tests/src/solver/expressions/test_LinearVisitor.cpp @@ -0,0 +1,329 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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); + + SumNode 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"); + PortFieldSumNode portFieldSumNode("port", "sum"); + + // 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); + + Node* expr2 = create(mult, &portFieldSumNode); + BOOST_CHECK_EQUAL(printVisitor.dispatch(expr2), "((65.000000*p1)+port.sum)"); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr2), LinearStatus::CONSTANT); +} + +BOOST_FIXTURE_TEST_CASE(LinearityVisitor_name, Registry) +{ + LinearityVisitor linearityVisitor; + BOOST_CHECK_EQUAL(linearityVisitor.name(), "LinearityVisitor"); +} + +BOOST_FIXTURE_TEST_CASE(sum_node_cases, Registry) +{ + LinearityVisitor linearVisitor; + + Node* expr = create(); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::CONSTANT); + + expr = create(create(41), create(4)); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::CONSTANT); + + expr = create( + create(create(5), create("a"))); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::LINEAR); + + expr = create(create(41), + create(create(5), + create("b"))); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::LINEAR); + + expr = create( + create(create("c"), create("d"))); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::NON_LINEAR); + + expr = create(create(41), + create(create(5), + create("e")), + create(create("f"), + create("g"))); + BOOST_CHECK_EQUAL(linearVisitor.dispatch(expr), LinearStatus::NON_LINEAR); +} +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..8ea1a61b1e --- /dev/null +++ b/src/tests/src/solver/expressions/test_PrintAndEvalNodes.cpp @@ -0,0 +1,378 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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(print_add_one_literal, Registry) +{ + Node* root = create(create(215)); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(printed, + "(215.000000)"); // TODO Number of decimals implementation dependent ? +} + +BOOST_FIXTURE_TEST_CASE(print_add_zero_literal, Registry) +{ + Node* root = create(); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(printed, "()"); +} + +BOOST_FIXTURE_TEST_CASE(print_add_six_literals, Registry) +{ + Node* root = create(create(21), + create(2), + create(34), + create(56), + create(12), + create(86)); + + PrintVisitor printVisitor; + const auto printed = printVisitor.dispatch(root); + + BOOST_CHECK_EQUAL( + printed, + "(21.000000+2.000000+34.000000+56.000000+12.000000+86.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_add_one_literal, Registry) +{ + Node* root = create(create(215)); + + EvalVisitor evalVisitor; + double eval = evalVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(eval, 215.); +} + +BOOST_FIXTURE_TEST_CASE(eval_add_zero_literal, Registry) +{ + Node* root = create(); + + EvalVisitor evalVisitor; + double eval = evalVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(eval, 0.); +} + +BOOST_FIXTURE_TEST_CASE(eval_add_six_literals, Registry) +{ + Node* root = create(create(21), + create(2), + create(34), + create(56), + create(12), + create(86)); + + EvalVisitor evalVisitor; + double eval = evalVisitor.dispatch(root); + + BOOST_CHECK_EQUAL(eval, 211.); +} + +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_SumNode, 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(print_port_field_sum_node, Registry) +{ + PortFieldSumNode 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) +{ + SumNode* 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(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..dc310c7aa1 --- /dev/null +++ b/src/tests/src/solver/expressions/test_SubstitutionVisitor.cpp @@ -0,0 +1,199 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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; + +// 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))[0], variables.first); + + // We expect to find an original node on the right + auto* right_substituted = (*dynamic_cast(subsd))[1]; + 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() + +BOOST_AUTO_TEST_SUITE(_PortfieldSubstitutionVisitor_) + +class SubstitutionFixture: public Registry +{ +public: + Node* originalExpression() + { + Node* port1 = create("port", "literal"); + Node* port2 = create("another port", "not a literal"); + Node* root = create(port1, port2); + return root; + } + + Node* expectedExpressionAfterSubstitution() + { + Node* node1 = create(10); + Node* port2 = create("another port", "not a literal"); + Node* root = create(node1, port2); + return root; + } + + Node* substitute(Node* original) + { + PortFieldSubstitutionContext ctx; + ctx.portfield.emplace(std::piecewise_construct, + std::forward_as_tuple("port", "literal"), + std::forward_as_tuple(create(10))); + + PortFieldSubstitutionVisitor sub(*this, ctx); + return sub.dispatch(original); + } +}; + +BOOST_FIXTURE_TEST_CASE(PortfieldSubstitutionVisitor_simple, SubstitutionFixture) + +{ + Node* original = originalExpression(); + Node* substituted = substitute(original); + Node* expected = expectedExpressionAfterSubstitution(); + + CompareVisitor cmp; + BOOST_CHECK(cmp.dispatch(substituted, expected)); +} + +BOOST_FIXTURE_TEST_CASE(PortfieldSubstitutionVisitor_name, Registry) +{ + PortFieldSubstitutionContext ctx; + + PortFieldSubstitutionVisitor substitutionVisitor(*this, ctx); + BOOST_CHECK_EQUAL(substitutionVisitor.name(), "PortFieldSubstitutionVisitor"); +} + +class SumSubstitutionFixture: public Registry +{ +public: + Node* originalExpression() + { + Node* port1 = create("port", "sum of literal"); + Node* port2 = create("another port", "another field"); + Node* root = create(port1, port2); + return root; + } + + Node* expectedExpressionAfterSubstitution() + { + Node* node1 = create(create(12), create(7)); + Node* port2 = create("another port", "another field"); + Node* root = create(node1, port2); + return root; + } + + Node* substitute(Node* original) + { + PortFieldSumSubstitutionContext ctx; + Node* sum1 = create(12); + Node* sum2 = create(7); + std::vector v = {sum1, sum2}; + ctx.portfieldSum.emplace(std::piecewise_construct, + std::forward_as_tuple("port", "sum of literal"), + std::forward_as_tuple(v)); + + PortFieldSumSubstitutionVisitor sub(*this, ctx); + return sub.dispatch(original); + } +}; + +BOOST_FIXTURE_TEST_CASE(PortFieldSumSubstitutionVisitor_simple, SumSubstitutionFixture) + +{ + Node* original = originalExpression(); + Node* substituted = substitute(original); + Node* expected = expectedExpressionAfterSubstitution(); + + CompareVisitor cmp; + BOOST_CHECK(cmp.dispatch(substituted, expected)); +} + +BOOST_FIXTURE_TEST_CASE(PortfieldSumSubstitutionVisitor_name, Registry) +{ + PortFieldSumSubstitutionContext ctx; + + PortFieldSumSubstitutionVisitor substitutionVisitor(*this, ctx); + BOOST_CHECK_EQUAL(substitutionVisitor.name(), "PortFieldSumSubstitutionVisitor"); +} + +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..030318d517 --- /dev/null +++ b/src/tests/src/solver/expressions/test_TimeIndexVisitor.cpp @@ -0,0 +1,201 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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 literalNode, parameterNode1 and variableNode1 is time and scenario dependent + Node* expr = create(&literalNode, ¶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, + &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..b21caac631 --- /dev/null +++ b/src/tests/src/solver/expressions/test_nodes.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 . + */ + +#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_AUTO_TEST_CASE(PortFieldSumNodeTest) +{ + std::string portName1("p1"); + std::string fieldName1("f1"); + + PortFieldSumNode pfs(portName1, fieldName1); + BOOST_CHECK_EQUAL(pfs.getPortName(), portName1); + BOOST_CHECK_EQUAL(pfs.getFieldName(), fieldName1); +} + +BOOST_FIXTURE_TEST_CASE(nodes_name, Registry) +{ + auto literalNode = create(2024.2); + std::map nodes = { + {literalNode, "LiteralNode"}, + {create(literalNode, literalNode), "SumNode"}, + {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"}, + {create(literalNode->name(), literalNode->name()), "PortFieldSumNode"}}; + + for (auto [node, name]: nodes) + { + BOOST_CHECK_EQUAL(node->name(), name); + } +} + +BOOST_AUTO_TEST_SUITE_END() 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() 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..ae048140aa --- /dev/null +++ b/src/tests/src/solver/modeler/api/CMakeLists.txt @@ -0,0 +1,24 @@ +set(EXECUTABLE_NAME unit-tests-for-modeler-api) +add_executable(${EXECUTABLE_NAME}) + +target_sources(${EXECUTABLE_NAME} + PRIVATE + test_main.cpp + testModelerLinearProblemWithOrtools.cpp + testModelerLPbuilder.cpp +) +target_include_directories(${EXECUTABLE_NAME} + PRIVATE + "${src_solver_optimisation}" +) + +target_link_libraries(${EXECUTABLE_NAME} + PRIVATE + Boost::unit_test_framework + Antares::modeler-ortools-impl +) + +set_target_properties(${EXECUTABLE_NAME} PROPERTIES FOLDER Unit-tests) +add_test(NAME ${EXECUTABLE_NAME} COMMAND ${EXECUTABLE_NAME}) +set_property(TEST ${EXECUTABLE_NAME} PROPERTY LABELS unit) + diff --git a/src/tests/src/solver/modeler/api/mock-fillers/OneConstraintFiller.h b/src/tests/src/solver/modeler/api/mock-fillers/OneConstraintFiller.h new file mode 100644 index 0000000000..cb1f9db3e9 --- /dev/null +++ b/src/tests/src/solver/modeler/api/mock-fillers/OneConstraintFiller.h @@ -0,0 +1,30 @@ +#pragma once + +#include "antares/solver/modeler/api/linearProblemFiller.h" + +namespace Antares::Solver::Modeler::Api +{ + +class OneConstraintFiller: public LinearProblemFiller +{ +public: + explicit OneConstraintFiller() = default; + void addVariables(ILinearProblem& pb, LinearProblemData& data) override; + void addConstraints(ILinearProblem& pb, LinearProblemData& data) override; + void addObjective(ILinearProblem& pb, LinearProblemData& data) override; +}; + +void OneConstraintFiller::addVariables(ILinearProblem& pb, LinearProblemData& data) +{ +} + +void OneConstraintFiller::addConstraints(ILinearProblem& pb, LinearProblemData& data) +{ + pb.addConstraint(1, 2, "constraint-by-OneConstraintFiller"); +} + +void OneConstraintFiller::addObjective(ILinearProblem& pb, LinearProblemData& data) +{ +} + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/tests/src/solver/modeler/api/mock-fillers/OneVarFiller.h b/src/tests/src/solver/modeler/api/mock-fillers/OneVarFiller.h new file mode 100644 index 0000000000..5d2ba08b55 --- /dev/null +++ b/src/tests/src/solver/modeler/api/mock-fillers/OneVarFiller.h @@ -0,0 +1,35 @@ +#pragma once + +#include "antares/solver/modeler/api/linearProblemFiller.h" + +namespace Antares::Solver::Modeler::Api +{ + +class OneVarFiller: public LinearProblemFiller +{ +public: + explicit OneVarFiller() = default; + void addVariables(ILinearProblem& pb, LinearProblemData& data) override; + void addConstraints(ILinearProblem& pb, LinearProblemData& data) override; + void addObjective(ILinearProblem& pb, LinearProblemData& data) override; + +private: + std::string added_var_name_ = "var-by-OneVarFiller"; +}; + +void OneVarFiller::addVariables(ILinearProblem& pb, LinearProblemData& data) +{ + pb.addNumVariable(0, 1, added_var_name_); +} + +void OneVarFiller::addConstraints(ILinearProblem& pb, LinearProblemData& data) +{ +} + +void OneVarFiller::addObjective(ILinearProblem& pb, LinearProblemData& data) +{ + auto* var = pb.getVariable(added_var_name_); + pb.setObjectiveCoefficient(var, 1); +} + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/tests/src/solver/modeler/api/mock-fillers/TwoVarsTwoConstraintsFiller.h b/src/tests/src/solver/modeler/api/mock-fillers/TwoVarsTwoConstraintsFiller.h new file mode 100644 index 0000000000..e8671644df --- /dev/null +++ b/src/tests/src/solver/modeler/api/mock-fillers/TwoVarsTwoConstraintsFiller.h @@ -0,0 +1,33 @@ +#pragma once + +#include "antares/solver/modeler/api/linearProblemFiller.h" + +namespace Antares::Solver::Modeler::Api +{ + +class TwoVarsTwoConstraintsFiller: public LinearProblemFiller +{ +public: + explicit TwoVarsTwoConstraintsFiller() = default; + void addVariables(ILinearProblem& pb, LinearProblemData& data) override; + void addConstraints(ILinearProblem& pb, LinearProblemData& data) override; + void addObjective(ILinearProblem& pb, LinearProblemData& data) override; +}; + +void TwoVarsTwoConstraintsFiller::addVariables(ILinearProblem& pb, LinearProblemData& data) +{ + pb.addNumVariable(0, 1, "var-1-by-TwoVarsTwoConstraintsFiller"); + pb.addNumVariable(0, 3, "var-2-by-TwoVarsTwoConstraintsFiller"); +} + +void TwoVarsTwoConstraintsFiller::addConstraints(ILinearProblem& pb, LinearProblemData& data) +{ + pb.addConstraint(1, 2, "constr-1-by-TwoVarsTwoConstraintsFiller"); + pb.addConstraint(1, 3, "constr-2-by-TwoVarsTwoConstraintsFiller"); +} + +void TwoVarsTwoConstraintsFiller::addObjective(ILinearProblem& pb, LinearProblemData& data) +{ +} + +} // namespace Antares::Solver::Modeler::Api diff --git a/src/tests/src/solver/modeler/api/testModelerLPbuilder.cpp b/src/tests/src/solver/modeler/api/testModelerLPbuilder.cpp new file mode 100644 index 0000000000..ccdccf251a --- /dev/null +++ b/src/tests/src/solver/modeler/api/testModelerLPbuilder.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 . + */ +#define WIN32_LEAN_AND_MEAN + +#include + +#include +#include + +#include "mock-fillers/OneConstraintFiller.h" +#include "mock-fillers/OneVarFiller.h" +#include "mock-fillers/TwoVarsTwoConstraintsFiller.h" + +using namespace Antares::Solver::Modeler::Api; +using namespace Antares::Solver::Modeler::OrtoolsImpl; + +struct Fixture +{ + Fixture() + { + pb = std::make_unique(false, "sirius"); + } + + std::vector fillers; + LinearProblemData LP_Data; + std::unique_ptr pb; +}; + +BOOST_AUTO_TEST_SUITE(tests_on_linear_problem_builder) + +BOOST_FIXTURE_TEST_CASE(no_filler_given_to_builder___nothing_built, Fixture) +{ + LinearProblemBuilder lpBuilder(fillers); + lpBuilder.build(*pb, LP_Data); + + BOOST_CHECK_EQUAL(pb->variableCount(), 0); + BOOST_CHECK_EQUAL(pb->constraintCount(), 0); +} + +BOOST_FIXTURE_TEST_CASE(one_var_filler___the_var_is_built, Fixture) +{ + auto oneVarFiller = std::make_unique(); + fillers = {oneVarFiller.get()}; + + LinearProblemBuilder lpBuilder(fillers); + lpBuilder.build(*pb, LP_Data); + + BOOST_CHECK_EQUAL(pb->variableCount(), 1); + BOOST_CHECK_EQUAL(pb->constraintCount(), 0); + auto* var = pb->getVariable("var-by-OneVarFiller"); + BOOST_CHECK(var); + BOOST_CHECK_EQUAL(pb->getObjectiveCoefficient(var), 1); +} + +BOOST_FIXTURE_TEST_CASE(one_constraint_filler___the_constraint_is_built, Fixture) +{ + auto oneConstrFiller = std::make_unique(); + fillers = {oneConstrFiller.get()}; + + LinearProblemBuilder lpBuilder(fillers); + lpBuilder.build(*pb, LP_Data); + + BOOST_CHECK_EQUAL(pb->variableCount(), 0); + BOOST_CHECK_EQUAL(pb->constraintCount(), 1); + BOOST_CHECK(pb->getConstraint("constraint-by-OneConstraintFiller")); +} + +BOOST_FIXTURE_TEST_CASE(two_fillers_given_to_builder___all_is_built, Fixture) +{ + auto oneVarFiller = std::make_unique(); + auto oneConstrFiller = std::make_unique(); + + fillers = {oneVarFiller.get(), oneConstrFiller.get()}; + + LinearProblemBuilder lpBuilder(fillers); + lpBuilder.build(*pb, LP_Data); + + BOOST_CHECK_EQUAL(pb->constraintCount(), 1); + BOOST_CHECK(pb->getConstraint("constraint-by-OneConstraintFiller")); + BOOST_CHECK_EQUAL(pb->variableCount(), 1); +} + +BOOST_FIXTURE_TEST_CASE(three_fillers_given_to_builder___3_vars_3_constr_are_built, Fixture) +{ + auto oneVarFiller = std::make_unique(); + auto oneConstrFiller = std::make_unique(); + auto twoVarsTwoConstrFiller = std::make_unique(); + fillers = {oneVarFiller.get(), oneConstrFiller.get(), twoVarsTwoConstrFiller.get()}; + + LinearProblemBuilder lpBuilder(fillers); + lpBuilder.build(*pb, LP_Data); + + BOOST_CHECK_EQUAL(pb->variableCount(), 3); + BOOST_CHECK_EQUAL(pb->constraintCount(), 3); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/modeler/api/testModelerLinearProblemWithOrtools.cpp b/src/tests/src/solver/modeler/api/testModelerLinearProblemWithOrtools.cpp new file mode 100644 index 0000000000..7c1f8f84e3 --- /dev/null +++ b/src/tests/src/solver/modeler/api/testModelerLinearProblemWithOrtools.cpp @@ -0,0 +1,238 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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 + +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() diff --git a/src/tests/src/solver/modeler/api/test_main.cpp b/src/tests/src/solver/modeler/api/test_main.cpp new file mode 100644 index 0000000000..0d5864e717 --- /dev/null +++ b/src/tests/src/solver/modeler/api/test_main.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.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 + +#define WIN32_LEAN_AND_MEAN + +#include 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/adequacy_patch/adequacy_patch.cpp b/src/tests/src/solver/optimisation/adequacy_patch/adequacy_patch.cpp index 377969fd5d..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,50 +31,14 @@ #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/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; - -// 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); -} +namespace tt = boost::test_tools; static const double flowArea0toArea1_positive = 10; static const double flowArea0toArea1_negative = -10; @@ -111,8 +75,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 +94,7 @@ std::pair calculateAreaFlowBalanceForOneTimeStep( double densNew; std::tie(netPositionInit, densNew, std::ignore) = calculateAreaFlowBalance( &problem, - adqPatchParams.localMatching.setToZeroOutsideInsideLinks, + adqPatchParams.setToZeroOutsideInsideLinks, Area, hour); @@ -143,119 +106,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 @@ -547,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() 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() 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/batchrun/main.cpp b/src/tools/batchrun/main.cpp index 2ae0bc03e1..e2fb2e2278 100644 --- a/src/tools/batchrun/main.cpp +++ b/src/tools/batchrun/main.cpp @@ -74,7 +74,7 @@ String sendToNull() #endif } -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { // locale InitializeDefaultLocale(); diff --git a/src/tools/config/main.cpp b/src/tools/config/main.cpp index 0cb15eac90..947b1f5a69 100644 --- a/src/tools/config/main.cpp +++ b/src/tools/config/main.cpp @@ -34,7 +34,7 @@ using namespace Yuni; using namespace Antares; -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { // locale InitializeDefaultLocale(); diff --git a/src/tools/finder/main.cpp b/src/tools/finder/main.cpp index 02ea7fdb7f..0e04320741 100644 --- a/src/tools/finder/main.cpp +++ b/src/tools/finder/main.cpp @@ -68,7 +68,7 @@ class MyStudyFinder: public Data::StudyFinder bool csv; }; -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { // locale InitializeDefaultLocale(); diff --git a/src/tools/kirchhoff-cbuilder/kirchhoff-cbuilder.h b/src/tools/kirchhoff-cbuilder/kirchhoff-cbuilder.h index e3afd8ab2b..1591840d1b 100644 --- a/src/tools/kirchhoff-cbuilder/kirchhoff-cbuilder.h +++ b/src/tools/kirchhoff-cbuilder/kirchhoff-cbuilder.h @@ -24,7 +24,7 @@ static void NotEnoughMemory(); -bool initResources(int argc, char* argv[]); +bool initResources(int argc, const char* argv[]); bool initComponents(std::shared_ptr 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/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) { } diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index d923d26a6c..baece8ca45 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -28,7 +28,6 @@ #include #include "antares/tools/ts-generator/linksTSgenerator.h" #include "antares/tools/ts-generator/tsGenerationOptions.h" -using namespace Antares::TSGenerator; using namespace Antares::TSGenerator; @@ -64,7 +63,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/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/application/study.cpp b/src/ui/simulator/application/study.cpp index c71e4de6ca..23a1fcd957 100644 --- a/src/ui/simulator/application/study.cpp +++ b/src/ui/simulator/application/study.cpp @@ -1091,7 +1091,7 @@ void RunSimulationOnTheStudy(Data::Study::Ptr study, Solver::Feature features, bool preproOnly, bool useOrtools, - const std::string& ortoolsSolver) + const std::string& solverName) { if (!study) // A valid study would be better { @@ -1212,7 +1212,7 @@ void RunSimulationOnTheStudy(Data::Study::Ptr study, cmd << " --use-ortools"; // add solver name for ortools - cmd << " --ortools-solver=" << ortoolsSolver; + cmd << " --ortools-solver=" << solverName; } // Go go go ! diff --git a/src/ui/simulator/application/study.h b/src/ui/simulator/application/study.h index 569de2e9e4..4cb7b878da 100644 --- a/src/ui/simulator/application/study.h +++ b/src/ui/simulator/application/study.h @@ -114,7 +114,7 @@ bool CheckIfInsideAStudyFolder(const AnyString& path, bool quiet = false); ** \param simuComments Comments for the simulation ** \param ignoreWarnings True if warnings can be silently ignored ** \param useOrtools True if ortools must be used by antares-solver -** \param ortoolsSolver Ortools solver used in case of ortools use by antares-solver +** \param solverName Solver used */ void RunSimulationOnTheStudy(Data::Study::Ptr study, const YString& simuName, @@ -123,7 +123,7 @@ void RunSimulationOnTheStudy(Data::Study::Ptr study, Solver::Feature features = Solver::standard, bool preproOnly = false, bool useOrtools = false, - const std::string& ortoolsSolver = "sirius"); + const std::string& solverName = "sirius"); /*! ** \brief Update the state of controls 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; 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) { 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); } } } 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"; diff --git a/src/ui/simulator/windows/simulation/run.cpp b/src/ui/simulator/windows/simulation/run.cpp index e32fb55101..8be0054bd9 100644 --- a/src/ui/simulator/windows/simulation/run.cpp +++ b/src/ui/simulator/windows/simulation/run.cpp @@ -323,10 +323,10 @@ Run::Run(wxWindow* parent, bool preproOnly) : = Antares::Component::CreateLabel(pBigDaddy, wxT("Ortools solver : ")); pOrtoolsSolverCombox = new wxComboBox(pBigDaddy, wxID_ANY); - std::list ortoolsSolverList = getAvailableOrtoolsSolverName(); - for (const std::string& ortoolsSolver : ortoolsSolverList) + std::list solverList = getAvailableOrtoolsSolverName(); + for (const std::string& solverName : solverList) { - pOrtoolsSolverCombox->Append(ortoolsSolver); + pOrtoolsSolverCombox->Append(solverName); } // Ortools solver selection visibility