diff --git a/.github/workflows/add_release_documentation.yml b/.github/workflows/add_release_documentation.yml index fcf9326d7d..be9fd17f94 100644 --- a/.github/workflows/add_release_documentation.yml +++ b/.github/workflows/add_release_documentation.yml @@ -146,7 +146,7 @@ jobs: ./generate_redirections.sh $GITHUB_REF_NAME - name: Create Pull Request at DLR-AMR/t8code-website if: ${{ env.MINOR_RELEASE == 'true' }} - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: path: t8code-website title: Add documentation for t8code ${{ github.ref_name }} diff --git a/.github/workflows/build_cmake_tarball.yml b/.github/workflows/build_cmake_tarball.yml new file mode 100644 index 0000000000..2f50850e86 --- /dev/null +++ b/.github/workflows/build_cmake_tarball.yml @@ -0,0 +1,165 @@ +name: CMake Tarball + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2024 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# +# This github CI script constructs a tarball and checks if it is build correctly. +# + +env: + MAKEFLAGS: "-j2 V=0" + + +on: + push: + branches: + - main + - develop + - CI-*tarball* # for testing this script, all feature branches with "tarball" in their name + pull_request: + branches: + - main + - develop + workflow_dispatch: + +jobs: + build: + + if: (github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') || (github.event_name != 'schedule') + runs-on: ubuntu-20.04 + container: dlramr/t8code-ubuntu:t8-dependencies + timeout-minutes: 90 + steps: +# +# Setup and bootstrap +# + - uses: actions/checkout@v4 + with: + fetch-tags: true # required to get version tags + fetch-depth: 0 # required to get all history, especially the version tags + - name: install sudo + run: apt update && apt install sudo + # On the github Ubuntu 20.04, sudo is not available by default + # we need it, however, to update/upgrade our packages. + - name: Update packages + run: sudo apt-get update && sudo apt-get upgrade -y + # This step is necessary to get the newest package data + - name: disable ownership checks + run: git config --global --add safe.directory '*' + - name: init submodules + run: git submodule init + - name: update submodules + run: git submodule update + - name: bootstrap + run: ./bootstrap +# +# T8CODE +# with p4est and sc as internal dependencies which is needed for make dist +# +# + - name: less-test option + if: ${{ inputs.LESS_TESTS }} + run: export LESS_TEST_OPTION="-DT8CODE_ENABLE_LESS_TESTS=ON" + && echo LESS_TEST_OPTION="$LESS_TEST_OPTION" >> $GITHUB_ENV + - name: build config variables + run: export CONFIG_OPTIONS="${LESS_TEST_OPTION} -GNinja -DT8CODE_USE_SYSTEM_SC=OFF -DT8CODE_USE_SYSTEM_P4EST=OFF -DT8CODE_BUILD_PEDANTIC=ON -DT8CODE_ENABLE_MPI=$MPI -DCMAKE_BUILD_TYPE=$BUILD_TYPE" + && echo CONFIG_OPTIONS="$CONFIG_OPTIONS" >> $GITHUB_ENV + - name: cmake + run: mkdir build && cd build && cmake ../ $CONFIG_OPTIONS + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: config.log + path: build/config.log +# Start building tarball + - name: Install pandoc + uses: nikeee/setup-pandoc@v1 + - name: Test pandoc + run: pandoc --version +# Build the tarball + - name: Make tarball + run: cd build && ninja GenerateVersionFile && ninja package_source && mkdir tarballs && mv package/*Source.tar.gz tarballs +# Upload the tarball + - name: upload tarball + uses: actions/upload-artifact@v4 + with: + name: tarballs + path: build/tarballs + + test-tarball: + needs: build + runs-on: ubuntu-20.04 + container: dlramr/t8code-ubuntu:t8-dependencies + timeout-minutes: 90 + steps: + - name: install sudo + run: apt update && apt install sudo + # On the github Ubuntu 20.04, sudo is not available by default + # we need it, however, to update/upgrade our packages. + - name: Update packages + run: sudo apt-get update && sudo apt-get upgrade -y + # This step is necessary to get the newest package data + - name: Download tarball + uses: actions/download-artifact@v4 + with: + name: tarballs + path: tarballs + - name: Extract tarball + run: tar xzf tarballs/*.tar.gz -C $RUNNER_TEMP + - name: update Github_env + run: export TAR_DIR="$RUNNER_TEMP/`basename tarballs/*.tar.gz .tar.gz`" && + echo TAR_DIR="$TAR_DIR" >>$GITHUB_ENV + +# build config vars + - name: less-test-option + if: github.event_name == 'pull_request' + run: export LESS_TEST_OPTION="-DT8CODE_ENABLE_LESS_TESTS=ON" + && echo LESS_TEST_OPTION="$LESS_TEST_OPTION" >> $GITHUB_ENV + - name: build config variables + run: export CONFIG_OPTIONS="${LESS_TEST_OPTION} -GNinja -DT8CODE_USE_SYSTEM_SC=OFF -DT8CODE_USE_SYSTEM_P4EST=OFF -DT8CODE_BUILD_PEDANTIC=ON -DT8CODE_ENABLE_MPI=$MPI -DCMAKE_BUILD_TYPE=$BUILD_TYPE" + && echo CONFIG_OPTIONS="$CONFIG_OPTIONS" >> $GITHUB_ENV + - name: Check vars + run: echo "[$CONFIG_DEBUG]" + - name: configure from Tarball + run: mkdir build_tar && cd build_tar && cmake $TAR_DIR $CONFIG_OPTIONS + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: build_tar.log + path: build_tar/config.log + - name: build + run: cd build_tar && ninja + - name: install + run: cd build_tar && ninja install + - name: check serial + run: cd build_tar && ctest -R _serial + - name: check parallel + run: cd build_tar && ctest -R _parallel + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: build_tar.log + path: build_tar/test-suite.log + + diff --git a/.github/workflows/ci_playground.yml b/.github/workflows/ci_playground.yml deleted file mode 100644 index 73039d43db..0000000000 --- a/.github/workflows/ci_playground.yml +++ /dev/null @@ -1,121 +0,0 @@ -name: CI-playground - -# This file is part of t8code. -# t8code is a C library to manage a collection (a forest) of multiple -# connected adaptive space-trees of general element types in parallel. -# -# Copyright (C) 2015 the developers -# -# t8code is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# t8code is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with t8code; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The purpose of this script is for debugging and testing -# the github CI without the need to trigger the whole workflow. -# Its contents may change arbitrarily. - -on: - push: - branches: - - feature-*CI* # for testing this script, all feature branches with "CI" in their name - - workflow_dispatch: # Be able to trigger this manually on github.com - -jobs: - test_vars: - runs-on: ubuntu-20.04 - container: dlramr/t8code-ubuntu:t8-dependencies - env: - SC_DEBUG: ../sc/build_debug - P4EST_DEBUG: ../p4est/build_debug - steps: - - name: Test vars - run: echo "[$SC_DEBUG] [$P4EST_DEBUG]" - - name: New envs - run: echo NEW_VAR=blub >> $GITHUB_ENV - - name: Test var - run: echo $NEW_VAR ${{ env.NEW_VAR }} - - name: Test var for if not set - run: echo IF_VAR= >> $GITHUB_ENV - - name: print if 0 or var set - if: ${{ 0 || env.IF_VAR }} - run: echo $IF_VAR - - name: print if var set - if: ${{ env.IF_VAR }} - run: echo $IF_VAR - - name: print if 0 - if: 0 - run: echo 0 is true - - name: print var - run: echo $IF_VAR - - name: Test var for if set - run: echo IF_VAR2=1 >> $GITHUB_ENV - - name: print if var set - if: ${{ env.IF_VAR2 }} - run: echo $IF_VAR2 - - name: print if 0 or var set - if: ${{ 0 || env.IF_VAR2 }} - run: echo $IF_VAR2 - - name: print if 0 - if: 0 - run: echo 0 is true - - name: print var - run: echo $IF_VAR2 - - test_cache: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v4 - with: - fetch-tags: true # required to get version tags - fetch-depth: 0 # required to get all history, especially the version tags - - name: install sudo - run: apt update && apt install sudo - # On the github Ubuntu 20.04, sudo is not available by default - # we need it, however, to update/upgrade our packages. - - name: Update packages - run: sudo apt-get update && sudo apt-get upgrade -y - # This step is necessary to get the newest package data - - name: define sc var - run: hash=`git rev-parse HEAD:sc` && echo sc_commit=$hash >> $GITHUB_ENV - - name: define p4est var - run: hash=`git rev-parse HEAD:sc` && echo sc_commit=$hash >> $GITHUB_ENV - - name: Test var - run: echo $sc_commit $p4est_commit - # Cache sc - - name: create folder var - run: echo test_path=$PWD/test_path >> $GITHUB_ENV - - name: Cache SC - id: sc_cache - uses: actions/cache@v4 - with: - path: | - sc/build_test - sc/build_test_ci/install - ${{ env.test_path }} - # increase this number to trigger new caching - key: sc-3 - - name: create build and write commit - if: steps.sc_cache.outputs.cache-hit != 'true' - run: mkdir sc/build_test - && date >> sc/build_test/commit.log - && echo $sc_commit >> sc/build_test/commit.log - && mkdir sc/build_test_ci && mkdir sc/build_test_ci/install - && date >> sc/build_test_ci/install/commit.log - && mkdir test_path - && date >> test_path/test.log - - name: print files - run: cat sc/build_test/commit.log - && cat sc/build_test_ci/install/commit.log - && cat test_path/test.log diff --git a/.github/workflows/tests_cmake_preparation.yml b/.github/workflows/tests_cmake_preparation.yml new file mode 100644 index 0000000000..4325e59f35 --- /dev/null +++ b/.github/workflows/tests_cmake_preparation.yml @@ -0,0 +1,196 @@ +name: CMake tests preparation + + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2024 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +on: + workflow_call: + inputs: + MAKEFLAGS: + required: true + type: string + description: 'Make flags to use for compilation (like -j4)' + IGNORE_CACHE: + required: false + type: boolean + default: false + description: 'Ignore cache and force recompilation' + CACHE_COUNTER: + required: true + type: number + description: 'Counter to force updating the cache' + MPI: + required: true + type: string + description: 'Use MPI for compilation (ON/OFF)' + outputs: + USED_CACHE: + description: "Whether the cache was used" + value: ${{ jobs.cmake_preparation.outputs.USED_CACHE }} + +env: + USED_CACHE: ${{ !inputs.IGNORE_CACHE }} + +jobs: + cmake_preparation: + runs-on: ubuntu-latest + container: dlramr/t8code-ubuntu:t8-dependencies + timeout-minutes: 10 + outputs: + USED_CACHE: ${{ steps.used_cache.outputs.USED_CACHE }} + steps: +# +# Setup +# + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Update packages + run: apt-get update && apt-get upgrade -y + # This seems to be necessary because of the docker container + - name: disable ownership checks + run: git config --global --add safe.directory '*' + - name: init submodules + run: git submodule init + - name: update submodules + run: git submodule update + - name: Get input vars + run: export MAKEFLAGS="${{ inputs.MAKEFLAGS }}" + && export IGNORE_CACHE="${{ inputs.IGNORE_CACHE }}" + && export CACHE_COUNTER="${{ inputs.CACHE_COUNTER }}" + && export MPI="${{ inputs.MPI }}" + && echo MAKEFLAGS="$MAKEFLAGS" >> $GITHUB_ENV + && echo IGNORE_CACHE="$IGNORE_CACHE" >> $GITHUB_ENV + && echo CACHE_COUNTER="$CACHE_COUNTER" >> $GITHUB_ENV + && echo MPI="$MPI" >> $GITHUB_ENV +# +# SC installation +# + - name: store sc folders in var + run: echo SC_BUILD=$PWD/sc/build >> $GITHUB_ENV + && echo SC_DEBUG=$PWD/sc/build/Debug >> $GITHUB_ENV + && echo SC_RELEASE=$PWD/sc/build/Release >> $GITHUB_ENV + - name: Get sc commit hash + run: hash=`git rev-parse HEAD:sc` && echo sc_commit=$hash >> $GITHUB_ENV + - name: Check cache for previous sc installation + id: sc_cmake_cache + uses: actions/cache@v4 + with: + path: | + ${{ env.SC_DEBUG }} + ${{ env.SC_RELEASE }} + # You can increase the counter at the end to force a new key and hence recomputing the cache + key: sc-cmake-MPI-${{ inputs.MPI }}-${{ env.sc_commit }}-${{ inputs.CACHE_COUNTER }} + - name: Log that no cache was found + run: echo USED_CACHE=0 >> $GITHUB_ENV + if: ${{ steps.sc_cmake_cache.outputs.cache-hit != 'true' }} + - name: Cache info + if: ${{ steps.sc_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + run: echo No cache found or cache will be ignored. IGNORE_CACHE=$IGNORE_CACHE + - name: if ignore cache, delete folders + if: ${{ inputs.IGNORE_CACHE == 1 }} + # The true at the end is to ignore errors that i.e. occur when the folders do not exist + run: rm -r $SC_BUILD || true + - name: make folders + run: mkdir -p $SC_DEBUG $SC_RELEASE + if: ${{ steps.sc_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + - name: install sc + run: echo "Install sc" + if: ${{ steps.sc_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + ## sc debug + - name: sc cmake debug + run: cd $SC_DEBUG && cmake ../../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$SC_DEBUG/install -Dmpi=$MPI -GNinja + if: ${{ steps.sc_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + - name: sc build debug + run: cd $SC_DEBUG && ninja $MAKEFLAGS && ninja $MAKEFLAGS install + if: ${{ steps.sc_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + ## sc release + - name: sc cmake release + run: cd $SC_RELEASE && cmake ../../ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$SC_RELEASE/install -Dmpi=$MPI -GNinja + if: ${{ steps.sc_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + - name: sc build release + run: cd $SC_RELEASE && ninja $MAKEFLAGS && ninja $MAKEFLAGS install + if: ${{ steps.sc_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} +# +# P4EST +# + - name: store p4est folders in var + run: echo P4EST_BUILD=$PWD/p4est/build >> $GITHUB_ENV + && echo P4EST_DEBUG=$PWD/p4est/build/Debug >> $GITHUB_ENV + && echo P4EST_RELEASE=$PWD/p4est/build/Release >> $GITHUB_ENV + - name: Get p4est commit hash + run: hash=`git rev-parse HEAD:p4est` && echo p4est_commit=$hash >> $GITHUB_ENV + - name: Check cache for previous p4est installation + id: p4est_cmake_cache + uses: actions/cache@v4 + with: + path: | + ${{ env.P4EST_DEBUG }} + ${{ env.P4EST_RELEASE }} + # You can increase the counter at the end to force a new key and hence recomputing the cache + key: p4est-cmake-MPI-${{ inputs.MPI }}-${{ env.p4est_commit }}-${{ env.sc_commit }}-${{ inputs.CACHE_COUNTER }} + - name: Log that no cache was found + run: echo USED_CACHE=0 >> $GITHUB_ENV + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' }} + - name: Cache info + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + run: echo No cache found or cache will be ignored. IGNORE_CACHE=$IGNORE_CACHE + - name: install p4est + run: echo "Install p4est" + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + - name: if ignore cache, delete folders + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + # The true at the end is to ignore errors that i.e. occur when the folders do not exist + run: rm -r $P4EST_BUILD || true + - name: make folders + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + run: mkdir -p $P4EST_DEBUG $P4EST_RELEASE + ## p4est debug + - name: p4est cmake debug + run: cd $P4EST_DEBUG && cmake ../../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$P4EST_DEBUG/install -DP4EST_USE_SYSTEM_SC=ON -DSC_DIR=$SC_DEBUG/install/cmake -DP4EST_ENABLE_MPI=$MPI -GNinja + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + - name: p4est build debug + run: cd $P4EST_DEBUG && ninja $MAKEFLAGS && ninja $MAKEFLAGS install + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + ## p4est release + - name: p4est cmake release + run: cd $P4EST_RELEASE && cmake ../../ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$P4EST_RELEASE/install -DP4EST_USE_SYSTEM_SC=ON -DSC_DIR=$SC_DEBUG/install/cmake -DP4EST_ENABLE_MPI=$MPI -GNinja + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + - name: p4est build release + run: cd $P4EST_RELEASE && ninja $MAKEFLAGS && ninja $MAKEFLAGS install + if: ${{ steps.p4est_cmake_cache.outputs.cache-hit != 'true' || inputs.IGNORE_CACHE == 1 }} + + ## output cache info + - name: output cache info + id: used_cache + run: echo "USED_CACHE=$USED_CACHE" >> $GITHUB_OUTPUT + + ## tar artifact to keep permissions: https://github.com/actions/upload-artifact?tab=readme-ov-file#permission-loss + - name: Tar files + run: tar -cvf artifact.tar . + + ## upload artifacts + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: SC_P4EST_MPI_${{ inputs.MPI }} + path: ./artifact.tar + retention-days: 1 diff --git a/.github/workflows/tests_cmake_sc_p4est.yml b/.github/workflows/tests_cmake_sc_p4est.yml new file mode 100644 index 0000000000..15efd0db5b --- /dev/null +++ b/.github/workflows/tests_cmake_sc_p4est.yml @@ -0,0 +1,121 @@ +name: CMake tests sc and p4est + + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2024 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# +# This github CI script installs t8code and runs its tests for various configurations. +# We compile sc and p4est as thirdparty libraries and use caching to only trigger a +# new installation of them when their versions have changed in t8code. +# +# Note: To manually enforce sc and p4est installation, either increase the counter +# in the "key:" entries of the sc and p4est steps or set the variables +# SC_IGNORE_CACHE and P4EST_IGNORE_CACHE to 1 in the respective steps. + +on: + workflow_call: + inputs: + MAKEFLAGS: + required: true + type: string + description: 'Make flags to use for compilation (like -j4)' + MPI: + required: true + type: string + description: 'Use MPI for compilation (ON/OFF)' + +jobs: + sc_p4est_cmake_tests: + runs-on: ubuntu-latest + container: dlramr/t8code-ubuntu:t8-dependencies + timeout-minutes: 30 + steps: +# +# Setup +# + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: SC_P4EST_MPI_${{ inputs.MPI }} + - name: untar artifact + run: tar -xf artifact.tar && rm artifact.tar + - name: Update packages + run: apt-get update && apt-get upgrade -y + # This seems to be necessary because of the docker container + - name: disable ownership checks + run: git config --global --add safe.directory '*' + - name: Get input vars + run: export MAKEFLAGS="${{ inputs.MAKEFLAGS }}" + && export MPI="${{ inputs.MPI }}" + && echo MPI="$MPI" >> $GITHUB_ENV + && echo MAKEFLAGS="$MAKEFLAGS" >> $GITHUB_ENV +# +# SC tests +# + ## save variables + - name: Save variables + run: export SC_DEBUG=$PWD/sc/build/Debug + && export SC_RELEASE=$PWD/sc/build/Release + && export P4EST_DEBUG=$PWD/p4est/build/Debug + && export P4EST_RELEASE=$PWD/p4est/build/Release + && echo SC_DEBUG="$SC_DEBUG" >> $GITHUB_ENV + && echo SC_RELEASE="$SC_RELEASE" >> $GITHUB_ENV + && echo P4EST_DEBUG="$P4EST_DEBUG" >> $GITHUB_ENV + && echo P4EST_RELEASE="$P4EST_RELEASE" >> $GITHUB_ENV + ## sc debug + - name: sc debug check + run: cd $SC_DEBUG && ninja test + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: sc_debug_MPI_${{ inputs.MPI }}.log + path: $SC_DEBUG/Testing/Temporary/LastTest.log + ## sc release + - name: sc release check + run: cd $SC_RELEASE && ninja test + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: sc_release_MPI_${{ inputs.MPI }}.log + path: $SC_RELEASE/Testing/Temporary/LastTest.log +# +# P4EST tests +# + ## p4est debug + - name: p4est debug check + run: cd $P4EST_DEBUG && ninja test + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: sp4est_debug_MPI_${{ inputs.MPI }}.log + path: $P4EST_DEBUG/Testing/Temporary/LastTest.log + ## p4est release + - name: p4est release check + run: cd $P4EST_RELEASE && ninja test + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: sp4est_release_MPI_${{ inputs.MPI }}.log + path: $P4EST_RELEASE/Testing/Temporary/LastTest.log diff --git a/.github/workflows/tests_cmake_t8code.yml b/.github/workflows/tests_cmake_t8code.yml new file mode 100644 index 0000000000..1effcaba77 --- /dev/null +++ b/.github/workflows/tests_cmake_t8code.yml @@ -0,0 +1,119 @@ +name: CMake tests t8code + + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2024 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +on: + workflow_call: + inputs: + MAKEFLAGS: + required: true + type: string + description: 'Make flags to use for compilation (like -j4)' + MPI: + required: true + type: string + description: 'Use MPI for compilation (ON/OFF)' + BUILD_TYPE: + required: true + type: string + description: 'Build type (Release/Debug)' + LESS_TESTS: + required: true + type: boolean + description: 'Enable less tests option for configuring' + +jobs: + t8code_cmake_tests: + timeout-minutes: 30 + runs-on: ubuntu-latest + container: dlramr/t8code-ubuntu:t8-dependencies + steps: +# +# Setup +# + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: SC_P4EST_MPI_${{ inputs.MPI }} + - name: untar artifact + run: tar -xf artifact.tar && rm artifact.tar + - name: Update packages + run: apt-get update && apt-get upgrade -y + # This seems to be necessary because of the docker container + - name: disable ownership checks + run: git config --global --add safe.directory '*' + - name: Get input vars + run: export MAKEFLAGS="${{ inputs.MAKEFLAGS }}" + && export MPI="${{ inputs.MPI }}" + && export BUILD_TYPE="${{ inputs.BUILD_TYPE }}" + && export SC_PATH=$PWD/sc/build/$BUILD_TYPE + && export P4EST_PATH=$PWD/p4est/build/$BUILD_TYPE + && echo MAKEFLAGS="$MAKEFLAGS" >> $GITHUB_ENV + && echo MPI="$MPI" >> $GITHUB_ENV + && echo BUILD_TYPE="$BUILD_TYPE" >> $GITHUB_ENV + && echo SC_PATH="$SC_PATH" >> $GITHUB_ENV + && echo P4EST_PATH="$P4EST_PATH" >> $GITHUB_ENV +# +# T8CODE +# + # build config vars + - name: less-test option + if: ${{ inputs.LESS_TESTS }} + run: export LESS_TEST_OPTION="-DT8CODE_ENABLE_LESS_TESTS=ON" + && echo LESS_TEST_OPTION="$LESS_TEST_OPTION" >> $GITHUB_ENV + - name: build config variables + run: export CONFIG_OPTIONS="${LESS_TEST_OPTION} -GNinja -DT8CODE_USE_SYSTEM_SC=ON -DT8CODE_USE_SYSTEM_P4EST=ON -DT8CODE_BUILD_PEDANTIC=ON -DT8CODE_ENABLE_MPI=$MPI -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSC_DIR=$SC_PATH/install/cmake -DP4EST_DIR=$P4EST_PATH/install/cmake" + && echo CONFIG_OPTIONS="$CONFIG_OPTIONS" >> $GITHUB_ENV + # cmake and test + - name: Printing MPI compiler info + run: mpicc --version && mpirun --version + - name: Printing GCC compiler info + run: gcc --version && g++ --version + - name: echo cmake line + run: echo cmake ../ $CONFIG_OPTIONS + - name: cmake + run: mkdir build && cd build && cmake ../ $CONFIG_OPTIONS + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: cmake_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}.log + path: build/CMakeFiles/CMakeOutput.log + - name: ninja + run: cd build && ninja $MAKEFLAGS + - name: ninja install + run: cd build && ninja install $MAKEFLAGS + - name: serial tests (if MPI is enabled) + run: cd build && ctest $MAKEFLAGS -R _serial + if: ${{ inputs.MPI == 'ON' }} + - name: parallel tests (if MPI is enabled) + run: cd build && ctest -R _parallel + if: ${{ inputs.MPI == 'ON' }} + - name: tests (if MPI is disabled) + run: cd build && ctest $MAKEFLAGS + if: ${{ inputs.MPI == 'OFF' }} + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-suite_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}.log + path: build/Testing/Temporary/LastTest.log diff --git a/.github/workflows/tests_cmake_t8code_api.yml b/.github/workflows/tests_cmake_t8code_api.yml new file mode 100644 index 0000000000..d96b5d0b33 --- /dev/null +++ b/.github/workflows/tests_cmake_t8code_api.yml @@ -0,0 +1,111 @@ +name: CMake tests t8code api + + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2024 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +on: + workflow_call: + inputs: + MAKEFLAGS: + required: true + type: string + description: 'Make flags to use for compilation (like -j4)' + MPI: + required: true + type: string + description: 'Use MPI for compilation (ON/OFF)' + BUILD_TYPE: + required: true + type: string + description: 'Build type (Release/Debug)' + LESS_TESTS: + required: true + type: boolean + description: 'Enable less tests option for configuring' + +jobs: + t8code_cmake_tests: + timeout-minutes: 30 + runs-on: ubuntu-latest + container: dlramr/t8code-ubuntu:t8-dependencies + steps: +# +# Setup +# + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: SC_P4EST_MPI_${{ inputs.MPI }} + - name: untar artifact + run: tar -xf artifact.tar && rm artifact.tar + - name: Update packages + run: apt-get update && apt-get upgrade -y + # This seems to be necessary because of the docker container + - name: disable ownership checks + run: git config --global --add safe.directory '*' + - name: Get input vars + run: export MAKEFLAGS="${{ inputs.MAKEFLAGS }}" + && export MPI="${{ inputs.MPI }}" + && export BUILD_TYPE="${{ inputs.BUILD_TYPE }}" + && export SC_PATH=$PWD/sc/build/$BUILD_TYPE + && export P4EST_PATH=$PWD/p4est/build/$BUILD_TYPE + && echo MAKEFLAGS="$MAKEFLAGS" >> $GITHUB_ENV + && echo MPI="$MPI" >> $GITHUB_ENV + && echo BUILD_TYPE="$BUILD_TYPE" >> $GITHUB_ENV + && echo SC_PATH="$SC_PATH" >> $GITHUB_ENV + && echo P4EST_PATH="$P4EST_PATH" >> $GITHUB_ENV +# +# T8CODE +# +# + # build config vars + - name: less-test option + if: ${{ inputs.LESS_TESTS }} + run: export LESS_TEST_OPTION="-DT8CODE_ENABLE_LESS_TESTS=ON" + && echo LESS_TEST_OPTION="$LESS_TEST_OPTION" >> $GITHUB_ENV + - name: build config variables + run: export CONFIG_OPTIONS="${LESS_TEST_OPTION} -GNinja -DT8CODE_USE_SYSTEM_SC=ON -DT8CODE_USE_SYSTEM_P4EST=ON -DT8CODE_BUILD_PEDANTIC=ON -DT8CODE_ENABLE_MPI=$MPI -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSC_DIR=$SC_PATH/install/cmake -DP4EST_DIR=$P4EST_PATH/install/cmake" + && echo CONFIG_OPTIONS="$CONFIG_OPTIONS" >> $GITHUB_ENV + # cmake and test with fortran + - name: check fortran + run: echo "Checking fortran" + - name: echo cmake line + run: echo cmake ../ $CONFIG_OPTIONS -DT8CODE_BUILD_FORTRAN_INTERFACE=ON + - name: cmake MPI fortran debug + run: mkdir build_fortran && cd build_fortran && cmake ../ $CONFIG_OPTIONS -DT8CODE_ENABLE_FORTRAN=ON + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: cmake_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}_fortran.log + path: build_fortran/CMakeFiles/CMakeOutput.log + - name: make + run: cd build_fortran && ninja $MAKEFLAGS + - name: ninja install + run: cd build_fortran && ninja install $MAKEFLAGS + - name: ninja test + run: cd build_fortran && ninja test + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-suite_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}_fortran.log + path: build_fortran/Testing/Temporary/LastTest.log diff --git a/.github/workflows/tests_cmake_t8code_linkage.yml b/.github/workflows/tests_cmake_t8code_linkage.yml new file mode 100644 index 0000000000..6e58ed8ffd --- /dev/null +++ b/.github/workflows/tests_cmake_t8code_linkage.yml @@ -0,0 +1,182 @@ +name: CMake tests t8code linkage + + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2024 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +on: + workflow_call: + inputs: + MAKEFLAGS: + required: true + type: string + description: 'Make flags to use for compilation (like -j4)' + MPI: + required: true + type: string + description: 'Use MPI for compilation (ON/OFF)' + BUILD_TYPE: + required: true + type: string + description: 'Build type (Release/Debug)' + LESS_TESTS: + required: true + type: boolean + description: 'Enable less tests option for configuring' + +jobs: + t8code_cmake_tests: + timeout-minutes: 60 + runs-on: ubuntu-latest + container: dlramr/t8code-ubuntu:t8-dependencies + steps: +# +# Setup +# + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: SC_P4EST_MPI_${{ inputs.MPI }} + - name: untar artifact + run: tar -xf artifact.tar && rm artifact.tar + - name: Update packages + run: apt-get update && apt-get upgrade -y + # This seems to be necessary because of the docker container + - name: disable ownership checks + run: git config --global --add safe.directory '*' + - name: Get input vars + run: export MAKEFLAGS="${{ inputs.MAKEFLAGS }}" + && export MPI="${{ inputs.MPI }}" + && export BUILD_TYPE="${{ inputs.BUILD_TYPE }}" + && export SC_PATH=$PWD/sc/build/$BUILD_TYPE + && export P4EST_PATH=$PWD/p4est/build/$BUILD_TYPE + && echo MAKEFLAGS="$MAKEFLAGS" >> $GITHUB_ENV + && echo MPI="$MPI" >> $GITHUB_ENV + && echo BUILD_TYPE="$BUILD_TYPE" >> $GITHUB_ENV + && echo SC_PATH="$SC_PATH" >> $GITHUB_ENV + && echo P4EST_PATH="$P4EST_PATH" >> $GITHUB_ENV +# +# T8CODE +# +# + # build config vars + - name: less-test option + if: ${{ inputs.LESS_TESTS }} + run: export LESS_TEST_OPTION="-DT8CODE_ENABLE_LESS_TESTS=ON" + && echo LESS_TEST_OPTION="$LESS_TEST_OPTION" >> $GITHUB_ENV + - name: build config variables + run: export CONFIG_OPTIONS="${LESS_TEST_OPTION} -GNinja -DT8CODE_USE_SYSTEM_SC=ON -DT8CODE_USE_SYSTEM_P4EST=ON -DT8CODE_BUILD_PEDANTIC=ON -DT8CODE_ENABLE_MPI=$MPI -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSC_DIR=$SC_PATH/install/cmake -DP4EST_DIR=$P4EST_PATH/install/cmake" + && echo CONFIG_OPTIONS="$CONFIG_OPTIONS" >> $GITHUB_ENV + # cmake and test with netcdf + - name: check NetCDF + run: echo "Checking NetCDF" + - name: echo cmake line + run: echo cmake ../ $CONFIG_OPTIONS -DT8CODE_ENABLE_NETCDF=ON + - name: cmake MPI NetCDF debug + run: mkdir build_netcdf && cd build_netcdf && cmake ../ $CONFIG_OPTIONS -DT8CODE_ENABLE_NETCDF=ON + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: cmake_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}_NetCDF.log + path: build_netcdf/CMakeFiles/CMakeOutput.log + - name: make + run: cd build_netcdf && ninja $MAKEFLAGS + - name: ninja install + run: cd build_netcdf && ninja install $MAKEFLAGS + - name: serial tests (if MPI is enabled) + run: cd build_netcdf && ctest $MAKEFLAGS -R _serial + if: ${{ inputs.MPI == 'ON' }} + - name: parallel tests (if MPI is enabled) + run: cd build_netcdf && ctest -R _parallel + if: ${{ inputs.MPI == 'ON' }} + - name: tests (if MPI is disabled) + run: cd build_netcdf && ctest $MAKEFLAGS + if: ${{ inputs.MPI == 'OFF' }} + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-suite_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}_NetCDF.log + path: build_netcdf/Testing/Temporary/LastTest.log +# cmake and test with OpenCASCADE + - name: check OpenCASCADE + run: echo "Checking OpenCASCADE" + - name: echo cmake line + run: echo cmake ../ $CONFIG_OPTIONS -DT8CODE_ENABLE_OCC=ON + - name: cmake OpenCASCADE + run: mkdir build_occ && cd build_occ && cmake ../ $CONFIG_OPTIONS -DT8CODE_ENABLE_OCC=ON + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: cmake_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}_OCC.log + path: build_occ/CMakeFiles/CMakeOutput.log + - name: make + run: cd build_occ && ninja $MAKEFLAGS + - name: ninja install + run: cd build_occ && ninja install $MAKEFLAGS + - name: serial tests (if MPI is enabled) + run: cd build_occ && ctest $MAKEFLAGS -R _serial + if: ${{ inputs.MPI == 'ON' }} + - name: parallel tests (if MPI is enabled) + run: cd build_occ && ctest -R _parallel + if: ${{ inputs.MPI == 'ON' }} + - name: tests (if MPI is disabled) + run: cd build_occ && ctest $MAKEFLAGS + if: ${{ inputs.MPI == 'OFF' }} + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-suite_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}_OCC.log + path: build_occ/Testing/Temporary/LastTest.log +# cmake and test with VTK + - name: check VTK + run: echo "Checking VTK" + - name: echo cmake line + run: echo cmake ../ $CONFIG_OPTIONS -DT8CODE_ENABLE_VTK=ON -DVTK_DIR=/usr/local/lib/cmake/vtk-9.1 + - name: cmake MPI VTK debug + run: mkdir build_vtk && cd build_vtk && cmake ../ $CONFIG_OPTIONS -DT8CODE_ENABLE_VTK=ON -DVTK_DIR=/usr/local/lib/cmake/vtk-9.1 + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: cmake_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}_VTK.log + path: build_vtk/CMakeFiles/CMakeOutput.log + - name: make + run: cd build_vtk && ninja $MAKEFLAGS + - name: ninja install + run: cd build_vtk && ninja install $MAKEFLAGS + - name: serial tests (if MPI is enabled) + run: cd build_vtk && ctest $MAKEFLAGS -R _serial + if: ${{ inputs.MPI == 'ON' }} + - name: parallel tests (if MPI is enabled) + run: cd build_vtk && ctest -R _parallel + if: ${{ inputs.MPI == 'ON' }} + - name: tests (if MPI is disabled) + run: cd build_vtk && ctest $MAKEFLAGS + if: ${{ inputs.MPI == 'OFF' }} + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-suite_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}_VTK.log + path: build_vtk/Testing/Temporary/LastTest.log diff --git a/.github/workflows/tests_cmake_t8code_w_shipped_submodules.yml b/.github/workflows/tests_cmake_t8code_w_shipped_submodules.yml new file mode 100644 index 0000000000..01f83aac5b --- /dev/null +++ b/.github/workflows/tests_cmake_t8code_w_shipped_submodules.yml @@ -0,0 +1,116 @@ +name: CMake tests t8code with shipped submodules + + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2024 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +on: + workflow_call: + inputs: + MAKEFLAGS: + required: true + type: string + description: 'Make flags to use for compilation (like -j4)' + MPI: + required: true + type: string + description: 'Use MPI for compilation (ON/OFF)' + BUILD_TYPE: + required: true + type: string + description: 'Build type (Release/Debug)' + LESS_TESTS: + required: true + type: boolean + description: 'Enable less tests option for configuring' + +jobs: + t8code_cmake_tests: + timeout-minutes: 30 + runs-on: ubuntu-latest + container: dlramr/t8code-ubuntu:t8-dependencies + steps: +# +# Setup +# + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Update packages + run: apt-get update && apt-get upgrade -y + # This seems to be necessary because of the docker container + - name: disable ownership checks + run: git config --global --add safe.directory '*' + - name: init submodules + run: git submodule init + - name: update submodules + run: git submodule update + - name: Get input vars + run: export MAKEFLAGS="${{ inputs.MAKEFLAGS }}" + && export MPI="${{ inputs.MPI }}" + && export BUILD_TYPE="${{ inputs.BUILD_TYPE }}" + && echo MAKEFLAGS="$MAKEFLAGS" >> $GITHUB_ENV + && echo MPI="$MPI" >> $GITHUB_ENV + && echo BUILD_TYPE="$BUILD_TYPE" >> $GITHUB_ENV +# +# T8CODE +# + # build config vars + - name: less-test option + if: ${{ inputs.LESS_TESTS }} + run: export LESS_TEST_OPTION="-DT8CODE_ENABLE_LESS_TESTS=ON" + && echo LESS_TEST_OPTION="$LESS_TEST_OPTION" >> $GITHUB_ENV + - name: build config variables + run: export CONFIG_OPTIONS="${LESS_TEST_OPTION} -GNinja -DT8CODE_BUILD_PEDANTIC=ON -DT8CODE_ENABLE_MPI=$MPI -DCMAKE_BUILD_TYPE=$BUILD_TYPE" + && echo CONFIG_OPTIONS="$CONFIG_OPTIONS" >> $GITHUB_ENV + # cmake and test + - name: Printing MPI compiler info + run: mpicc --version && mpirun --version + - name: Printing GCC compiler info + run: gcc --version && g++ --version + - name: echo cmake line + run: echo cmake ../ $CONFIG_OPTIONS + - name: cmake + run: mkdir build && cd build && cmake ../ $CONFIG_OPTIONS + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: cmake_w_submodules_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}.log + path: build/CMakeFiles/CMakeOutput.log + - name: ninja + run: cd build && ninja $MAKEFLAGS + - name: ninja install + run: cd build && ninja install $MAKEFLAGS + - name: serial tests (if MPI is enabled) + run: cd build && ctest $MAKEFLAGS -R _serial + if: ${{ inputs.MPI == 'ON' }} + - name: parallel tests (if MPI is enabled) + run: cd build && ctest -R _parallel + if: ${{ inputs.MPI == 'ON' }} + - name: tests (if MPI is disabled) + run: cd build && ctest $MAKEFLAGS + if: ${{ inputs.MPI == 'OFF' }} + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-suite_w_submodules_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}.log + path: build/Testing/Temporary/LastTest.log diff --git a/.github/workflows/tests_cmake_testsuite.yml b/.github/workflows/tests_cmake_testsuite.yml new file mode 100644 index 0000000000..ac20231bc5 --- /dev/null +++ b/.github/workflows/tests_cmake_testsuite.yml @@ -0,0 +1,143 @@ +name: t8code CMake testsuite + + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2024 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# +# This github CI script installs t8code and runs its tests for various configurations. +# We compile sc and p4est as thirdparty libraries and use caching to only trigger a +# new installation of them when their versions have changed in t8code. +# +# Note: To manually enforce sc and p4est installation, either increase the counter +# in the "CACHE_COUNTER:" entries of the sc and p4est steps or set the variables +# IGNORE_CACHE to true in the respective steps. + +on: + push: + branches: + - main + - develop + - feature-*CI* # for testing this script, all feature branches with "CI" in their name + pull_request: + branches: + - main + - develop + workflow_dispatch: # Be able to trigger this manually on github.com + # Run every night at 1:10 + schedule: + - cron: '10 1 * * *' + +jobs: + # Preparation step for tests. Repo is cloned and sc + p4est are compiled with and without MPI. + preparation: + if: (github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') || (github.event_name != 'schedule') + uses: ./.github/workflows/tests_cmake_preparation.yml + strategy: + fail-fast: false + matrix: + MPI: [OFF, ON] + include: + - MAKEFLAGS: -j4 + with: + MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + IGNORE_CACHE: false # Use this to force a new installation of sc and p4est for this specific workflow run + CACHE_COUNTER: 0 # Increase this number to force a new installation of sc and p4est and to update the cache once + MPI: ${{ matrix.MPI }} + + # Run parallel tests for sc and p4est with and without MPI + sc_p4est_tests: + if: ((github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') || (github.event_name != 'schedule')) + needs: preparation + uses: ./.github/workflows/tests_cmake_sc_p4est.yml + strategy: + fail-fast: false + matrix: + MPI: [OFF, ON] + include: + - MAKEFLAGS: -j4 + with: + MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + MPI: ${{ matrix.MPI }} + + # Run t8code tests with and without MPI and in serial and debug mode + t8code_tests: + if: (github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') || (github.event_name != 'schedule') + uses: ./.github/workflows/tests_cmake_t8code.yml + strategy: + fail-fast: false + matrix: + MPI: [OFF, ON] + BUILD_TYPE: [Debug, Release] + include: + - MAKEFLAGS: -j4 + needs: preparation + with: + MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + MPI: ${{ matrix.MPI }} + BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + LESS_TESTS: ${{ github.event_name == 'pull_request' }} + + + # Run t8code linkage tests with and without MPI and in serial and debug mode + t8code_linkage_tests: + if: (github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') || (github.event_name != 'schedule') + uses: ./.github/workflows/tests_cmake_t8code_linkage.yml + strategy: + fail-fast: false + matrix: + MPI: [OFF, ON] + BUILD_TYPE: [Debug, Release] + include: + - MAKEFLAGS: -j4 + needs: preparation + with: + MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + MPI: ${{ matrix.MPI }} + BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + LESS_TESTS: ${{ github.event_name == 'pull_request' }} + + # Run t8code linkage tests with and without MPI and in serial and debug mode + t8code_api_tests: + if: (github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') || (github.event_name != 'schedule') + uses: ./.github/workflows/tests_cmake_t8code_api.yml + strategy: + fail-fast: false + matrix: + MPI: [ON] # For now the fortran API only supports building with MPI + BUILD_TYPE: [Debug, Release] + include: + - MAKEFLAGS: -j4 + needs: preparation + with: + MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + MPI: ${{ matrix.MPI }} + BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + LESS_TESTS: ${{ github.event_name == 'pull_request' }} + + # Run t8code tests with shipped submodules. This test is only for the build system, so only one config is tested. + t8code_w_shipped_submodules_tests: + if: (github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') || (github.event_name != 'schedule') + uses: ./.github/workflows/tests_cmake_t8code_w_shipped_submodules.yml + with: + MAKEFLAGS: -j4 + MPI: ON + BUILD_TYPE: Debug + LESS_TESTS: ${{ github.event_name == 'pull_request' }} diff --git a/.gitignore b/.gitignore index 03984a386e..da972a4f2d 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,9 @@ config.status Doxyfile doxygen/ +CMakeCache.txt +CMakeFiles/ + src/stamp-h1 src/t8_config.h src/pre_config.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c9727328e4..d04c785c09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,16 +4,18 @@ include(cmake/GitProjectVersion.cmake) project( T8CODE DESCRIPTION "Parallel algorithms and data structures for tree-based AMR with arbitrary element shapes." - LANGUAGES C CXX + LANGUAGES C CXX Fortran VERSION "${T8CODE_VERSION_MAJOR}.${T8CODE_VERSION_MINOR}.${T8CODE_VERSION_PATCH}" ) include( CTest ) option( T8CODE_BUILD_AS_SHARED_LIBRARY "Whether t8code should be built as a shared or a static library" ON ) option( T8CODE_BUILD_PEDANTIC "Compile t8code with `-Wall -pedantic -Werror` as done in the Github CI." OFF ) +option( T8CODE_EXPORT_COMPILE_COMMANDS "Export the compile commands as json. Can be used by IDEs for code completion (e.g. intellisense, clangd)" OFF ) option( T8CODE_BUILD_TESTS "Build t8code's automated tests" ON ) option( T8CODE_BUILD_TUTORIALS "Build t8code's tutorials" ON ) option( T8CODE_BUILD_EXAMPLES "Build t8code's examples" ON ) option( T8CODE_BUILD_BENCHMARKS "Build t8code's benchmarks" ON ) +option( T8CODE_BUILD_FORTRAN_INTERFACE "Build t8code's Fortran interface" OFF ) option( T8CODE_ENABLE_LESS_TESTS "Tests not as thoroughly to speed up the test suite. Tests the same functionality. (WARNING: Use with care.)" OFF ) option( T8CODE_ENABLE_MPI "Enable t8code's features which rely on MPI" ON ) @@ -29,13 +31,20 @@ option( T8CODE_BUILD_DOCUMENTATION "Build t8code's documentation" OFF ) include(CMakeDependentOption) cmake_dependent_option( T8CODE_BUILD_DOCUMENTATION_SPHINX "Build t8code's documentation using sphinx" OFF "T8CODE_BUILD_DOCUMENTATION" OFF ) -set(T8CODE_CUSTOM_TEST_COMMAND "" CACHE STRING "Define custom test command, e.g.: mpirun -n 4") +set(T8CODE_CUSTOM_PARALLEL_TEST_COMMAND "" CACHE STRING "Define a custom command for parallel tests , e.g.: mpirun -np 8 (overwrites standard mpirun -np 4 if build with mpi)") +set(T8CODE_CUSTOM_SERIAL_TEST_COMMAND "" CACHE STRING "Define a custom command for serial tests.") -if( NOT CMAKE_BUILD_TYPE ) - set( CMAKE_BUILD_TYPE "Release" ) -endif() +# Set a default build type if none was specified +set(default_build_type "Release") -set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Release RelWithDebInfo Debug) +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${default_build_type}' as none was specified.") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE + STRING "Choose the type of build. Build types available: Release Debug RelWithDebInfo" FORCE) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Release" "RelWithDebInfo") +endif() set( CMAKE_C_STANDARD 11 ) set( CMAKE_C_STANDARD_REQUIRED ON ) @@ -48,7 +57,12 @@ set( CMAKE_CXX_EXTENSIONS OFF ) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) if( T8CODE_ENABLE_MPI ) - find_package( MPI COMPONENTS C REQUIRED ) + if( T8CODE_BUILD_FORTRAN_INTERFACE ) + find_package( MPI COMPONENTS C Fortran REQUIRED ) + else() + find_package( MPI COMPONENTS C REQUIRED ) + endif() + if( NOT MPIEXEC_EXECUTABLE ) message( FATAL_ERROR "MPIEXEC was not found" ) endif() @@ -57,7 +71,10 @@ if( T8CODE_ENABLE_MPI ) endif() if( T8CODE_ENABLE_VTK ) - find_package( VTK REQUIRED ) + find_package( VTK REQUIRED COMPONENTS + IOXML CommonExecutionModel CommonDataModel + IOGeometry IOXMLParser IOParallelXML IOPLY + ParallelMPI FiltersCore vtksys CommonCore zlib IOLegacy) if(VTK_FOUND) message("Found VTK") endif (VTK_FOUND) @@ -81,7 +98,6 @@ if( T8CODE_ENABLE_NETCDF ) endif (netCDF_FOUND) endif( T8CODE_ENABLE_NETCDF ) - # Override default for this libsc option set( BUILD_SHARED_LIBS ON CACHE BOOL "Build libsc as a shared library" ) @@ -126,3 +142,14 @@ endif() if ( T8CODE_BUILD_DOCUMENTATION ) add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/doc ) endif() + +if( T8CODE_BUILD_FORTRAN_INTERFACE ) + enable_language( Fortran ) + add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/api/t8_fortran_interface ) + + if( NOT T8CODE_ENABLE_MPI ) + message( FATAL_ERROR "Fortran API only available when MPI is enabled." ) + endif() +endif() + +include (cmake/CPackConfig.cmake) diff --git a/Makefile.am b/Makefile.am index f0872791e7..e4c53198bb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,7 @@ dist_t8aclocal_DATA = config/t8_include.m4 \ config/t8_netcdf.m4 \ config/t8_vtk.m4 \ config/t8_occ.m4 \ + config/t8_fortran.m4 \ config/t8_mpi.m4 diff --git a/README.md b/README.md index 3e5b00e21e..b71e4ba413 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ We provide a short guide to install t8code in our Wiki [Installation guide](http ### Getting started To get familiar with t8code and its algorithms and data structures we recommend executing the tutorial examples in `tutorials` - and read the corresponding Wiki pages starting with [Step 0 - Helloworld](https://github.com/holke/t8code/wiki/Step-0---Hello-World). + and read the corresponding Wiki pages starting with [Step 0 - Helloworld](https://github.com/DLR-AMR/t8code/wiki/Step-0---Hello-World). A sophisticated example of a complete numerical simulation is our finite volume solver of the advection equation in `example/advection`. diff --git a/api/Makefile.am b/api/Makefile.am index 974f210370..b27d462ba9 100644 --- a/api/Makefile.am +++ b/api/Makefile.am @@ -10,8 +10,24 @@ libt8_installed_headers_fortran_interface = \ dist_fortraninterfaceinclude_HEADERS = $(libt8_installed_headers_fortran_interface) +# Save the module sources in a different variable for later use +t8_fortran_module_sources = api/t8_fortran_interface/t8_fortran_interface_mod.f90 + +# Add the Fortran sources to the lib +libt8_compiled_sources += $(t8_fortran_module_sources) + +AM_FCFLAGS = libt8_compiled_sources += \ api/t8_fortran_interface/t8_fortran_interface.c -AM_CPPFLAGS += -I@top_srcdir@/api +AM_CPPFLAGS += -I@top_srcdir@/api/t8_fortran_interface +MODSOURCES = $(t8_fortran_module_sources) + +src_libt8_la_FCFLAGS = $(AM_FCFLAGS) +src_libt8_la_FFLAGS = $(FFLAGS) + +# Include the Fortran specific variables and rules +include api/t8_fortran_interface/t8_fortran_specific.mk + +# T8_ENABLE_FORTRAN endif diff --git a/api/t8_fortran_interface/CMakeLists.txt b/api/t8_fortran_interface/CMakeLists.txt new file mode 100644 index 0000000000..3072277cd3 --- /dev/null +++ b/api/t8_fortran_interface/CMakeLists.txt @@ -0,0 +1,18 @@ +# Link in C-Fortran interface file into libt8. +target_sources( T8 PRIVATE t8_fortran_interface.c ) +target_sources( T8 PRIVATE t8_fortran_interface_mod.f90 ) + +# Add this directory to header search path. +target_include_directories( T8 PRIVATE ${CMAKE_CURRENT_LIST_DIR} ) + +# Install header files. +install( + FILES ${CMAKE_CURRENT_LIST_DIR}/t8_fortran_interface.h + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/t8_fortran_interface +) + +# Install module files. +install( + FILES ${CMAKE_BINARY_DIR}/src/t8_fortran_interface_mod.mod + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/t8_fortran_interface +) diff --git a/api/t8_fortran_interface/t8_fortran_interface.c b/api/t8_fortran_interface/t8_fortran_interface.c index 92d0ab5a8e..487ca829fe 100644 --- a/api/t8_fortran_interface/t8_fortran_interface.c +++ b/api/t8_fortran_interface/t8_fortran_interface.c @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include +#include #include #include #include diff --git a/api/t8_fortran_interface/t8_fortran_interface.h b/api/t8_fortran_interface/t8_fortran_interface.h index 3424a34d61..195205f280 100644 --- a/api/t8_fortran_interface/t8_fortran_interface.h +++ b/api/t8_fortran_interface/t8_fortran_interface.h @@ -35,6 +35,7 @@ #include #include #include +#include typedef int (*t8_fortran_adapt_coordinate_callback) (double x, double y, double z, int is_family); diff --git a/api/t8_fortran_interface/t8_fortran_interface_mod.f90 b/api/t8_fortran_interface/t8_fortran_interface_mod.f90 new file mode 100644 index 0000000000..5001bc70cf --- /dev/null +++ b/api/t8_fortran_interface/t8_fortran_interface_mod.f90 @@ -0,0 +1,327 @@ +!! This file is part of t8code. +!! t8code is a C library to manage a collection (a forest) of multiple +!! connected adaptive space-trees of general element classes in parallel. +!! +!! Copyright (C) 2024 the developers +!! +!! t8code is free software; you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation; either version 2 of the License, or +!! (at your option) any later version. +!! +!! t8code is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with t8code; if not, write to the Free Software Foundation, Inc., +!! 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +module t8_fortran_interface_mod + + use, intrinsic :: ISO_C_BINDING + + + !!! Interface for t8_fortran_MPI_Comm_new + !!! Given a fortran MPI Communicator, converts it into C and + !!! returns a pointer to the C MPI communicator. + !!! This function allocates memory that needs to be freed with + !!! t8_fortran_mpi_comm_delete_f + !!! + !!! Code modified from: https://stackoverflow.com/questions/42530620/how-to-pass-mpi-communicator-handle-from-fortran-to-c-using-iso-c-binding + INTERFACE + type (C_PTR) FUNCTION t8_fortran_mpi_comm_new_f (FCOMM) & + BIND(C, NAME='t8_fortran_MPI_Comm_new') + use, intrinsic :: ISO_C_BINDING, only: c_int, c_ptr + IMPLICIT NONE + INTEGER (C_INT), VALUE :: Fcomm + END FUNCTION t8_fortran_mpi_comm_new_f + END INTERFACE + + !!! Free memory of a C MPI communicator pointer that was + !!! allocated using t8_fortran_mpi_comm_new_f + INTERFACE + subroutine t8_fortran_mpi_comm_delete_f (Ccomm) & + BIND(C, NAME='t8_fortran_MPI_Comm_delete') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr), value :: Ccomm + END subroutine t8_fortran_mpi_comm_delete_f + END INTERFACE + + !!! Initialize sc and t8code with a given C MPI Communicator + Interface + subroutine t8_fortran_init_all_f (Ccomm) & + BIND(C, NAME='t8_fortran_init_all') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr), value :: Ccomm + END subroutine t8_fortran_init_all_f + end Interface + + !!! Initialize sc and t8code with a given C MPI Communicator + Interface + subroutine t8_fortran_init_all_noMPI_f () & + BIND(C, NAME='t8_fortran_init_all_noMPI') + END subroutine t8_fortran_init_all_noMPI_f + end Interface + + Interface + type (c_ptr) function t8_cmesh_new_periodic_tri_f (Ccomm) & + bind (c, name = 't8_cmesh_new_periodic_tri_wrap') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr), value :: Ccomm + end function t8_cmesh_new_periodic_tri_f + end Interface + + Interface + integer (c_int) function t8_cmesh_vtk_write_file_f (cmesh, fileprefix, scale) & + bind (c, name = 't8_cmesh_vtk_write_file') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int, c_char, c_double + IMPLICIT NONE + type (c_ptr), value :: cmesh + character (c_char) :: fileprefix + real (c_double), value :: scale + end function t8_cmesh_vtk_write_file_f + end Interface + + Interface + subroutine t8_cmesh_destroy_f (cmesh) & + bind (c, name = 't8_cmesh_destroy') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr) :: cmesh + end subroutine t8_cmesh_destroy_f + end Interface + + Interface + subroutine t8_fortran_cmesh_init_f (cmesh) & + bind (c, name = 't8_cmesh_init') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr) :: cmesh + end subroutine t8_fortran_cmesh_init_f + end Interface + + Interface + type (c_ptr) function t8_fortran_geometry_linear_new_f (dimension) & + bind (c, name = 't8_geometry_linear_new') + use, intrinsic :: ISO_C_BINDING, only: c_int, c_ptr + IMPLICIT NONE + integer (c_int), value :: dimension + end function t8_fortran_geometry_linear_new_f + end Interface + + Interface + subroutine t8_fortran_cmesh_register_geometry_f (cmesh, geometry) & + bind (c, name = 't8_cmesh_register_geometry') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr), value :: cmesh + type (c_ptr), value :: geometry + end subroutine t8_fortran_cmesh_register_geometry_f + end Interface + + Interface + subroutine t8_fortran_cmesh_set_tree_class_f (cmesh, gtree_id, tree_class) & + bind (c, name = 't8_cmesh_set_tree_class') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int64_t, c_int + IMPLICIT NONE + type (c_ptr), value :: cmesh + integer (c_int64_t), value :: gtree_id + integer (c_int), value :: tree_class + end subroutine t8_fortran_cmesh_set_tree_class_f + end Interface + + Interface + subroutine t8_fortran_cmesh_set_tree_vertices_f (cmesh, ltree_id, vertices, num_vertices) & + bind (c, name = 't8_cmesh_set_tree_vertices') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int, c_int64_t + IMPLICIT NONE + type (c_ptr), value :: cmesh + integer (c_int64_t), value :: ltree_id + type(c_ptr),value :: vertices + integer (c_int), value :: num_vertices + end subroutine t8_fortran_cmesh_set_tree_vertices_f + end Interface + + Interface + subroutine t8_fortran_cmesh_set_join_f (cmesh, gtree1, gtree2, face1, face2, orientation) & + bind (c, name = 't8_cmesh_set_join') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int, c_int64_t + IMPLICIT NONE + type (c_ptr), value :: cmesh + integer (c_int64_t), value :: gtree1 + integer (c_int64_t), value :: gtree2 + integer (c_int), value :: face1 + integer (c_int), value :: face2 + integer (c_int), value :: orientation + end subroutine t8_fortran_cmesh_set_join_f + end Interface + + Interface + subroutine t8_fortran_cmesh_set_join_by_vertices_noConn_f (cmesh, ntrees, eclasses, vertices, do_both_directions) & + bind (c, name = 't8_fortran_cmesh_set_join_by_vertices_noConn') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: cmesh + integer (c_int), value :: ntrees + type (c_ptr), value :: eclasses + type (c_ptr), value :: vertices + integer (c_int), value :: do_both_directions + end subroutine t8_fortran_cmesh_set_join_by_vertices_noConn_f + end Interface + + Interface + subroutine t8_fortran_cmesh_commit_f (cmesh, Ccom) & + bind (c, name = 't8_fortran_cmesh_commit') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr), value :: cmesh + type (c_ptr), value :: Ccom + end subroutine t8_fortran_cmesh_commit_f + end Interface + + Interface + type (c_ptr) function t8_forest_new_uniform_default_f (cmesh, level, do_face_ghost, Ccomm) & + bind (c, name = 't8_forest_new_uniform_default') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: cmesh + integer (c_int), value :: level + integer (c_int), value :: do_face_ghost + type (c_ptr), value :: Ccomm + end function t8_forest_new_uniform_default_f + end Interface + + + Interface + subroutine t8_forest_unref_f (forest) & + bind (c, name = 't8_forest_unref') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr) :: forest + end subroutine t8_forest_unref_f + end Interface + + + Interface + integer (c_int) function t8_forest_write_vtk_f (forest, fileprefix) & + bind (c, name = 't8_forest_write_vtk') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int, c_char, c_double + IMPLICIT NONE + type (c_ptr), value :: forest + character (c_char) :: fileprefix + end function t8_forest_write_vtk_f + end Interface + + Interface + subroutine t8_forest_iterate_replace_f (forest_new, forest_old, replace_fn) & + bind (c, name = 't8_forest_iterate_replace') + use, intrinsic :: ISO_C_BINDING, only: c_ptr + IMPLICIT NONE + type (c_ptr), value :: forest_new + type (c_ptr), value :: forest_old + type (c_ptr), value :: replace_fn + end subroutine t8_forest_iterate_replace_f + end Interface + + Interface + integer (c_int) function t8_forest_get_local_num_elements (forest) & + bind (c, name = 't8_forest_get_local_num_elements') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: forest + end function t8_forest_get_local_num_elements + end Interface + + Interface + integer (c_int) function t8_forest_get_global_num_elements (forest) & + bind (c, name = 't8_forest_get_global_num_elements') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: forest + end function t8_forest_get_global_num_elements + end Interface + + Interface + integer (c_int) function t8_forest_get_num_local_trees (forest) & + bind (c, name = 't8_forest_get_num_local_trees') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: forest + end function t8_forest_get_num_local_trees + end Interface + + Interface + integer (c_int) function t8_forest_get_tree_num_elements (forest, ltreeid) & + bind (c, name = 't8_forest_get_tree_num_elements') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: forest + integer (c_int), value :: ltreeid + end function t8_forest_get_tree_num_elements + end Interface + + Interface + type (c_ptr) function t8_forest_get_element_in_tree (forest, ltreeid, leid_in_tree) & + bind (c, name = 't8_forest_get_element_in_tree') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: forest + integer (c_int), value :: ltreeid, leid_in_tree + end function t8_forest_get_element_in_tree + end Interface + + Interface + subroutine t8_forest_element_from_ref_coords (forest, ltreeid, element, ref_coords, num_coords, coords_out) & + bind (c, name = 't8_forest_element_from_ref_coords') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int, c_double + IMPLICIT NONE + type (c_ptr), value :: forest, element + integer (c_int), value :: ltreeid, num_coords + real (c_double), dimension(3) :: ref_coords, coords_out + end subroutine t8_forest_element_from_ref_coords + end Interface + + Interface + subroutine t8_global_productionf_noargs_f (string) & + bind (c, name = 't8_global_productionf_noargs') + use, intrinsic :: ISO_C_BINDING, only: c_char + IMPLICIT NONE + character (c_char) :: string + end subroutine t8_global_productionf_noargs_f + end Interface + + Interface + subroutine t8_fortran_finalize_f () & + bind (c, name = 't8_fortran_finalize') + IMPLICIT NONE + end subroutine t8_fortran_finalize_f + end Interface + + Interface + type (c_ptr) function t8_fortran_adapt_by_coordinates_f (forest, recursive, callback) & + bind (c, name = 't8_fortran_adapt_by_coordinates') + use, intrinsic :: ISO_C_BINDING, only : c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: forest + integer (c_int), value :: recursive + type (c_ptr), value :: callback + end function t8_fortran_adapt_by_coordinates_f + end Interface + + Interface + subroutine t8_fortran_element_volume_f (forest, ltreeid, element) & + bind (c, name = 't8_forest_element_volume') + use, intrinsic :: ISO_C_BINDING, only: c_ptr, c_int + IMPLICIT NONE + type (c_ptr), value :: forest + integer (c_int), value :: ltreeid + type (c_ptr), value :: element + end subroutine t8_fortran_element_volume_f + end Interface + +End module t8_fortran_interface_mod diff --git a/api/t8_fortran_interface/t8_fortran_specific.mk b/api/t8_fortran_interface/t8_fortran_specific.mk new file mode 100644 index 0000000000..3bde84337f --- /dev/null +++ b/api/t8_fortran_interface/t8_fortran_specific.mk @@ -0,0 +1,47 @@ +if T8_ENABLE_FORTRAN +# Clean up modules files in the root directory (if no module directory has been specified) +CLEANFILES += *.$(FC_MODEXT) + +# Get the supplied FCFLAGS +AM_FCFLAGS += @FCFLAGS@ + +# Define a variable holding the module directory (for a rule below) +t8_current_moddir = + +if T8_WITH_MODDIR +# Updates for the module output and include path (if a separate module directory has been specified) +AM_FCFLAGS += $(FC_MODOUT)@T8_FORTRAN_MODULE_DIR@ $(FC_MODINC)@T8_FORTRAN_MODULE_DIR@ +AM_CPPFLAGS += -I@T8_FORTRAN_MODULE_DIR@ + +# Clean the module files in this directory +CLEANFILES += @T8_FORTRAN_MODULE_DIR@/*.$(FC_MODEXT) + +# Add the creation of the module directory as an order only prerequisite to the Fortran module files +$(MODSOURCES): %.f90 : | create-moddir + +# Rule to create the module directory +create-moddir: + @$(MKDIR_P) @T8_FORTRAN_MODULE_DIR@ + +# Save the module directory +t8_current_moddir += @T8_FORTRAN_MODULE_DIR@/ + +# End if T8_WITH_MODDIR +endif + +# If the install target is made, we will copy the module files into the include directory (after the installation of the header files) +install-data-hook: + @cp -fp $(t8_current_moddir)*.$(FC_MODEXT) $(includedir)/t8_fortran_interface + +# Define dependencies of the Fortran modules (in case they depend on other modules) +# This needs to be done in order to ensure the correct build process in any case + +# Define dependencies for all Fortran programs of the Fortran modules +# This needs to be done in order to ensure the correct build process in any case +# ... + +# TODO: Implement t8_fortran_test depends on the modules: t8_fortran_interface +#example/Fortran/t8_fortran_test.o : api/t8_fortran_interface/t8_fortran_interface.o + +# end if T8_ENABLE_FORTRAN +endif diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index 462d0c3184..8d39c49d5a 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -4,10 +4,27 @@ function( add_t8_benchmark ) set( multiValueArgs "SOURCES" ) cmake_parse_arguments( ADD_T8_BENCHMARK "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + # Get the path of the first file listed in the SOURCES list and use it to determine the build directory. + # The executable will be build in the same directory as the first source file. + list(GET ADD_T8_BENCHMARK_SOURCES 0 FIRST_SOURCE) + get_filename_component(BENCHMARK_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/${FIRST_SOURCE}" DIRECTORY) + file(RELATIVE_PATH BENCHMARK_RELATIVE_DIR "${CMAKE_SOURCE_DIR}" "${BENCHMARK_SOURCE_DIR}") + set(BENCHMARK_BUILD_DIR "${CMAKE_BINARY_DIR}/${BENCHMARK_RELATIVE_DIR}") + add_executable( ${ADD_T8_BENCHMARK_NAME} ${ADD_T8_BENCHMARK_SOURCES} ) target_include_directories( ${ADD_T8_BENCHMARK_NAME} PRIVATE ${PROJECT_SOURCE_DIR} ) target_link_libraries( ${ADD_T8_BENCHMARK_NAME} PRIVATE T8 SC::SC ) + set_target_properties(${ADD_T8_BENCHMARK_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_BUILD_DIR}" + LIBRARY_OUTPUT_DIRECTORY "${BENCHMARK_BUILD_DIR}" + ARCHIVE_OUTPUT_DIRECTORY "${BENCHMARK_BUILD_DIR}" + ) + + if( T8CODE_EXPORT_COMPILE_COMMANDS ) + set_target_properties( ${ADD_T8_BENCHMARK_NAME} PROPERTIES EXPORT_COMPILE_COMMANDS ON ) + endif( T8CODE_EXPORT_COMPILE_COMMANDS ) + install( TARGETS ${ADD_T8_BENCHMARK_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin ) endfunction() diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake new file mode 100644 index 0000000000..0d87a38539 --- /dev/null +++ b/cmake/CPackConfig.cmake @@ -0,0 +1,51 @@ +set(CPACK_PACKAGE_VENDOR "DLR-SC AMR") +set(CPACK_PACKAGE_NAME "T8CODE") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Parallel algorithms and data structures for tree-based AMR with arbitrary element shapes.") +set(CPACK_PACKAGE_VERSION_MAJOR ${T8CODE_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${T8CODE_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${T8CODE_VERSION_PATCH}) +set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") +set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/package) +set(CPACK_PACKAGE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/t8code_logo.png) + +# Define a variable for the version file +set(VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/version.txt") + + +# Custom command to generate the version file +add_custom_command( + OUTPUT ${VERSION_FILE} + COMMAND ${CMAKE_COMMAND} -E echo "Version ${T8CODE_VERSION_MAJOR}.${T8CODE_VERSION_MINOR}.${T8CODE_VERSION_PATCH}" > ${VERSION_FILE} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt # Change as needed + ) + +# Create a custom target to ensure the version file is generated +add_custom_target(GenerateVersionFile ALL DEPENDS ${VERSION_FILE}) + +set(CPACK_SOURCE_GENERATOR "TGZ;ZIP") +set(CPACK_SOURCE_INCLUDE_FILES ${VERSION_FILE}) +set(CPACK_SOURCE_IGNORE_FILES .git/ .github/ .vscode/ _CPack_Packages/ +.gitmodules .gitignore +${PROJECT_BINARY_DIR}/ +Makefile.in +aclocal.m4 +autom4te.cache/ +build/ +bin/ +configure +DartConfiguration.tcl +CMakeCache.txt +build/ +build-aux/ +configure +config.log +compile_commands.json +) + +set(CPACK_PACKAGE_NAME "T8CODE") +set(CPACK_VERBATIM_VARIABLES TRUE) + + +include(CPack) + diff --git a/cmake/FindOpenCASCADE.cmake b/cmake/FindOpenCASCADE.cmake index 0e21bc0b7e..6eb5c10c22 100644 --- a/cmake/FindOpenCASCADE.cmake +++ b/cmake/FindOpenCASCADE.cmake @@ -1,4 +1,4 @@ -# taken and adapted from the heekscad project: https://github.com/Heeks +# Taken and adapted from the heekscad project: https://github.com/Heeks # HeeksCAD is covered by the new BSD license @@ -34,25 +34,25 @@ IF( NOT OpenCASCADE_FOUND ) ENDIF( CMAKE_SIZEOF_VOID_P EQUAL 4 ) IF(UNIX) - set( _incsearchpath /usr/include/opencascade /usr/include/ /opt/occ/inc ${CASROOT}/inc ${CASROOT}/include/) - set( _libsearchpath /usr/lib64 /usr/lib /opt/occ/lib ${CASROOT}/lib64 ${CASROOT}/lib ) + set( _incsearchpath /usr/include/opencascade;/usr/include/;/opt/occ/inc;${CASROOT}/inc;${CASROOT}/include/ ) + set( _libsearchpath /usr/lib64;/usr/lib;/opt/occ/lib;${CASROOT}/lib64;${CASROOT}/lib ) ELSE(UNIX) IF (WIN32) - set( _incsearchpath ${CASROOT}\\inc ${CASROOT}\\include) + set( _incsearchpath ${CASROOT}\\inc;${CASROOT}\\include) set( _testdllname TKernel.dll ) - set( _libsearchpath ${CASROOT}\\win32\\lib ${CASROOT}\\win${BITS}\\lib ${CASROOT}\\win${BITS}\\vc9\\lib ${CASROOT}\\win${BITS}\\vc10\\lib ${CASROOT}\\win${BITS}\\vc14\\lib) - set( _dllsearchpath ${CASROOT}\\win32\\bin ${CASROOT}\\win${BITS}\\bin ${CASROOT}\\win${BITS}\\vc9\\bin ${CASROOT}\\win${BITS}\\vc10\\bin ${CASROOT}\\win${BITS}\\vc14\\bin) + set( _libsearchpath ${CASROOT}\\win32\\lib;${CASROOT}\\win${BITS}\\lib;${CASROOT}\\win${BITS}\\vc9\\lib;${CASROOT}\\win${BITS}\\vc10\\lib;${CASROOT}\\win${BITS}\\vc14\\lib) + set( _dllsearchpath ${CASROOT}\\win32\\bin;${CASROOT}\\win${BITS}\\bin;${CASROOT}\\win${BITS}\\vc9\\bin;${CASROOT}\\win${BITS}\\vc10\\bin;${CASROOT}\\win${BITS}\\vc14\\bin) ELSE(WIN32) message( FATAL_ERROR "Unknown system! Exiting." ) ENDIF (WIN32) ENDIF (UNIX) #find the include dir by looking for Standard_Real.hxx - FIND_PATH( OpenCASCADE_INCLUDE_DIR Standard_Real.hxx PATH_SUFFIXES oce PATHS ${_incsearchpath} DOC "Path to OCC includes" ) - IF( OpenCASCADE_INCLUDE_DIR STREQUAL Standard_Real.hxx-NOTFOUND ) + FIND_PATH( OpenCASCADE_INCLUDE_DIR Standard_Real.hxx PATH_SUFFIXES oce PATHS ${_incsearchpath} DOC "Path to OCC includes" ) + IF( OpenCASCADE_INCLUDE_DIR MATCHES "NOTFOUND" ) SET( OpenCASCADE_FOUND FALSE CACHE BOOL FORCE ) - MESSAGE( FATAL_ERROR "Cannot find OCC include dir. Install opencascade or set CASROOT or create a symlink /opt/occ/inc pointing to the correct directory." ) - ENDIF( OpenCASCADE_INCLUDE_DIR STREQUAL Standard_Real.hxx-NOTFOUND ) + MESSAGE( FATAL_ERROR "Cannot find OCC include dir. Install opencascade or add the include directory to INCLUDE or set CASROOT or create a symlink /opt/occ/inc pointing to the correct directory." ) + ENDIF( OpenCASCADE_INCLUDE_DIR MATCHES "NOTFOUND" ) # Find one lib and save its directory to OpenCASCADE_LINK_DIRECTORY. Because # OCC has so many libs, there is increased risk of a name collision. @@ -60,21 +60,21 @@ IF( NOT OpenCASCADE_FOUND ) SET( OpenCASCADE_LINK_DIRECTORY "OpenCASCADE_LINK_DIRECTORY-NOTFOUND" CACHE PATH "Path to OCC libs" ) FIND_LIBRARY(TKernel_OCCLIB NAMES TKernel PATHS ${_libsearchpath} ${OpenCASCADE_LINK_DIRECTORY}) MARK_AS_ADVANCED( TKernel_OCCLIB ) - IF(TKernel_OCCLIB STREQUAL TKernel_OCCLIB-NOTFOUND) + IF(TKernel_OCCLIB MATCHES "NOTFOUND") SET( OpenCASCADE_FOUND FALSE CACHE BOOL FORCE ) - MESSAGE( FATAL_ERROR "Cannot find OCC lib dir. Install opencascade or set CASROOT or create a symlink /opt/occ/lib pointing to the dir where the OCC libs are." ) - ELSE(TKernel_OCCLIB STREQUAL TKernel_OCCLIB-NOTFOUND) + MESSAGE( FATAL_ERROR "Cannot find OCC lib dir. Install opencascade or add the lib directory to LIB or set CASROOT or create a symlink /opt/occ/lib pointing to the dir where the OCC libs are." ) + ELSE(TKernel_OCCLIB MATCHES "NOTFOUND") GET_FILENAME_COMPONENT(TMPDIR ${TKernel_OCCLIB} PATH) SET( OpenCASCADE_LINK_DIRECTORY ${TMPDIR} CACHE PATH "Path to OCC libs" FORCE) - ENDIF(TKernel_OCCLIB STREQUAL TKernel_OCCLIB-NOTFOUND) + ENDIF(TKernel_OCCLIB MATCHES "NOTFOUND") # check dll path if(WIN32) FIND_PATH( OpenCASCADE_DLL_DIRECTORY ${_testdllname} PATH ${_dllsearchpath} DOC "Path to OCC dlls" NO_SYSTEM_ENVIRONMENT_PATH) - IF( OpenCASCADE_DLL_DIRECTORY STREQUAL OpenCASCADE_DLL_DIRECTORY-NOTFOUND ) + IF( OpenCASCADE_DLL_DIRECTORY MATCHES "NOTFOUND" ) SET( OpenCASCADE_FOUND FALSE CACHE BOOL FORCE ) MESSAGE( FATAL_ERROR "Cannot find OCC DLL dir. Install opencascade or set CASROOT to the correct directory." ) - ENDIF( OpenCASCADE_DLL_DIRECTORY STREQUAL OpenCASCADE_DLL_DIRECTORY-NOTFOUND ) + ENDIF( OpenCASCADE_DLL_DIRECTORY MATCHES "NOTFOUND" ) endif(WIN32) # everything was found diff --git a/cmake/GitProjectVersion.cmake b/cmake/GitProjectVersion.cmake index c92ce991da..1e6f227d28 100644 --- a/cmake/GitProjectVersion.cmake +++ b/cmake/GitProjectVersion.cmake @@ -1,32 +1,54 @@ find_package( Git REQUIRED ) -# See `scr/t8_version.h` for the documentation of following definitions. +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") + # See `scr/t8_version.h` for the documentation of following definitions. + + execute_process( COMMAND ${GIT_EXECUTABLE} describe --tags --dirty + COMMAND cut -c 2- + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE T8CODE_VERSION_RAW + OUTPUT_STRIP_TRAILING_WHITESPACE ) + execute_process( COMMAND echo ${T8CODE_VERSION_RAW} + COMMAND cut -d- -f1 + OUTPUT_VARIABLE T8CODE_VERSION_NUMBERS + OUTPUT_STRIP_TRAILING_WHITESPACE ) + execute_process( COMMAND echo ${T8CODE_VERSION_RAW} + COMMAND cut -d- -f2- + OUTPUT_VARIABLE T8CODE_VERSION_POINT + OUTPUT_STRIP_TRAILING_WHITESPACE ) + + # To reuse the version in other CMakeLists. + else() + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/version.txt") + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version.txt" VERSION_CONTENT) + # Extract the version number + string(REGEX MATCH "Version ([0-9])\.([0-9]+)\.([0-9]+)" VERSION_MATCH "${VERSION_CONTENT}" ) + if (VERSION_MATCH) + # The version number will be in ${CMAKE_MATCH_1} + set(T8CODE_VERSION_NUMBERS "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + set(T8CODE_VERSION_RAW "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + message(STATUS "Extracted Version: ${T8CODE_VERSION_NUMBERS}") + else() + message(WARNING "Version number not found in version.txt") + endif() + else() + message(WARNING "Version information not found") + endif() +endif() + -execute_process( COMMAND ${GIT_EXECUTABLE} describe --tags --dirty - COMMAND cut -c 2- - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - OUTPUT_VARIABLE T8CODE_VERSION_RAW - OUTPUT_STRIP_TRAILING_WHITESPACE ) -execute_process( COMMAND echo ${T8CODE_VERSION_RAW} - COMMAND cut -d- -f1 - OUTPUT_VARIABLE T8CODE_VERSION_NUMBERS - OUTPUT_STRIP_TRAILING_WHITESPACE ) -execute_process( COMMAND echo ${T8CODE_VERSION_RAW} - COMMAND cut -d- -f2- - OUTPUT_VARIABLE T8CODE_VERSION_POINT - OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND echo ${T8CODE_VERSION_NUMBERS} - COMMAND cut -d. -f1 - OUTPUT_VARIABLE T8CODE_VERSION_MAJOR - OUTPUT_STRIP_TRAILING_WHITESPACE ) + COMMAND cut -d. -f1 + OUTPUT_VARIABLE T8CODE_VERSION_MAJOR + OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND echo ${T8CODE_VERSION_NUMBERS} - COMMAND cut -d. -f2 - OUTPUT_VARIABLE T8CODE_VERSION_MINOR - OUTPUT_STRIP_TRAILING_WHITESPACE ) + COMMAND cut -d. -f2 + OUTPUT_VARIABLE T8CODE_VERSION_MINOR + OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND echo ${T8CODE_VERSION_NUMBERS} - COMMAND cut -d. -f3 - OUTPUT_VARIABLE T8CODE_VERSION_PATCH - OUTPUT_STRIP_TRAILING_WHITESPACE ) - -# To reuse the version in other CMakeLists. + COMMAND cut -d. -f3 + OUTPUT_VARIABLE T8CODE_VERSION_PATCH + OUTPUT_STRIP_TRAILING_WHITESPACE ) set(T8_VERSION ${T8CODE_VERSION_NUMBERS} CACHE INTERNAL "") + + diff --git a/config/t8_fortran.m4 b/config/t8_fortran.m4 new file mode 100644 index 0000000000..b1e452376e --- /dev/null +++ b/config/t8_fortran.m4 @@ -0,0 +1,34 @@ +dnl T8_CHECK_FORTRAN +dnl This functions checks some properties of Fortran modules and +dnl whether specific directory for the Fortran module files has been specified or not. +dnl +dnl A directory may be specified by the option --with-moddir= +dnl This option is only of relevance if the option --enable-fortran has been chosen, +dnl since only in this case Fortran codes will be compiled +dnl +AC_DEFUN([T8_CHECK_FORTRAN], [ + +dnl Check if a directory has been specified which will hold the module files +T8_ARG_WITH([moddir], + [if Fortran modules will be built, this option specifies an explicit directory which should hold the module files (use --with-moddir=)], + [MODDIR]) + +dnl If Fortran is enabled +if test "x$T8_ENABLE_FORTRAN" != xno ; then + +dnl Check the properties of Fortran modules (after the Fortran Compiler has been found by MPI_ENGAGE) +AC_FC_MODULE_EXTENSION +AC_FC_MODULE_FLAG +AC_FC_MODULE_OUTPUT_FLAG + +if test "x$T8_WITH_MODDIR" = xyes ; then + dnl The option is given without a directory + AC_MSG_ERROR([missing directory path for the module directory]) +elif test "x$T8_WITH_MODDIR" != xno ; then + AC_MSG_NOTICE([we have set a module dir var]) + dnl Substitute the variable in the makefile + AC_SUBST(T8_FORTRAN_MODULE_DIR, $T8_WITH_MODDIR) +fi + +fi +]) diff --git a/doc/author_albers.txt b/doc/author_albers.txt new file mode 100644 index 0000000000..36c70c8599 --- /dev/null +++ b/doc/author_albers.txt @@ -0,0 +1 @@ +I place my contributions to t8code under the FreeBSD license. Ole Albers (ole.albers@arcor.de). diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 5fcb9239eb..ad32fd28a7 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -5,8 +5,8 @@ else() add_library( t8example STATIC ) endif() target_sources( t8example PRIVATE common/t8_example_common.cxx common/t8_example_common_functions.cxx ) -target_include_directories( t8example PRIVATE ${CMAKE_CURRENT_LIST_DIR}/.. ) -target_link_libraries( t8example PRIVATE T8 ) +target_include_directories( t8example PRIVATE ${CMAKE_CURRENT_LIST_DIR}/.. ${SC_INCLUDE_DIR} ) +target_link_libraries( t8example PRIVATE T8 ${SC_LIBRARIES} m ) install( TARGETS t8example DESTINATION ${CMAKE_INSTALL_PREFIX}/lib ) function( add_t8_example ) @@ -15,10 +15,27 @@ function( add_t8_example ) set( multiValueArgs "SOURCES" ) cmake_parse_arguments( ADD_T8_EXAMPLE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + # Get the path of the first file listed in the SOURCES list and use it to determine the build directory. + # The executable will be build in the same directory as the first source file. + list(GET ADD_T8_EXAMPLE_SOURCES 0 FIRST_SOURCE) + get_filename_component(EXAMPLE_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/${FIRST_SOURCE}" DIRECTORY) + file(RELATIVE_PATH EXAMPLE_RELATIVE_DIR "${CMAKE_SOURCE_DIR}" "${EXAMPLE_SOURCE_DIR}") + set(EXAMPLE_BUILD_DIR "${CMAKE_BINARY_DIR}/${EXAMPLE_RELATIVE_DIR}") + add_executable( ${ADD_T8_EXAMPLE_NAME} ${ADD_T8_EXAMPLE_SOURCES} ) target_link_libraries( ${ADD_T8_EXAMPLE_NAME} PRIVATE T8 t8example SC::SC ) target_include_directories( ${ADD_T8_EXAMPLE_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/.. ) + set_target_properties(${ADD_T8_EXAMPLE_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${EXAMPLE_BUILD_DIR}" + LIBRARY_OUTPUT_DIRECTORY "${EXAMPLE_BUILD_DIR}" + ARCHIVE_OUTPUT_DIRECTORY "${EXAMPLE_BUILD_DIR}" + ) + + if( T8CODE_EXPORT_COMPILE_COMMANDS ) + set_target_properties( ${ADD_T8_EXAMPLE_NAME} PROPERTIES EXPORT_COMPILE_COMMANDS ON ) + endif( T8CODE_EXPORT_COMPILE_COMMANDS ) + install( TARGETS ${ADD_T8_EXAMPLE_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin ) endfunction() diff --git a/example/IO/cmesh/gmsh/t8_read_msh_file.cxx b/example/IO/cmesh/gmsh/t8_read_msh_file.cxx index 48616cf92f..192976f77a 100644 --- a/example/IO/cmesh/gmsh/t8_read_msh_file.cxx +++ b/example/IO/cmesh/gmsh/t8_read_msh_file.cxx @@ -3,7 +3,7 @@ t8code is a C library to manage a collection (a forest) of multiple connected adaptive space-trees of general element types in parallel. - Copyright (C) 2015 the developers + Copyright (C) 2024 the developers t8code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -140,7 +140,7 @@ main (int argc, char *argv[]) opt = sc_options_new (argv[0]); sc_options_add_switch (opt, 'h', "help", &helpme, "Display a short help message."); - sc_options_add_string (opt, 'f', "prefix", &prefix, "", "The prefix of the tetgen files."); + sc_options_add_string (opt, 'f', "prefix", &prefix, "", "The prefix of the gmsh files."); sc_options_add_switch (opt, 'p', "partition", &partition, "If true the generated cmesh is repartitioned uniformly."); sc_options_add_int (opt, 'd', "dim", &dim, 2, "The dimension of the mesh"); sc_options_add_int (opt, 'm', "master", &master, -1, diff --git a/example/IO/forest/gmsh/t8_gmsh_to_vtk.cxx b/example/IO/forest/gmsh/t8_gmsh_to_vtk.cxx index fb8c862b89..cb0e662e51 100644 --- a/example/IO/forest/gmsh/t8_gmsh_to_vtk.cxx +++ b/example/IO/forest/gmsh/t8_gmsh_to_vtk.cxx @@ -79,9 +79,8 @@ main (int argc, char **argv) sc_options_add_string (opt, 'f', "fileprefix", &fileprefix, NULL, "Fileprefix of the msh and brep files."); sc_options_add_int (opt, 'l', "level", &level, 2, "The uniform refinement level. Default: 2"); sc_options_add_int (opt, 'd', "dimension", &dim, 3, "The dimension of the mesh. Default: 3"); - sc_options_add_int ( - opt, 'c', "use_cad", &use_cad, 0, - "Enable CAD-based curvilinear geometry. Needs a `.brep` file with the same file prefix. Default: 0"); + sc_options_add_switch (opt, 'c', "use_cad", &use_cad, + "Enable CAD-based curvilinear geometry. Needs a `.brep` file with the same file prefix."); parsed = sc_options_parse (t8_get_package_id (), SC_LP_ERROR, opt, argc, argv); if (helpme) { diff --git a/example/geometry/t8_example_geometries.cxx b/example/geometry/t8_example_geometries.cxx index 0139974b6e..dc8384ac57 100644 --- a/example/geometry/t8_example_geometries.cxx +++ b/example/geometry/t8_example_geometries.cxx @@ -81,8 +81,8 @@ typedef enum { struct t8_geometry_sincos: public t8_geometry { public: - /* Basic constructor that sets the dimension and the name. */ - t8_geometry_sincos (): t8_geometry (2, "t8_sincos_geometry") + /* Basic constructor that sets the name. */ + t8_geometry_sincos (): t8_geometry ("t8_sincos_geometry") { } @@ -93,7 +93,7 @@ struct t8_geometry_sincos: public t8_geometry * models the rectangle [0,2] x [0,1]. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -139,6 +139,22 @@ struct t8_geometry_sincos: public t8_geometry return 0; } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only quad elements are supported by this geometry. + */ + bool + t8_geom_check_tree_compatibility () const + { + if (active_tree_class != T8_ECLASS_QUAD) { + t8_productionf ( + "t8_geometry_sincos is not compatible with tree type %s\n It is only compatible with quad elements.\n", + t8_eclass_to_string[active_tree_class]); + return false; + } + return true; + } + /** * Get the type of this geometry. * \return The type. @@ -159,8 +175,8 @@ struct t8_geometry_sincos: public t8_geometry struct t8_geometry_moebius: public t8_geometry_with_vertices { public: - /* Basic constructor that sets the dimension and the name. */ - t8_geometry_moebius (): t8_geometry_with_vertices (2, "t8_moebius_geometry") + /* Basic constructor that sets the name. */ + t8_geometry_moebius (): t8_geometry_with_vertices ("t8_moebius_geometry") { } @@ -168,7 +184,7 @@ struct t8_geometry_moebius: public t8_geometry_with_vertices * Maps points in \f$ [0,1]^2 \f$ to the moebius band. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -203,6 +219,22 @@ struct t8_geometry_moebius: public t8_geometry_with_vertices SC_ABORT_NOT_REACHED (); } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only quad elements are supported by this geometry. + */ + bool + t8_geom_check_tree_compatibility () const + { + if (active_tree_class != T8_ECLASS_QUAD) { + t8_productionf ( + "t8_geometry_moebius is not compatible with tree type %s\n It is only compatible with quad elements.\n", + t8_eclass_to_string[active_tree_class]); + return false; + } + return true; + } + /** * Get the type of this geometry. * \return The type. @@ -224,8 +256,8 @@ struct t8_geometry_moebius: public t8_geometry_with_vertices struct t8_geometry_cylinder: public t8_geometry { public: - /* Basic constructor that sets the dimension and the name. */ - t8_geometry_cylinder (): t8_geometry (2, "t8_cylinder_geometry") + /* Basic constructor that sets the name. */ + t8_geometry_cylinder (): t8_geometry ("t8_cylinder_geometry") { } @@ -233,7 +265,7 @@ struct t8_geometry_cylinder: public t8_geometry * Map a reference point in the unit square to a cylinder. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -273,6 +305,22 @@ struct t8_geometry_cylinder: public t8_geometry return 0; } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only quad elements are supported by this geometry. + */ + bool + t8_geom_check_tree_compatibility () const + { + if (active_tree_class != T8_ECLASS_QUAD) { + t8_productionf ( + "t8_geometry_cylinder is not compatible with tree type %s\n It is only compatible with quad elements.\n", + t8_eclass_to_string[active_tree_class]); + return false; + } + return true; + } + /** * Get the type of this geometry. * \return The type. @@ -295,8 +343,8 @@ struct t8_geometry_cylinder: public t8_geometry struct t8_geometry_circle: public t8_geometry_with_vertices { public: - /* Basic constructor that sets the dimension and the name. */ - t8_geometry_circle (): t8_geometry_with_vertices (2, "t8_circle_geometry") + /* Basic constructor that sets the name. */ + t8_geometry_circle (): t8_geometry_with_vertices ("t8_circle_geometry") { } @@ -304,7 +352,7 @@ struct t8_geometry_circle: public t8_geometry_with_vertices * Map a reference point in the unit square to a circle. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -341,6 +389,22 @@ struct t8_geometry_circle: public t8_geometry_with_vertices SC_ABORT_NOT_REACHED (); } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only quad elements are supported by this geometry. + */ + bool + t8_geom_check_tree_compatibility () const + { + if (active_tree_class != T8_ECLASS_QUAD) { + t8_productionf ( + "t8_geometry_circle is not compatible with tree type %s\n It is only compatible with quad elements.\n", + t8_eclass_to_string[active_tree_class]); + return false; + } + return true; + } + /** * Get the type of this geometry. * \return The type. @@ -367,8 +431,8 @@ struct t8_geometry_circle: public t8_geometry_with_vertices struct t8_geometry_moving: public t8_geometry { public: - /* Basic constructor that sets the dimension the name and the time pointer. */ - t8_geometry_moving (const double *time): t8_geometry (2, "t8_moving_geometry"), ptime (time) + /* Basic constructor that sets the name and the time pointer. */ + t8_geometry_moving (const double *time): t8_geometry ("t8_moving_geometry"), ptime (time) { } @@ -376,7 +440,7 @@ struct t8_geometry_moving: public t8_geometry * Map a reference point in the unit square to a square distorted with time. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -434,6 +498,22 @@ struct t8_geometry_moving: public t8_geometry return 0; } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only quad elements are supported by this geometry. + */ + bool + t8_geom_check_tree_compatibility () const + { + if (active_tree_class != T8_ECLASS_QUAD) { + t8_productionf ( + "t8_geometry_moving is not compatible with tree type %s\n It is only compatible with quad elements.\n", + t8_eclass_to_string[active_tree_class]); + return false; + } + return true; + } + /** * Get the type of this geometry. * \return The type. @@ -455,15 +535,15 @@ struct t8_geometry_moving: public t8_geometry struct t8_geometry_cube_zdistorted: public t8_geometry { public: - /* Basic constructor that sets the dimension and the name. */ - t8_geometry_cube_zdistorted (): t8_geometry (3, "t8_cube_zdistorted_geometry") + /* Basic constructor that sets the name. */ + t8_geometry_cube_zdistorted (): t8_geometry ("t8_cube_zdistorted_geometry") { } /** * Map a reference point in the unit cube to a cube distorted in the z axis. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^2 \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -504,6 +584,22 @@ struct t8_geometry_cube_zdistorted: public t8_geometry return 0; } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only hex elements are supported by this geometry. + */ + bool + t8_geom_check_tree_compatibility () const + { + if (active_tree_class != T8_ECLASS_HEX) { + t8_productionf ( + "t8_geometry_cube_zdistorted is not compatible with tree type %s\n It is only compatible with hex elements.\n", + t8_eclass_to_string[active_tree_class]); + return false; + } + return true; + } + /** * Get the type of this geometry. * \return The type. @@ -652,8 +748,8 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type) break; case T8_GEOM_ANALYTIC_QUAD_TO_SPHERE: t8_global_productionf ("Wrapping a quad around a sphere.\n"); - t8_cmesh_register_geometry (cmesh, 3, "geom_quad_to_sphere", quad_to_sphere_callback, nullptr, - nullptr, nullptr, nullptr); + t8_cmesh_register_geometry (cmesh, "geom_quad_to_sphere", quad_to_sphere_callback, nullptr, + nullptr, nullptr, nullptr, nullptr); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD); t8_cmesh_set_join (cmesh, 0, 0, 1, 0, 0); @@ -680,7 +776,7 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type) shape = BRepBuilderAPI_MakeEdge (cad_curve).Edge (); /* Create a cad geometry. */ - t8_cmesh_register_geometry (cmesh, 2, shape); + t8_cmesh_register_geometry (cmesh, shape); /* The arrays indicate which face/edge carries a geometry. * 0 means no geometry and any other number indicates the position of the geometry @@ -744,7 +840,7 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type) shape = BRepAlgoAPI_Fuse (shape, BRepBuilderAPI_MakeEdge (cad_curve1).Edge ()); /* Create a cad geometry. */ - t8_cmesh_register_geometry (cmesh, 3, shape); + t8_cmesh_register_geometry (cmesh, shape); /* The arrays indicate which face/edge carries a geometry. * 0 means no geometry and any other number indicates the position of the geometry @@ -845,7 +941,7 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type) int edges[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* Create cad geometry. */ - t8_cmesh_register_geometry (cmesh, 3, shape); + t8_cmesh_register_geometry (cmesh, shape); /* Create tree 0 */ t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_HEX); @@ -942,7 +1038,7 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type) int edges[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* Create a cad geometry. */ - t8_cmesh_register_geometry (cmesh, 3, shape); + t8_cmesh_register_geometry (cmesh, shape); /* Create corresponding trees and parameters. * Here we create num trees by a coordinate transformation from cylinder to cartesian coordinates. */ diff --git a/p4est b/p4est index 7896878956..8206f0e56d 160000 --- a/p4est +++ b/p4est @@ -1 +1 @@ -Subproject commit 78968789560133460f0eee74897a44b3444790e5 +Subproject commit 8206f0e56d536d6d7f2e1d106c491b8c9386e28f diff --git a/pull_request_template.md b/pull_request_template.md index b253b5fe7f..de9763105b 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -10,7 +10,7 @@ As a reviewer please read through all the code lines and make sure that the code #### General - [ ] The reviewer executed the new code features at least once and checked the results manually -- [ ] The code follows the [t8code coding guidelines](https://github.com/holke/t8code/wiki/Coding-Guideline) +- [ ] The code follows the [t8code coding guidelines](https://github.com/DLR-AMR/t8code/wiki/Coding-Guideline) - [ ] New source/header files are properly added to the Makefiles - [ ] The code is well documented - [ ] All function declarations, structs/classes and their members have a proper doxygen documentation @@ -33,6 +33,6 @@ As a reviewer please read through all the code lines and make sure that the code - [ ] If a new directory with source-files is added, it must be covered by the `script/find_all_source_files.scp` to check the indentation of these files. - [ ] If this PR introduces a new feature, it must be covered in an example/tutorial and a Wiki article. -#### Licence +#### License - [ ] The author added a BSD statement to `doc/` (or already has one) diff --git a/scripts/README.md b/scripts/README.md index f488ff64b6..110dd9d6d3 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -4,7 +4,7 @@ This folder contains several scripts that are useful for t8code users and develo ## Indentation -The purpose of the indentation scripts is to help t8code developers to indent their code according to the t8code [indentation guidelines](https://github.com/holke/t8code/wiki/Coding-Guideline#indentation). Please read these guidelines before using these scripts. +The purpose of the indentation scripts is to help t8code developers to indent their code according to the t8code [indentation guidelines](https://github.com/DLR-AMR/t8code/wiki/Coding-Guideline#indentation). Please read these guidelines before using these scripts. #### t8indent @@ -16,7 +16,7 @@ Sometimes `t8indent` does produce undesired results. Therefore, after indenting #### pre-commit -This script should be copied to your `.git/hooks` folder. `git` then automatically checks the indentation of committed files and prevents you from committing wrongly indented files. See [Git indentation workflow](https://github.com/holke/t8code/wiki/Coding-Guideline#git-indentation-workflow). +This script should be copied to your `.git/hooks` folder. `git` then automatically checks the indentation of committed files and prevents you from committing wrongly indented files. See [Git indentation workflow](https://github.com/DLR-AMR/t8code/wiki/Coding-Guideline#git-indentation-workflow). #### check_if_file_indented.scp diff --git a/scripts/indent_all_files.scp b/scripts/indent_all_files.scp index 2b176f09b1..8879513291 100755 --- a/scripts/indent_all_files.scp +++ b/scripts/indent_all_files.scp @@ -55,6 +55,7 @@ echo $PWD/../example/ echo $PWD/../test/ echo $PWD/../tutorials/ echo $PWD/../benchmarks/ +echo $PWD/../api/ echo read -p "Are you sure? ('Y' or 'y' to continue)" -n 1 -r echo diff --git a/scripts/t8indent b/scripts/t8indent index 8c1567acb7..bf5aff81a3 100755 --- a/scripts/t8indent +++ b/scripts/t8indent @@ -31,8 +31,7 @@ FORMAT_OPTIONS="-i --style=file" # Required version of the clang format program. REQUIRED_VERSION_MAJOR="17" REQUIRED_VERSION_MINOR="0" -REQUIRED_VERSION_PATCH="1" -REQUIRED_VERSION_STRING="${REQUIRED_VERSION_MAJOR}.${REQUIRED_VERSION_MINOR}.${REQUIRED_VERSION_PATCH}" +REQUIRED_VERSION_STRING="${REQUIRED_VERSION_MAJOR}.${REQUIRED_VERSION_MINOR}" FORMAT=`which clang-format 2> /dev/null` @@ -52,7 +51,7 @@ MAJOR=`echo $VERSION | cut -d. -f1` MINOR=`echo $VERSION | cut -d. -f2` PATCH=`echo $VERSION | cut -d. -f3` -if [[ "$MAJOR" != "$REQUIRED_VERSION_MAJOR" || $MINOR != "$REQUIRED_VERSION_MINOR" || $PATCH != "$REQUIRED_VERSION_PATCH" ]]; then +if [[ "$MAJOR" != "$REQUIRED_VERSION_MAJOR" || $MINOR != "$REQUIRED_VERSION_MINOR" ]]; then echo "Please install clang-format version $REQUIRED_VERSION_STRING" exit 1 fi diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6cc4516e49..899c014f74 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,10 @@ if( CMAKE_BUILD_TYPE STREQUAL "Debug" ) target_compile_definitions( T8 PUBLIC T8_ENABLE_DEBUG ) endif() +if( T8CODE_EXPORT_COMPILE_COMMANDS ) + set_target_properties( T8 PROPERTIES EXPORT_COMPILE_COMMANDS ON ) +endif( T8CODE_EXPORT_COMPILE_COMMANDS ) + if( T8CODE_ENABLE_NETCDF ) target_link_libraries( T8 PUBLIC netCDF::netcdf ) target_compile_definitions(T8 PUBLIC @@ -90,7 +94,7 @@ target_sources( T8 PRIVATE t8_cmesh/t8_cmesh_vtk_reader.cxx t8_cmesh/t8_cmesh_save.cxx t8_cmesh/t8_cmesh_netcdf.c - t8_cmesh/t8_cmesh_trees.c + t8_cmesh/t8_cmesh_trees.cxx t8_cmesh/t8_cmesh_commit.cxx t8_cmesh/t8_cmesh_partition.cxx t8_cmesh/t8_cmesh_copy.c diff --git a/src/Makefile.am b/src/Makefile.am index e559ab5704..d60a5ccac6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -117,7 +117,7 @@ libt8_compiled_sources = \ src/t8_cmesh/t8_cmesh_vtk_reader.cxx \ src/t8_cmesh/t8_cmesh_save.cxx \ src/t8_cmesh/t8_cmesh_netcdf.c \ - src/t8_cmesh/t8_cmesh_trees.c src/t8_cmesh/t8_cmesh_commit.cxx \ + src/t8_cmesh/t8_cmesh_trees.cxx src/t8_cmesh/t8_cmesh_commit.cxx \ src/t8_cmesh/t8_cmesh_vertex_conn_tree_to_vertex.cxx \ src/t8_cmesh/t8_cmesh_vertex_conn_vertex_to_tree.cxx \ src/t8_cmesh/t8_cmesh_vertex_connectivity.cxx \ diff --git a/src/t8_cmesh.h b/src/t8_cmesh.h index 3c0a6b68b0..186835b722 100644 --- a/src/t8_cmesh.h +++ b/src/t8_cmesh.h @@ -104,17 +104,6 @@ t8_cmesh_is_committed (const t8_cmesh_t cmesh); */ int t8_cmesh_validate_geometry (const t8_cmesh_t cmesh); - -/** After a cmesh is committed, check whether all trees in a cmesh do have positive volume. - * Returns true if all trees have positive volume. - * \param [in] cmesh This cmesh is examined. May be NULL. - * \return True if \a cmesh is not NULL and all trees for - * which \ref t8_cmesh_set_tree_vertices - * was called, do have positive geometric volume. - * False otherwise. - */ -int -t8_cmesh_no_negative_volume (t8_cmesh_t cmesh); #endif /** Given a set of vertex coordinates for a tree of a given eclass. diff --git a/src/t8_cmesh/t8_cmesh.cxx b/src/t8_cmesh/t8_cmesh.cxx index 462e008754..c04d3febde 100644 --- a/src/t8_cmesh/t8_cmesh.cxx +++ b/src/t8_cmesh/t8_cmesh.cxx @@ -125,15 +125,45 @@ t8_cmesh_is_committed (const t8_cmesh_t cmesh) return 1; } -#ifdef T8_ENABLE_DEBUG +#if T8_ENABLE_DEBUG int t8_cmesh_validate_geometry (const t8_cmesh_t cmesh) { + /* After a cmesh is committed, check whether all trees in a cmesh are compatible + * with their geometry and if they have positive volume. + * Returns true if all trees are valid. Returns also true if no geometries are + * registered yet, since the validity computation depends on the used geometry. + */ + /* Geometry handler is not constructed yet */ if (cmesh->geometry_handler == NULL) { - return 1; + return true; } - return t8_cmesh_no_negative_volume (cmesh); + if (cmesh == NULL) { + return true; + } + if (cmesh->geometry_handler->get_num_geometries () > 0) { + /* Iterate over all trees, get their vertices and check the volume */ + for (t8_locidx_t itree = 0; itree < cmesh->num_local_trees; itree++) { + /* Check if tree and geometry are compatible. */ + const int geometry_compatible + = cmesh->geometry_handler->tree_compatible_with_geom (cmesh, t8_cmesh_get_global_id (cmesh, itree)); + if (!geometry_compatible) { + t8_debugf ("Detected incompatible geometry for tree %li\n", (long) itree); + return false; + } + if (geometry_compatible) { + /* Check for negative volume. This only makes sense if the geometry is valid for the tree. */ + const int negative_volume + = cmesh->geometry_handler->tree_negative_volume (cmesh, t8_cmesh_get_global_id (cmesh, itree)); + if (negative_volume) { + t8_debugf ("Detected negative volume in tree %li\n", (long) itree); + return false; + } + } + } + } + return true; } #endif /* T8_ENABLE_DEBUG */ @@ -402,7 +432,6 @@ t8_cmesh_get_tree_vertices (const t8_cmesh_t cmesh, const t8_locidx_t ltreeid) { T8_ASSERT (t8_cmesh_is_committed (cmesh)); T8_ASSERT (t8_cmesh_treeid_is_local_tree (cmesh, ltreeid) || t8_cmesh_treeid_is_ghost (cmesh, ltreeid)); - return (double *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_VERTICES_ATTRIBUTE_KEY, ltreeid); } @@ -584,39 +613,6 @@ t8_cmesh_tree_vertices_negative_volume (const t8_eclass_t eclass, const double * return eclass == T8_ECLASS_TET ? sc_prod > 0 : sc_prod < 0; } -#ifdef T8_ENABLE_DEBUG -/* After a cmesh is committed, check whether all trees in a cmesh do have positive volume. - * Returns true if all trees have positive volume. Returns also true if no geometries are - * registered yet, since the volume computation depends on the used geometry. - */ -int -t8_cmesh_no_negative_volume (const t8_cmesh_t cmesh) -{ - bool res = false; - - if (cmesh == NULL) { - return 0; - } - if (cmesh->geometry_handler == NULL) { - return 0; - } - if (cmesh->geometry_handler->get_num_geometries () > 0) { - /* Iterate over all trees, get their vertices and check the volume */ - for (t8_locidx_t itree = 0; itree < cmesh->num_local_trees; itree++) { - const int ret = cmesh->geometry_handler->tree_negative_volume (cmesh, t8_cmesh_get_global_id (cmesh, itree)); - if (ret) { - t8_debugf ("Detected negative volume in tree %li\n", (long) itree); - } - res |= ret; /* res is true if one ret value is true */ - } - return !res; - } - else { - return true; - } -} -#endif - void t8_cmesh_set_tree_vertices (t8_cmesh_t cmesh, const t8_gloidx_t gtree_id, const double *vertices, const int num_vertices) diff --git a/src/t8_cmesh/t8_cmesh_cad.cxx b/src/t8_cmesh/t8_cmesh_cad.cxx index 10b91311c5..5eba00cf4d 100644 --- a/src/t8_cmesh/t8_cmesh_cad.cxx +++ b/src/t8_cmesh/t8_cmesh_cad.cxx @@ -81,14 +81,14 @@ t8_cmesh_new_hollow_cylinder (sc_MPI_Comm comm, int num_tangential_trees, int nu shape = BRepBuilderAPI_MakeFace (cylinder_outer, 1e-6).Face (); shape = BRepAlgoAPI_Fuse (shape, BRepBuilderAPI_MakeFace (cylinder_inner, 1e-6).Face ()); - t8_cmesh_register_geometry (cmesh, 3, shape, "cad surface"); + t8_cmesh_register_geometry (cmesh, shape, "cad surface"); #else /* !T8_WITH_OCC */ SC_ABORTF ("OCC not linked"); #endif /* T8_WITH_OCC */ } else { - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); } #if T8_WITH_OCC diff --git a/src/t8_cmesh/t8_cmesh_commit.cxx b/src/t8_cmesh/t8_cmesh_commit.cxx index b76299ccff..9c53731059 100644 --- a/src/t8_cmesh/t8_cmesh_commit.cxx +++ b/src/t8_cmesh/t8_cmesh_commit.cxx @@ -85,7 +85,7 @@ t8_cmesh_set_shmem_type (sc_MPI_Comm comm) } static void -t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids, size_t *attribute_data_offset) +t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids) { t8_stash_attribute_struct_t *attribute; const t8_stash_t stash = cmesh->stash; @@ -95,6 +95,7 @@ t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids, size_t *a temp_facejoin = T8_ALLOC_ZERO (t8_ghost_facejoin_t, 1); + t8_locidx_t ghosts_inserted = 0; ltree = -1; for (si = 0, sj = 0; si < stash->attributes.elem_count; si++, sj++) { attribute = (t8_stash_attribute_struct_t *) sc_array_index (&stash->attributes, si); @@ -113,9 +114,13 @@ t8_cmesh_add_attributes (const t8_cmesh_t cmesh, sc_hash_t *ghost_ids, size_t *a T8_ASSERT (ghost_ids != NULL); temp_facejoin->ghost_id = attribute->id; if (sc_hash_lookup (ghost_ids, temp_facejoin, (void ***) &facejoin_pp)) { + T8_ASSERT ((t8_locidx_t) sj == (t8_locidx_t) (*facejoin_pp)->attr_id); + if (sj == 0) { + ghosts_inserted++; + } /* attribute is on a ghost tree */ - t8_cmesh_trees_add_ghost_attribute (cmesh->trees, 0, attribute, (*facejoin_pp)->local_id, - (*facejoin_pp)->attr_id, attribute_data_offset); + t8_cmesh_trees_add_ghost_attribute (cmesh->trees, attribute, (*facejoin_pp)->local_id, ghosts_inserted, + (*facejoin_pp)->attr_id); (*facejoin_pp)->attr_id++; } } @@ -168,7 +173,7 @@ t8_cmesh_commit_replicated_new (t8_cmesh_t cmesh) t8_stash_attribute_sort (cmesh->stash); cmesh->num_trees = cmesh->num_local_trees = num_trees; cmesh->first_tree = 0; - t8_cmesh_add_attributes (cmesh, NULL, NULL); + t8_cmesh_add_attributes (cmesh, NULL); /* Set all face connections */ t8_cmesh_trees_set_all_boundary (cmesh, cmesh->trees); @@ -199,7 +204,6 @@ t8_cmesh_commit_partitioned_new (t8_cmesh_t cmesh, sc_MPI_Comm comm) t8_cghost_t ghost1; int F; size_t si; - size_t attribute_data_offset; #if T8_ENABLE_DEBUG sc_flopinfo_t fi, snapshot; @@ -376,7 +380,7 @@ t8_cmesh_commit_partitioned_new (t8_cmesh_t cmesh, sc_MPI_Comm comm) ghost1->att_offset += attribute->attr_size; } } - attribute_data_offset = t8_cmesh_trees_finish_part (cmesh->trees, 0); + t8_cmesh_trees_finish_part (cmesh->trees, 0); t8_cmesh_trees_set_all_boundary (cmesh, cmesh->trees); /* Go through all face_neighbour entries and parse every @@ -474,7 +478,7 @@ t8_cmesh_commit_partitioned_new (t8_cmesh_t cmesh, sc_MPI_Comm comm) * counting the attributes per tree. */ t8_stash_attribute_sort (cmesh->stash); - t8_cmesh_add_attributes (cmesh, ghost_ids, &attribute_data_offset); + t8_cmesh_add_attributes (cmesh, ghost_ids); /* compute global number of trees. id1 serves as buffer since * global number and local number have different datatypes */ diff --git a/src/t8_cmesh/t8_cmesh_examples.cxx b/src/t8_cmesh/t8_cmesh_examples.cxx index 8425beb751..22dc75ea90 100644 --- a/src/t8_cmesh/t8_cmesh_examples.cxx +++ b/src/t8_cmesh/t8_cmesh_examples.cxx @@ -20,6 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include #include #include #include @@ -118,7 +119,7 @@ t8_cmesh_new_from_p4est_ext (void *conn, int dim, sc_MPI_Comm comm, int set_part /* basic setup */ t8_cmesh_init (&cmesh); /* We use the linear geometry */ - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); /* Add each tree to cmesh and get vertex information for each tree */ for (ltree = 0; ltree < _T8_CMESH_P48_CONN (num_trees); ltree++) { /* loop over each tree */ t8_cmesh_set_tree_class (cmesh, ltree + offset, dim == 2 ? T8_ECLASS_QUAD : T8_ECLASS_HEX); @@ -211,7 +212,7 @@ t8_cmesh_new_vertex (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 0); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_VERTEX); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 1); t8_cmesh_commit (cmesh, comm); @@ -231,7 +232,7 @@ t8_cmesh_new_line (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 1); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_LINE); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 2); t8_cmesh_commit (cmesh, comm); @@ -252,7 +253,7 @@ t8_cmesh_new_tri (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 2); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TRIANGLE); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 3); t8_cmesh_commit (cmesh, comm); @@ -274,7 +275,7 @@ t8_cmesh_new_tet (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TET); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 4); t8_cmesh_commit (cmesh, comm); @@ -296,7 +297,7 @@ t8_cmesh_new_quad (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 2); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 4); t8_cmesh_commit (cmesh, comm); @@ -322,7 +323,7 @@ t8_cmesh_new_hex (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_HEX); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 8); t8_cmesh_commit (cmesh, comm); @@ -345,7 +346,7 @@ t8_cmesh_new_pyramid_deformed (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_PYRAMID); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 5); t8_cmesh_commit (cmesh, comm); @@ -368,9 +369,9 @@ t8_cmesh_new_pyramid (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_PYRAMID); - t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 15); + t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 5); t8_cmesh_commit (cmesh, comm); return cmesh; } @@ -392,7 +393,7 @@ t8_cmesh_new_prism (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_PRISM); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 6); t8_cmesh_commit (cmesh, comm); @@ -489,7 +490,7 @@ t8_cmesh_new_hypercube_hybrid (sc_MPI_Comm comm, int do_partition, int periodic) } /* We use standard linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); /************************************/ /* The tetrahedra */ @@ -677,13 +678,12 @@ t8_cmesh_new_hypercube (t8_eclass_t eclass, sc_MPI_Comm comm, int do_bcast, int }; /* clang-format on */ - const int dim = t8_eclass_to_dimension[eclass]; SC_CHECK_ABORT (eclass != T8_ECLASS_PYRAMID || !periodic, "The pyramid cube mesh cannot be periodic.\n"); if (do_partition) { t8_global_errorf ( "WARNING: Partitioning the hypercube cmesh is currently not supported.\n" - "Using this cmesh will crash when vertices are used. See also https://github.com/holke/t8code/issues/79\n"); + "Using this cmesh will crash when vertices are used. See also https://github.com/DLR-AMR/t8code/issues/79\n"); } mpiret = sc_MPI_Comm_rank (comm, &mpirank); @@ -840,7 +840,7 @@ t8_cmesh_new_hypercube (t8_eclass_t eclass, sc_MPI_Comm comm, int do_bcast, int /* Use linear geometry */ /* We need to set the geometry after broadcasting, since we * cannot bcast the geometries. */ - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); /* Check whether the cmesh will be partitioned */ if (do_partition) { @@ -1289,10 +1289,10 @@ t8_cmesh_new_hypercube_pad_ext (const t8_eclass_t eclass, sc_MPI_Comm comm, cons t8_cmesh_init (&cmesh); if (use_axis_aligned) { - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); } else { - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); } /* Number of trees inside each polygon of given eclass. */ @@ -1623,7 +1623,7 @@ t8_cmesh_new_disjoint_bricks (t8_gloidx_t num_x, t8_gloidx_t num_y, t8_gloidx_t /* Create empty cmesh. */ t8_cmesh_init (&cmesh); - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); t8_cmesh_commit (cmesh, comm); } @@ -1645,7 +1645,7 @@ t8_cmesh_new_periodic_line_more_trees (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 1); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_LINE); t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_LINE); @@ -1678,7 +1678,7 @@ t8_cmesh_new_periodic_tri (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 2); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TRIANGLE); t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_TRIANGLE); @@ -1736,7 +1736,7 @@ t8_cmesh_new_periodic_hybrid (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 2); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TRIANGLE); t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_TRIANGLE); @@ -1793,7 +1793,7 @@ t8_cmesh_new_periodic (sc_MPI_Comm comm, int dim) T8_ASSERT (dim == 1 || dim == 2 || dim == 3); t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); switch (dim) { case 1: @@ -1863,7 +1863,7 @@ t8_cmesh_new_line_zigzag (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 1); + t8_cmesh_register_geometry (cmesh); for (i = 0; i < 3; i++) { t8_cmesh_set_tree_class (cmesh, i, T8_ECLASS_LINE); @@ -1916,7 +1916,7 @@ t8_cmesh_new_prism_cake (sc_MPI_Comm comm, int num_of_prisms) } t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); for (i = 0; i < num_of_prisms; i++) { t8_cmesh_set_tree_class (cmesh, i, T8_ECLASS_PRISM); @@ -1951,7 +1951,7 @@ t8_cmesh_new_prism_deformed (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_PRISM); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 6); t8_cmesh_commit (cmesh, comm); @@ -2022,7 +2022,7 @@ t8_cmesh_new_prism_cake_funny_oriented (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); for (i = 0; i < 6; i++) { t8_cmesh_set_tree_class (cmesh, i, T8_ECLASS_PRISM); @@ -2123,7 +2123,7 @@ t8_cmesh_new_prism_geometry (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); for (i = 0; i < 8; i++) { t8_cmesh_set_tree_class (cmesh, i, T8_ECLASS_PRISM); @@ -2171,7 +2171,7 @@ t8_cmesh_new_tet_orientation_test (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); /* A tet has 4 faces and each face connection has 3 possible orientations, * we thus have (4+3+2+1)*3 = 30 possible face-to-face combinations. @@ -2248,7 +2248,7 @@ t8_cmesh_new_hybrid_gate (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TET); t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_TET); t8_cmesh_set_tree_class (cmesh, 2, T8_ECLASS_PRISM); @@ -2372,7 +2372,7 @@ t8_cmesh_new_hybrid_gate_deformed (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Use linear geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TET); t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_TET); t8_cmesh_set_tree_class (cmesh, 2, T8_ECLASS_PRISM); @@ -2528,7 +2528,7 @@ t8_cmesh_new_full_hybrid (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_HEX); t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_PYRAMID); @@ -2640,7 +2640,6 @@ t8_cmesh_new_pyramid_cake (sc_MPI_Comm comm, int num_of_pyra) double *vertices = T8_ALLOC (double, num_of_pyra * 5 * 3); t8_cmesh_t cmesh; const double degrees = 360. / num_of_pyra; - int dim = t8_eclass_to_dimension[T8_ECLASS_PYRAMID]; int mpirank, mpiret; mpiret = sc_MPI_Comm_rank (comm, &mpirank); SC_CHECK_MPI (mpiret); @@ -2672,7 +2671,7 @@ t8_cmesh_new_pyramid_cake (sc_MPI_Comm comm, int num_of_pyra) t8_cmesh_set_join (cmesh, current_pyra, (current_pyra == (num_of_pyra - 1) ? 0 : current_pyra + 1), 0, 1, 0); t8_cmesh_set_tree_vertices (cmesh, current_pyra, vertices + current_pyra * 15, 5); } - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); t8_cmesh_commit (cmesh, comm); T8_FREE (vertices); @@ -2700,7 +2699,6 @@ t8_cmesh_new_long_brick_pyramid (sc_MPI_Comm comm, int num_cubes) }; /* clang-format on */ - int dim = t8_eclass_to_dimension[T8_ECLASS_PYRAMID]; mpiret = sc_MPI_Comm_rank (comm, &mpirank); SC_CHECK_MPI (mpiret); T8_ASSERT (num_cubes > 0); @@ -2756,7 +2754,7 @@ t8_cmesh_new_long_brick_pyramid (sc_MPI_Comm comm, int num_cubes) vertices_coords[current_pyra_in_current_cube * 3 + 1] += 1; } } - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); t8_cmesh_commit (cmesh, comm); return cmesh; } @@ -2768,7 +2766,7 @@ t8_cmesh_new_row_of_cubes (t8_locidx_t num_trees, const int set_attributes, cons t8_cmesh_t cmesh; t8_cmesh_init (&cmesh); - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); /* clang-format off */ /* Vertices of first cube in row. */ @@ -3126,8 +3124,8 @@ t8_cmesh_new_triangulated_spherical_surface_cube (const double radius, sc_MPI_Co const int nface_rot = 4; // Four triangles create a cube's face. const int ncube_rot = 6; // Six rotations of the four triangles to the six cube's faces. - constexpr int ntrees = nface_rot * ncube_rot; // Number of cmesh elements resp. trees. - const int nverts = 3; // Number of cmesh element (triangle) vertices. + const int ntrees = nface_rot * ncube_rot; // Number of cmesh elements resp. trees. + const int nverts = 3; // Number of cmesh element (triangle) vertices. // Arrays for the face connectivity computations via vertices. double all_verts[ntrees * T8_ECLASS_MAX_CORNERS * T8_ECLASS_MAX_DIM]; @@ -3139,7 +3137,7 @@ t8_cmesh_new_triangulated_spherical_surface_cube (const double radius, sc_MPI_Co all_eclasses[itree] = T8_ECLASS_TRIANGLE; } - constexpr double _CBRT = std::cbrt (1.0); + const double _CBRT = std::cbrt (1.0); const double r = radius / _CBRT; const double vertices[3][3] = { { -r, -r, r }, { r, -r, r }, { 0.0, 0.0, r } }; @@ -3220,7 +3218,7 @@ t8_cmesh_new_quadrangulated_spherical_surface (const double radius, sc_MPI_Comm all_eclasses[itree] = T8_ECLASS_QUAD; } - constexpr double _CBRT = std::cbrt (1.0); + const double _CBRT = std::cbrt (1.0); const double r = radius / _CBRT; const double vertices[4][3] = { { -r, -r, r }, { r, -r, r }, { -r, r, r }, { r, r, r } }; @@ -3514,7 +3512,7 @@ t8_cmesh_new_cubed_sphere (const double radius, sc_MPI_Comm comm) const double inner_radius = 0.6 * radius; const double outer_radius = radius; - constexpr double _CBRT = std::cbrt(1.0); + const double _CBRT = std::cbrt(1.0); const double inner_x = inner_radius / _CBRT; const double inner_y = inner_x; diff --git a/src/t8_cmesh/t8_cmesh_examples.h b/src/t8_cmesh/t8_cmesh_examples.h index 0a4c80f51b..c5937e347e 100644 --- a/src/t8_cmesh/t8_cmesh_examples.h +++ b/src/t8_cmesh/t8_cmesh_examples.h @@ -65,7 +65,7 @@ t8_cmesh_new_from_p8est (p8est_connectivity_t *conn, sc_MPI_Comm comm, int do_pa * this function is merely for debugging and to show the possibility. * \param [in] comm mpi communicator to be used with the new cmesh. * \param [in] do_partition Flag whether the cmesh should be partitioned or not. - * \param [in] dimension An empty cmesh requires a dimension nevertheless. 0 <= \a dimension <= 3. + * \param [in] dimension An empty cmesh requires a dimension nevertheless. 0 <= tree dimension <= 3. * \return A committed t8_cmesh structure that has no trees. */ t8_cmesh_t diff --git a/src/t8_cmesh/t8_cmesh_geometry.cxx b/src/t8_cmesh/t8_cmesh_geometry.cxx index 1fd599ea88..eca196b4bf 100644 --- a/src/t8_cmesh/t8_cmesh_geometry.cxx +++ b/src/t8_cmesh/t8_cmesh_geometry.cxx @@ -97,7 +97,7 @@ t8_cmesh_get_tree_geom_hash (const t8_cmesh_t cmesh, const t8_gloidx_t gtreeid) const size_t *hash = (const size_t *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_GEOMETRY_ATTRIBUTE_KEY, ltreeid); if (hash == nullptr) { - SC_ABORTF ("Could not find geometry for tree %ld.", gtreeid); + SC_ABORTF ("Could not find geometry for tree %ld.", static_cast (gtreeid)); } return *hash; } diff --git a/src/t8_cmesh/t8_cmesh_partition.cxx b/src/t8_cmesh/t8_cmesh_partition.cxx index 1655661496..b9de8fbc54 100644 --- a/src/t8_cmesh/t8_cmesh_partition.cxx +++ b/src/t8_cmesh/t8_cmesh_partition.cxx @@ -25,6 +25,8 @@ * TODO: document this file */ +#include + #include #include #include @@ -389,7 +391,8 @@ t8_cmesh_partition_sendrange (const t8_cmesh_t cmesh, const t8_cmesh_t cmesh_fro ret--; } - t8_debugf ("%s_first = %i, %s_last = %i, last_tree = %li\n", "send", *send_first, "send", *send_last, ret); + t8_debugf ("%s_first = %i, %s_last = %i, last_tree = %li\n", "send", *send_first, "send", *send_last, + static_cast (ret)); T8_ASSERT (*send_first >= 0); //TODO:reactivate T8_ASSERT (*send_last >= 0); @@ -1410,7 +1413,7 @@ t8_cmesh_partition_debug_listprocs (const t8_cmesh_t cmesh, const t8_cmesh_t cme } } t8_debugf ("I send to: %s\n", out); - sprintf (out, " "); + std::strcpy (out, " "); if (cmesh_from->set_partition) { for (p = 0; p < mpisize; p++) { if (t8_offset_sendsto (p, mpirank, from, to)) { @@ -1440,7 +1443,9 @@ t8_cmesh_partition_given (const t8_cmesh_t cmesh, const t8_cmesh_t cmesh_from, c size_t my_buffer_bytes = -1; char **send_buffer = NULL, *my_buffer = NULL; - int fs, ls, fr, lr; + int fs, ls; + int fr = 0; + int lr = 0; sc_MPI_Request *requests = NULL; t8_locidx_t num_ghosts, itree, num_trees; diff --git a/src/t8_cmesh/t8_cmesh_readmshfile.cxx b/src/t8_cmesh/t8_cmesh_readmshfile.cxx index de8f05b34e..a356692de2 100644 --- a/src/t8_cmesh/t8_cmesh_readmshfile.cxx +++ b/src/t8_cmesh/t8_cmesh_readmshfile.cxx @@ -179,7 +179,7 @@ t8_cmesh_check_version_of_msh_file (FILE *fp) /* Search for the line starting with "$MeshFormat". */ while (!feof (fp) && strcmp (first_word, "$MeshFormat")) { (void) t8_cmesh_msh_read_next_line (&line, &linen, fp); - retval = sscanf (line, "%2048s", first_word); + retval = sscanf (line, "%2047s", first_word); /* Checking for read/write error */ if (retval != 1) { @@ -258,7 +258,7 @@ t8_msh_file_2_read_nodes (FILE *fp, t8_locidx_t *num_nodes, sc_mempool_t **node_ while (!feof (fp) && strcmp (first_word, "$Nodes")) { (void) t8_cmesh_msh_read_next_line (&line, &linen, fp); /* Get the first word of this line */ - retval = sscanf (line, "%2048s", first_word); + retval = sscanf (line, "%2047s", first_word); /* Checking for read/write error */ if (retval != 1) { @@ -358,7 +358,7 @@ t8_msh_file_4_read_nodes (FILE *fp, t8_locidx_t *num_nodes, sc_mempool_t **node_ while (!feof (fp) && strcmp (first_word, "$Nodes")) { (void) t8_cmesh_msh_read_next_line (&line, &linen, fp); /* Get the first word of this line */ - retval = sscanf (line, "%2048s", first_word); + retval = sscanf (line, "%2047s", first_word); /* Checking for read/write error */ if (retval != 1) { t8_global_errorf ("Premature end of line while reading nodes.\n"); @@ -524,7 +524,7 @@ t8_cmesh_msh_file_2_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices, while (!feof (fp) && strcmp (first_word, "$Elements")) { (void) t8_cmesh_msh_read_next_line (&line, &linen, fp); /* Get the first word of this line */ - retval = sscanf (line, "%2048s", first_word); + retval = sscanf (line, "%2047s", first_word); /* Checking for read/write error */ if (retval != 1) { @@ -634,7 +634,7 @@ t8_cmesh_msh_file_2_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices, int switch_indices[4] = { 0 }; int iswitch; T8_ASSERT (t8_eclass_to_dimension[eclass] > 1); - t8_debugf ("Correcting negative volume of tree %li\n", tree_count); + t8_debugf ("Correcting negative volume of tree %li\n", static_cast (tree_count)); switch (eclass) { case T8_ECLASS_TRIANGLE: case T8_ECLASS_QUAD: @@ -847,7 +847,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices, while (!feof (fp) && strcmp (first_word, "$Elements")) { (void) t8_cmesh_msh_read_next_line (&line, &linen, fp); /* Get the first word of this line */ - retval = sscanf (line, "%2048s", first_word); + retval = sscanf (line, "%2047s", first_word); /* Checking for read/write error */ if (retval != 1) { @@ -973,7 +973,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices, int switch_indices[4] = { 0 }; int iswitch; T8_ASSERT (t8_eclass_to_dimension[eclass] > 1); - t8_debugf ("Correcting negative volume of tree %li\n", tree_count); + t8_debugf ("Correcting negative volume of tree %li\n", static_cast (tree_count)); switch (eclass) { case T8_ECLASS_TRIANGLE: case T8_ECLASS_QUAD: @@ -1765,15 +1765,14 @@ T8_EXTERN_C_BEGIN (); * no cad geometry is used. */ static int -t8_cmesh_from_msh_file_register_geometries (t8_cmesh_t cmesh, const int use_cad_geometry, const int dim, - const char *fileprefix, const t8_geometry_c **linear_geometry, - const t8_geometry_c **cad_geometry) +t8_cmesh_from_msh_file_register_geometries (t8_cmesh_t cmesh, const int use_cad_geometry, const char *fileprefix, + const t8_geometry_c **linear_geometry, const t8_geometry_c **cad_geometry) { /* Register linear geometry */ - *linear_geometry = t8_cmesh_register_geometry (cmesh, dim); + *linear_geometry = t8_cmesh_register_geometry (cmesh); if (use_cad_geometry) { #if T8_WITH_OCC - *cad_geometry = t8_cmesh_register_geometry (cmesh, dim, std::string (fileprefix)); + *cad_geometry = t8_cmesh_register_geometry (cmesh, std::string (fileprefix)); #else /* !T8_WITH_OCC */ *cad_geometry = NULL; return 0; @@ -1819,8 +1818,8 @@ t8_cmesh_from_msh_file (const char *fileprefix, const int partition, sc_MPI_Comm t8_cmesh_set_dimension (cmesh, dim); /* Register the geometries for the cmesh. */ - const int registered_geom_success = t8_cmesh_from_msh_file_register_geometries ( - cmesh, use_cad_geometry, dim, fileprefix, &linear_geometry, &cad_geometry); + const int registered_geom_success + = t8_cmesh_from_msh_file_register_geometries (cmesh, use_cad_geometry, fileprefix, &linear_geometry, &cad_geometry); if (!registered_geom_success) { /* Registering failed */ t8_errorf ("cad is not linked. Cannot use cad geometry.\n"); diff --git a/src/t8_cmesh/t8_cmesh_trees.c b/src/t8_cmesh/t8_cmesh_trees.cxx similarity index 85% rename from src/t8_cmesh/t8_cmesh_trees.c rename to src/t8_cmesh/t8_cmesh_trees.cxx index 8e9f06ef23..9c136c554f 100644 --- a/src/t8_cmesh/t8_cmesh_trees.c +++ b/src/t8_cmesh/t8_cmesh_trees.cxx @@ -25,6 +25,9 @@ * TODO: document this file */ +#include +#include +#include #include "t8_cmesh_stash.h" #include "t8_cmesh_trees.h" @@ -210,6 +213,46 @@ t8_cmesh_trees_start_part (const t8_cmesh_trees_t trees, const int proc, const t part->first_ghost_id = lfirst_ghost; } +/* Helper struct for sorting the number of ghost attributes by global id. + * In order to sort them, we need the part ghost id to access the global id. + * Thus, we store both the part id and the number of attributes. */ +typedef struct +{ + t8_locidx_t part_ghost_id; + t8_gloidx_t global_id; + int num_attributes; + int attribute_offset; +} t8_part_ghost_id_and_num_atts; + +/* Compare function for t8_part_ghost_id_and_num_atts to compare by global id. +* +* Return True if global_id of if_A < global_id of id_B +* Return False otherwise +* */ +bool +t8_compare_id_and_att_by_global_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_ghost_id_and_num_atts &id_B) +{ + return id_A.global_id < id_B.global_id; +} + +/* Compare function for t8_part_ghost_id_and_num_atts to compare by local id. +* +* Return True if local id of if_A < local id of id_B +* Return False otherwise +* */ +bool +t8_compare_id_and_att_by_part_id (t8_part_ghost_id_and_num_atts &id_A, t8_part_ghost_id_and_num_atts &id_B) +{ + return id_A.part_ghost_id < id_B.part_ghost_id; +} + +static std::vector +t8_cmesh_allocate_ghost_num_atts_array (t8_locidx_t part_num_ghosts) +{ + std::vector num_attributes_of_ghosts (part_num_ghosts); + return num_attributes_of_ghosts; +} + /* After all classes of trees and ghosts have been set and after the * number of tree attributes was set and their total size (per tree) * stored temporarily in the att_offset variable @@ -218,21 +261,17 @@ t8_cmesh_trees_start_part (const t8_cmesh_trees_t trees, const int proc, const t /* The workflow can be: call start_part, set tree and ghost classes maually, call * init_attributes, call finish_part, successively call add_attributes * and also set all face neighbors (TODO: write function)*/ -size_t +void t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) { t8_part_tree_t part; t8_ctree_t tree; t8_cghost_t ghost; - size_t tree_attr_bytes; - size_t ghost_attr_bytes; - size_t face_neigh_bytes; /* count the total number of bytes needed for face_neighbor information */ - size_t first_face; /* offset of the first face neighbor information */ - size_t first_tree; /* offset of the first tree */ - size_t first_ghost; /* offset of the first ghost */ - size_t temp_offset; /* offset of the currently looked at tree/ghost */ - size_t num_tree_attributes; /* total number of tree attributes */ - size_t num_ghost_attributes; /* total number of ghost attributes */ + size_t tree_attr_data_bytes; + size_t ghost_attr_data_bytes; + size_t face_neigh_bytes; /* count the total number of bytes needed for face_neighbor information */ + size_t temp_offset; /* offset of the currently looked at tree/ghost */ + size_t num_tree_attributes; /* total number of tree attributes */ t8_attribute_info_struct_t *attr; t8_locidx_t it; #ifndef SC_ENABLE_REALLOC @@ -243,16 +282,22 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) part = t8_cmesh_trees_get_part (trees, proc); T8_ASSERT (part != NULL); - num_tree_attributes = num_ghost_attributes = 0; - tree_attr_bytes = ghost_attr_bytes = face_neigh_bytes = 0; + num_tree_attributes = 0; + tree_attr_data_bytes = ghost_attr_data_bytes = face_neigh_bytes = 0; /* The offset of the first tree */ - first_tree = 0; + const size_t first_tree = 0; /* The offset of the first ghost */ - first_ghost = first_tree + part->num_trees * sizeof (t8_ctree_struct_t); + const size_t first_ghost = first_tree + part->num_trees * sizeof (t8_ctree_struct_t); /* The offset of the first ghost face */ - first_face = first_ghost + part->num_ghosts * sizeof (t8_cghost_struct_t); + const size_t first_face = first_ghost + part->num_ghosts * sizeof (t8_cghost_struct_t); + + /* First pass through ghosts to set the face neighbor offsets. */ + /* Additionally, we need to sort the number of attributes according to the global id in order + * to properly compute the attribute info offsets later. */ + + std::vector num_attributes_of_ghosts + = t8_cmesh_allocate_ghost_num_atts_array (part->num_ghosts); - /* First pass through ghosts to set the face neighbor offsets */ temp_offset = first_ghost; for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); @@ -264,7 +309,27 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) face_neigh_bytes += T8_ADD_PADDING (face_neigh_bytes); T8_ASSERT (face_neigh_bytes % T8_PADDING_SIZE == 0); temp_offset += sizeof (t8_cghost_struct_t); + + /* Add the number of attributes of this ghost to the array. */ + t8_part_ghost_id_and_num_atts &lid_and_num_atts_entry = num_attributes_of_ghosts[it]; + lid_and_num_atts_entry.part_ghost_id = it; + lid_and_num_atts_entry.num_attributes = ghost->num_attributes; + lid_and_num_atts_entry.global_id = ghost->treeid; + lid_and_num_atts_entry.attribute_offset = 0; + } + /* We now sort the array of num attributes by global id */ + std::sort (num_attributes_of_ghosts.begin (), num_attributes_of_ghosts.end (), t8_compare_id_and_att_by_global_id); + + if (part->num_ghosts > 0) { + num_attributes_of_ghosts[0].attribute_offset = 0; } + for (t8_locidx_t ighost = 1; ighost < part->num_ghosts; ++ighost) { + // Build the sum: 0 a a+b a+b+c a+b+c+d + num_attributes_of_ghosts[ighost].attribute_offset + = num_attributes_of_ghosts[ighost - 1].attribute_offset + num_attributes_of_ghosts[ighost - 1].num_attributes; + } + /* We now need to sort the offset sum by local id again. */ + std::sort (num_attributes_of_ghosts.begin (), num_attributes_of_ghosts.end (), t8_compare_id_and_att_by_part_id); /* First pass through trees to set the face neighbor offsets */ temp_offset = 0; @@ -280,41 +345,51 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) /* Second pass through trees to set attribute offsets */ temp_offset = 0; + size_t next_tree_offset = 0; // Compute the offset of the next tree for (it = 0; it < part->num_trees; it++) { tree = t8_part_tree_get_tree (part, it + part->first_tree_id); - tree_attr_bytes += tree->att_offset; /* att_offset temporarily stored the total size of the attributes */ + tree_attr_data_bytes += tree->att_offset; /* att_offset temporarily stored the total size of the attributes */ /* The att_offset of the tree is the first_face plus the number of attribute * bytes used by previous trees minus the temp_offset */ tree->att_offset = first_face - temp_offset + face_neigh_bytes + num_tree_attributes * sizeof (t8_attribute_info_struct_t); + T8_ASSERT (it == 0 || tree->att_offset == next_tree_offset); num_tree_attributes += tree->num_attributes; temp_offset += sizeof (t8_ctree_struct_t); + next_tree_offset + = tree->att_offset + tree->num_attributes * sizeof (t8_attribute_info_struct_t) - sizeof (t8_ctree_struct_t); } - tree_attr_bytes += num_tree_attributes * sizeof (t8_attribute_info_struct_t); + const size_t tree_attr_total_bytes = tree_attr_data_bytes + num_tree_attributes * sizeof (t8_attribute_info_struct_t); /* Second pass through ghosts to set attribute offsets */ - temp_offset = first_ghost; + temp_offset = 0; + size_t num_ghost_attributes = 0; /* total number of ghost attributes */ + /* To get the offset of the first ghost attribute info, we have to add the bytes + * of all tree attributes. */ + size_t first_ghost_offset = next_tree_offset + tree_attr_data_bytes; for (it = 0; it < part->num_ghosts; it++) { ghost = t8_part_tree_get_ghost (part, it + part->first_ghost_id); - ghost_attr_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ - /* The att_offset of the tree is the first_face plus the number of attribute - * bytes used by previous trees minus the temp_offset */ - ghost->att_offset = first_face - temp_offset + face_neigh_bytes + tree_attr_bytes - + num_ghost_attributes * sizeof (t8_attribute_info_struct_t); - num_ghost_attributes += ghost->num_attributes; + ghost_attr_data_bytes += ghost->att_offset; /* att_offset temporarily stored the total size of the attributes */ + /* The att_offset of the ghost is the offset of the first ghost + the attribute + * offset of this ghost minus the size of all previous ghosts. */ + ghost->att_offset = first_ghost_offset + + num_attributes_of_ghosts[it].attribute_offset * sizeof (t8_attribute_info_struct_t) + - temp_offset; temp_offset += sizeof (t8_cghost_struct_t); + num_ghost_attributes += ghost->num_attributes; } - ghost_attr_bytes += num_ghost_attributes * sizeof (t8_attribute_info_struct_t); - size_t attr_bytes = tree_attr_bytes + ghost_attr_bytes; + const size_t ghost_attr_total_bytes + = ghost_attr_data_bytes + num_ghost_attributes * sizeof (t8_attribute_info_struct_t); + const size_t attr_total_bytes = tree_attr_total_bytes + ghost_attr_total_bytes; /* Done setting all tree and ghost offsets */ - /* Allocate memory, first_face + attr_bytes + face_neigh_bytes gives the new total byte count */ + /* Allocate memory, first_face + attr_total_bytes + face_neigh_bytes gives the new total byte count */ #ifdef SC_ENABLE_REALLOC /* Since we use realloc and padding, memcmp will not work if we don't set everything to zero, solved with memset */ - SC_REALLOC (part->first_tree, char, first_face + attr_bytes + +face_neigh_bytes); - memset (part->first_tree + first_face, 0, attr_bytes + face_neigh_bytes) + SC_REALLOC (part->first_tree, char, first_face + attr_total_bytes + face_neigh_bytes); + memset (part->first_tree + first_face, 0, attr_total_bytes + face_neigh_bytes) #else - temp = T8_ALLOC_ZERO (char, first_face + attr_bytes + face_neigh_bytes); + temp = T8_ALLOC_ZERO (char, first_face + attr_total_bytes + face_neigh_bytes); memcpy (temp, part->first_tree, first_face); T8_FREE (part->first_tree); part->first_tree = temp; @@ -324,7 +399,11 @@ t8_cmesh_trees_finish_part (const t8_cmesh_trees_t trees, const int proc) attr = (t8_attribute_info_struct_t *) (part->first_tree + first_face + face_neigh_bytes); attr->attribute_offset = num_tree_attributes * sizeof (t8_attribute_info_struct_t); } - return num_ghost_attributes * sizeof (t8_attribute_info_struct_t); + if (num_ghost_attributes > 0) { + ghost = t8_part_tree_get_ghost (part, 0); + attr = (t8_attribute_info_struct_t *) (part->first_tree + first_face + face_neigh_bytes + tree_attr_total_bytes); + attr->attribute_offset = num_ghost_attributes * sizeof (t8_attribute_info_struct_t); + } } void @@ -608,7 +687,7 @@ t8_cmesh_trees_copy_toproc (t8_cmesh_trees_t trees_dest, const t8_cmesh_trees_t void t8_cmesh_trees_init_attributes (const t8_cmesh_trees_t trees, const t8_locidx_t ltree_id, const size_t num_attributes, - const size_t attr_bytes) + const size_t attr_info_bytes) { int proc; t8_ctree_t tree; @@ -619,7 +698,7 @@ t8_cmesh_trees_init_attributes (const t8_cmesh_trees_t trees, const t8_locidx_t T8_ASSERT (proc >= 0 && proc < t8_cmesh_trees_get_num_procs (trees)); tree = t8_part_tree_get_tree (t8_cmesh_trees_get_part (trees, proc), ltree_id); - tree->att_offset = attr_bytes; /* This is only temporary until t8_cmesh_trees_finish_part + tree->att_offset = attr_info_bytes; /* This is only temporary until t8_cmesh_trees_finish_part is called */ tree->num_attributes = num_attributes; } @@ -676,9 +755,9 @@ t8_cmesh_trees_add_attribute (const t8_cmesh_trees_t trees, const int proc, cons } void -t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc, - const t8_stash_attribute_struct_t *attr, const t8_locidx_t local_ghost_id, - const size_t index, size_t *attribute_data_offset) +t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const t8_stash_attribute_struct_t *attr, + const t8_locidx_t local_ghost_id, const t8_locidx_t ghosts_inserted, + const size_t index) { t8_part_tree_t part; t8_cghost_t ghost; @@ -690,11 +769,10 @@ t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc T8_ASSERT (attr->attr_data != NULL || attr->attr_size == 0); T8_ASSERT (attr->id >= 0); - part = t8_cmesh_trees_get_part (trees, proc); + part = t8_cmesh_trees_get_part (trees, 0); ghost = t8_part_tree_get_ghost (part, local_ghost_id); attr_info = T8_GHOST_ATTR_INFO (ghost, index); - attr_info->attribute_offset = *attribute_data_offset; new_attr_data = T8_GHOST_ATTR (ghost, attr_info); memcpy (new_attr_data, attr->attr_data, attr->attr_size); @@ -704,9 +782,19 @@ t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const int proc attr_info->package_id = attr->package_id; attr_info->attribute_size = attr->attr_size; - *attribute_data_offset += attr->attr_size; - if (index == (size_t) ghost->num_attributes - 1) { - *attribute_data_offset -= ghost->num_attributes * sizeof (t8_attribute_info_struct_t); + /* If we are not yet at the last attribute of the part, + * get next attribute and set its offset*/ + if (!(index == (size_t) ghost->num_attributes - 1 && part->num_ghosts == ghosts_inserted)) { + /* Store offset of current attribute */ + const size_t offset = attr_info->attribute_offset; + attr_info = attr_info + 1; + attr_info->attribute_offset = offset + attr->attr_size; + /* if the current attribute was the last attribute of the tree + * the next attribute offset must be corrected by the size of + * the attribute infos of the current tree */ + if (index == (size_t) ghost->num_attributes - 1) { + attr_info->attribute_offset -= ghost->num_attributes * sizeof (t8_attribute_info_struct_t); + } } } diff --git a/src/t8_cmesh/t8_cmesh_trees.h b/src/t8_cmesh/t8_cmesh_trees.h index 919a576bfd..60bbc74ac7 100644 --- a/src/t8_cmesh/t8_cmesh_trees.h +++ b/src/t8_cmesh/t8_cmesh_trees.h @@ -220,7 +220,7 @@ t8_cmesh_trees_start_part (t8_cmesh_trees_t trees, int proc, t8_locidx_t lfirst_ * \param [in,out] trees The trees structure to be updated. * \param [in] proc The number of the part to be finished. */ -size_t +void t8_cmesh_trees_finish_part (t8_cmesh_trees_t trees, int proc); /** Copy the tree_to_proc and ghost_to_proc arrays of one tree structure to @@ -433,9 +433,19 @@ void t8_cmesh_trees_add_attribute (const t8_cmesh_trees_t trees, int proc, const t8_stash_attribute_struct_t *attr, t8_locidx_t tree_id, size_t index); +/** Add the next ghost attribute from stash to the correct position in the char pointer structure + * Since it is created from stash, all attributes are added to part 0. + * The following attribute offset gets updated already. + * \param [in,out] trees The trees structure, whose char array is updated. + * \param [in] attr The stash attribute that is added. + * \param [in] local_ghost_id The local ghost id. + * \param [in] ghosts_inserted The number of ghost that were already inserted, so that we do not write over the end. + * \param [in] index The attribute index of the attribute to be added. +*/ + void -t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, int proc, const t8_stash_attribute_struct_t *attr, - t8_locidx_t local_ghost_id, size_t index, size_t *attribute_data_offset); +t8_cmesh_trees_add_ghost_attribute (const t8_cmesh_trees_t trees, const t8_stash_attribute_struct_t *attr, + t8_locidx_t local_ghost_id, t8_locidx_t ghosts_inserted, size_t index); /** Return the number of parts of a trees structure. * \param [in] trees The trees structure. diff --git a/src/t8_cmesh/t8_cmesh_triangle.cxx b/src/t8_cmesh/t8_cmesh_triangle.cxx index ba45711c1d..63badde55c 100644 --- a/src/t8_cmesh/t8_cmesh_triangle.cxx +++ b/src/t8_cmesh/t8_cmesh_triangle.cxx @@ -262,7 +262,7 @@ t8_cmesh_triangle_read_eles (t8_cmesh_t cmesh, int corner_offset, char *filename double temp; T8_ASSERT (dim == 3); - t8_debugf ("Correcting negative volume of tree %li\n", (long) triangle - triangle_offset); + t8_debugf ("Correcting negative volume of tree %li\n", static_cast (triangle - triangle_offset)); /* We switch vertex 0 and vertex 1 */ for (i = 0; i < 3; i++) { temp = tree_vertices[i]; @@ -531,7 +531,7 @@ t8_cmesh_from_tetgen_or_triangle_file (char *fileprefix, int partition, sc_MPI_C t8_cmesh_init (&cmesh); /* We will use linear geometry. */ - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); /* read .node file */ snprintf (current_file, BUFSIZ, "%s.node", fileprefix); retval = t8_cmesh_triangle_read_nodes (cmesh, current_file, &vertices, &num_vertices, dim); @@ -658,7 +658,7 @@ t8_cmesh_from_tetgen_or_triangle_file_time (char *fileprefix, int partition, sc_ if (cmesh != NULL) { /* Use linear geometry. * We need to set the geometry after the broadcast. */ - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_register_geometry (cmesh); if (partition) { first_tree = (mpirank * cmesh->num_trees) / mpisize; last_tree = ((mpirank + 1) * cmesh->num_trees) / mpisize - 1; diff --git a/src/t8_cmesh/t8_cmesh_types.h b/src/t8_cmesh/t8_cmesh_types.h index c1781b177e..f59f5e26c7 100644 --- a/src/t8_cmesh/t8_cmesh_types.h +++ b/src/t8_cmesh/t8_cmesh_types.h @@ -61,9 +61,9 @@ typedef struct t8_cprofile t8_cprofile_t; /* Defined below */ +T8_ECLASS_MAX_EDGES /* Used to store which face is linked to which surface */ #define T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY \ T8_CMESH_CAD_FACE_ATTRIBUTE_KEY + 1 /* Used to store face parameters */ -#define T8_CMESH_LAGRANGE_POLY_DEGREE T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + T8_ECLASS_MAX_FACES +#define T8_CMESH_LAGRANGE_POLY_DEGREE_KEY T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + T8_ECLASS_MAX_FACES #define T8_CMESH_NEXT_POSSIBLE_KEY \ - T8_CMESH_LAGRANGE_POLY_DEGREE + 1 /* The next free value for a t8code attribute key */ + T8_CMESH_LAGRANGE_POLY_DEGREE_KEY + 1 /* The next free value for a t8code attribute key */ /** This structure holds the connectivity data of the coarse mesh. * It can either be replicated, then each process stores a copy of the whole diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index 41fb758b67..0a8fb6b29e 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -4158,6 +4158,17 @@ t8_forest_new_uniform (t8_cmesh_t cmesh, t8_scheme_cxx_t *scheme, const int leve /* Initialize the forest */ t8_forest_init (&forest); + + if (cmesh->set_partition) { + t8_cmesh_t cmesh_uniform_partition; + t8_cmesh_init (&cmesh_uniform_partition); + t8_cmesh_set_derive (cmesh_uniform_partition, cmesh); + t8_scheme_cxx_ref (scheme); + t8_cmesh_set_partition_uniform (cmesh_uniform_partition, level, scheme); + t8_cmesh_commit (cmesh_uniform_partition, comm); + cmesh = cmesh_uniform_partition; + } + /* Set the cmesh, scheme and level */ t8_forest_set_cmesh (forest, cmesh, comm); t8_forest_set_scheme (forest, scheme); diff --git a/src/t8_forest/t8_forest_ghost.cxx b/src/t8_forest/t8_forest_ghost.cxx index 1f85ef452a..de868e1922 100644 --- a/src/t8_forest/t8_forest_ghost.cxx +++ b/src/t8_forest/t8_forest_ghost.cxx @@ -593,11 +593,7 @@ t8_forest_ghost_search_boundary (t8_forest_t forest, t8_locidx_t ltreeid, const /* Store the new bounds at the entry for this element */ new_bounds[iface * 2] = lower; new_bounds[iface * 2 + 1] = upper; - if (lower == upper && lower == forest->mpirank) { - /* All neighbor leaves at this face are owned by the current rank */ - faces_totally_owned = faces_totally_owned && 1; - } - else { + if (lower != upper or lower != forest->mpirank) { faces_totally_owned = 0; } } diff --git a/src/t8_forest/t8_forest_partition.cxx b/src/t8_forest/t8_forest_partition.cxx index 8826af7f3a..eb77317fa4 100644 --- a/src/t8_forest/t8_forest_partition.cxx +++ b/src/t8_forest/t8_forest_partition.cxx @@ -1044,7 +1044,7 @@ static void t8_forest_partition_recvloop (t8_forest_t forest, int recv_first, int recv_last, const int recv_data, sc_array_t *data_out, char *sent_to_self, size_t byte_to_self) { - int iproc, num_receive, prev_recvd; + int iproc, prev_recvd; t8_locidx_t last_received_local_element = 0; t8_forest_t forest_from; int mpiret; @@ -1064,7 +1064,6 @@ t8_forest_partition_recvloop (t8_forest_t forest, int recv_first, int recv_last, /* In order of their ranks, receive the trees and elements from the other processes. */ - num_receive = 0; prev_recvd = 0; if (!recv_data) { forest->local_num_elements = 0; @@ -1072,7 +1071,6 @@ t8_forest_partition_recvloop (t8_forest_t forest, int recv_first, int recv_last, for (iproc = recv_first; iproc <= recv_last; iproc++) { if (!t8_forest_partition_empty (offset_from, iproc)) { /* We receive from each nonempty rank between recv_first and recv_last */ - num_receive++; if (iproc != forest->mpirank) { /* Probe for the message */ mpiret = sc_MPI_Probe (iproc, T8_MPI_PARTITION_FOREST, comm, &status); diff --git a/src/t8_geometry/t8_geometry_base.cxx b/src/t8_geometry/t8_geometry_base.cxx index c5b55fe4d8..bb68077fd9 100644 --- a/src/t8_geometry/t8_geometry_base.cxx +++ b/src/t8_geometry/t8_geometry_base.cxx @@ -27,18 +27,6 @@ #include #include -/** Get the dimension of a geometry. - * \param [in] geom A geometry. - * \return The dimension of \a geom. - */ -int -t8_geom_get_dimension (const t8_geometry_c *geom) -{ - T8_ASSERT (geom != NULL); - - return geom->t8_geom_get_dimension (); -} - /** Get the name of a geometry. * \param [in] geom A geometry. * \return The name of \a geom. @@ -62,3 +50,25 @@ t8_geom_get_type (const t8_geometry_c *geom) return geom->t8_geom_get_type (); } + +/* Load the id and class of the newly active tree to the active_tree and active_tree_class variable. */ +void +t8_geometry::t8_geom_load_tree_data (const t8_cmesh_t cmesh, const t8_gloidx_t gtreeid) +{ + /* Set active id and eclass */ + const t8_locidx_t ltreeid = t8_cmesh_get_local_id (cmesh, gtreeid); + active_tree = gtreeid; + const t8_locidx_t num_local_trees = t8_cmesh_get_num_local_trees (cmesh); + if (0 <= ltreeid && ltreeid < num_local_trees) { + active_tree_class = t8_cmesh_get_tree_class (cmesh, ltreeid); + } + else { + active_tree_class = t8_cmesh_get_ghost_class (cmesh, ltreeid - num_local_trees); + } + + /* Check whether we support this class */ + T8_ASSERT (active_tree_class == T8_ECLASS_VERTEX || active_tree_class == T8_ECLASS_TRIANGLE + || active_tree_class == T8_ECLASS_TET || active_tree_class == T8_ECLASS_QUAD + || active_tree_class == T8_ECLASS_HEX || active_tree_class == T8_ECLASS_LINE + || active_tree_class == T8_ECLASS_PRISM || active_tree_class == T8_ECLASS_PYRAMID); +} diff --git a/src/t8_geometry/t8_geometry_base.h b/src/t8_geometry/t8_geometry_base.h index b7c665e51b..5c8f82f181 100644 --- a/src/t8_geometry/t8_geometry_base.h +++ b/src/t8_geometry/t8_geometry_base.h @@ -35,13 +35,6 @@ T8_EXTERN_C_BEGIN (); -/** Get the dimension of a geometry. - * \param [in] geom A geometry. - * \return The dimension of \a geom. - */ -int -t8_geom_get_dimension (const t8_geometry_c *geom); - /** Get the name of a geometry. * \param [in] geom A geometry. * \return The name of \a geom. diff --git a/src/t8_geometry/t8_geometry_base.hxx b/src/t8_geometry/t8_geometry_base.hxx index df848cb2e3..aa0c50e702 100644 --- a/src/t8_geometry/t8_geometry_base.hxx +++ b/src/t8_geometry/t8_geometry_base.hxx @@ -47,16 +47,15 @@ T8_EXTERN_C_BEGIN (); struct t8_geometry { public: - /* Basic constructor that sets the dimension, the name, and the name for the attribute. */ - t8_geometry (int dim, std::string name): dimension (dim), name (name), hash (std::hash {}(name)) + /* Basic constructor that sets the name. */ + t8_geometry (std::string name): name (name), hash (std::hash {}(name)) { - T8_ASSERT (0 <= dim && dim <= T8_ECLASS_MAX_DIM); } /* Base constructor with no arguments. We need this since it * is called from derived class constructors. - * Sets dimension and name to invalid values. */ - t8_geometry (): t8_geometry (-1, "Invalid") + * Sets the name to an invalid value. */ + t8_geometry (): t8_geometry ("Invalid") { } @@ -73,7 +72,7 @@ struct t8_geometry * Maps points in the reference space \f$ [0,1]^\mathrm{dim} \to \mathbb{R}^3 \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -86,7 +85,7 @@ struct t8_geometry * Compute the jacobian of the \a t8_geom_evaluate map at a point in the reference space \f$ [0,1]^\mathrm{dim} \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] glreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] jacobian The jacobian at \a ref_coords. Array of size \a num_coords x dimension x 3. Indices \f$ 3 \cdot i\f$ , \f$ 3 \cdot i+1 \f$ , \f$ 3 \cdot i+2 \f$ * correspond to the \f$ i \f$-th column of the jacobian (Entry \f$ 3 \cdot i + j \f$ is \f$ \frac{\partial f_j}{\partial x_i} \f$). @@ -98,14 +97,14 @@ struct t8_geometry /** Update a possible internal data buffer for per tree data. * This function is called before the first coordinates in a new tree are - * evaluated. You can use it for example to load the vertex coordinates of the - * tree into an internal buffer (as is done in the linear geometry). + * evaluated. + * In this base implementation we use it to load the treeid and class + * to the internal member variables \a active_tree and \a active_tree_class. * \param [in] cmesh The cmesh. * \param [in] gtreeid The global tree. */ virtual void - t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid) - = 0; + t8_geom_load_tree_data (const t8_cmesh_t cmesh, const t8_gloidx_t gtreeid); /** Query whether a batch of points lies inside an element. * \param [in] forest The forest. @@ -131,8 +130,8 @@ struct t8_geometry }; /** - * Check if the currently active tree has a negative volume - * \return True (non-zero) if the currently loaded tree has a negative volume. 0 otherwise. + * Check if the currently active tree has a negative volume. + * \return True if the currently loaded tree has a negative volume. */ virtual bool t8_geom_tree_negative_volume () const @@ -143,20 +142,21 @@ struct t8_geometry }; /** - * Get the dimension of this geometry. - * \return The dimension. + * Check for compatibility of the currently loaded tree with the geometry. + * If the geometry has limitations these can be checked here. + * This includes for example if only specific tree types or dimensions are supported. + * If all trees are supported, this function should return true. + * \return True if the geometry is compatible with the tree. */ - inline int - t8_geom_get_dimension () const - { - return dimension; - } + virtual bool + t8_geom_check_tree_compatibility () const + = 0; /** * Get the name of this geometry. * \return The name. */ - inline const std::string + inline const std::string & t8_geom_get_name () const { return name; @@ -177,14 +177,10 @@ struct t8_geometry = 0; protected: - int dimension; - /**< The dimension of reference space for which this is a geometry. */ - - std::string name; - /**< The name of this geometry. */ - - size_t hash; - /**< The hash of the name of this geometry. */ + std::string name; /**< The name of this geometry. */ + size_t hash; /**< The hash of the name of this geometry. */ + t8_gloidx_t active_tree; /**< The tree of which currently vertices are loaded. */ + t8_eclass_t active_tree_class; /**< The class of the currently active tree. */ }; T8_EXTERN_C_END (); diff --git a/src/t8_geometry/t8_geometry_handler.cxx b/src/t8_geometry/t8_geometry_handler.cxx index e22b55f2c1..130cc54fea 100644 --- a/src/t8_geometry/t8_geometry_handler.cxx +++ b/src/t8_geometry/t8_geometry_handler.cxx @@ -36,7 +36,7 @@ #include void -t8_geometry_handler::register_geometry (t8_geometry_c *geom) +t8_geometry_handler::register_geometry (t8_geometry *geom) { std::unique_ptr geom_ptr = std::unique_ptr (std::move (geom)); add_geometry (std::move (geom_ptr)); @@ -62,7 +62,7 @@ t8_geometry_handler::update_tree (t8_cmesh_t cmesh, t8_gloidx_t gtreeid) active_geometry = get_geometry (geom_hash); SC_CHECK_ABORTF (active_geometry != nullptr, "Could not find geometry with hash %zu or tree %ld has no registered geometry.", geom_hash, - gtreeid); + static_cast (gtreeid)); } /* Get the user data for this geometry and this tree. */ active_geometry->t8_geom_load_tree_data (cmesh, gtreeid); diff --git a/src/t8_geometry/t8_geometry_handler.hxx b/src/t8_geometry/t8_geometry_handler.hxx index 207c584eae..b4229c6a4b 100644 --- a/src/t8_geometry/t8_geometry_handler.hxx +++ b/src/t8_geometry/t8_geometry_handler.hxx @@ -211,6 +211,19 @@ struct t8_geometry_handler return active_geometry->t8_geom_tree_negative_volume (); } + /** + * Check for compatibility of the tree with the assigned geometry. + * \param [in] cmesh The cmesh. + * \param [in] gtreeid The global tree id of the tree to check. + * \return True if the tree and assigned geometry are compatible. + */ + inline bool + tree_compatible_with_geom (const t8_cmesh_t cmesh, const t8_gloidx_t gtreeid) + { + update_tree (cmesh, gtreeid); + return active_geometry->t8_geom_check_tree_compatibility (); + } + /** * Increase the reference count of the geometry handler. */ @@ -249,6 +262,12 @@ struct t8_geometry_handler if (registered_geometries.find (hash) == registered_geometries.end ()) { registered_geometries.emplace (hash, std::move (geom)); } + else { + t8_productionf ("WARNING: Did not register the geometry %s because it is already registered.\n" + "Geometries only need to be registered once per process.\n" + "If you are registering a new geometry it probably has the same name as another one.\n", + geom->t8_geom_get_name ().c_str ()); + } if (registered_geometries.size () == 1) { active_geometry = registered_geometries.at (hash).get (); } diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.cxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.cxx index 8ca8b98ba9..eca52eb353 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.cxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.cxx @@ -22,27 +22,28 @@ #include -t8_geometry_analytic::t8_geometry_analytic (int dim, std::string name, t8_geom_analytic_fn analytical, +t8_geometry_analytic::t8_geometry_analytic (std::string name, t8_geom_analytic_fn analytical, t8_geom_analytic_jacobian_fn jacobian_in, t8_geom_load_tree_data_fn load_tree_data_in, t8_geom_tree_negative_volume_fn tree_negative_volume_in, - const void *user_data_in) - : t8_geometry (dim, name + "_" + std::to_string (dim)) + t8_geom_tree_compatible_fn tree_compatible_in, const void *user_data_in) + : t8_geometry (name) { analytical_function = analytical; jacobian = jacobian_in; load_tree_data = load_tree_data_in; tree_negative_volume = tree_negative_volume_in; + tree_compatible = tree_compatible_in; user_data = user_data_in; } -t8_geometry_analytic::t8_geometry_analytic (int dim, std::string name) - : t8_geometry (dim, name + "_" + std::to_string (dim)) +t8_geometry_analytic::t8_geometry_analytic (std::string name): t8_geometry (name) { analytical_function = NULL; jacobian = NULL; load_tree_data = NULL; tree_negative_volume = NULL; + tree_compatible = NULL; user_data = NULL; } @@ -87,6 +88,18 @@ t8_geometry_analytic::t8_geom_tree_negative_volume () const } } +bool +t8_geometry_analytic::t8_geom_check_tree_compatibility () const +{ + if (tree_compatible != NULL) { + /* tree_compatible if a loading function was provided. */ + return tree_compatible (); + } + else { + return true; + } +} + T8_EXTERN_C_BEGIN (); void @@ -99,12 +112,13 @@ t8_geometry_analytic_destroy (t8_geometry_c **geom) } t8_geometry_c * -t8_geometry_analytic_new (int dim, const char *name, t8_geom_analytic_fn analytical, - t8_geom_analytic_jacobian_fn jacobian, t8_geom_load_tree_data_fn load_tree_data, - t8_geom_tree_negative_volume_fn tree_negative_volume, const void *user_data) +t8_geometry_analytic_new (const char *name, t8_geom_analytic_fn analytical, t8_geom_analytic_jacobian_fn jacobian, + t8_geom_load_tree_data_fn load_tree_data, + t8_geom_tree_negative_volume_fn tree_negative_volume, + t8_geom_tree_compatible_fn tree_compatible, const void *user_data) { - t8_geometry_analytic *geom - = new t8_geometry_analytic (dim, name, analytical, jacobian, load_tree_data, tree_negative_volume, user_data); + t8_geometry_analytic *geom = new t8_geometry_analytic (name, analytical, jacobian, load_tree_data, + tree_negative_volume, tree_compatible, user_data); return (t8_geometry_c *) geom; } diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.h index f846437257..8964216246 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.h +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.h @@ -47,7 +47,7 @@ typedef void (*t8_geom_analytic_fn) (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, cons * Definition for the jacobian of an analytic geometry function. * \param [in] cmesh The cmesh. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] jacobian The jacobian at \a ref_coords. Array of size \f$ \mathrm{dim} \cdot 3 \f$ x \a num_coords. Indices \f$ 3 \cdot i\f$ , \f$ 3 \cdot i+1 \f$ , \f$ 3 \cdot i+2 \f$ * correspond to the \f$ i \f$-th column of the jacobian (Entry \f$ 3 \cdot i + j \f$ is \f$ \frac{\partial f_j}{\partial x_i} \f$). @@ -71,6 +71,11 @@ typedef void (*t8_geom_load_tree_data_fn) (t8_cmesh_t cmesh, t8_gloidx_t gtreeid */ typedef int (*t8_geom_tree_negative_volume_fn) (); +/** + * Definition for the tree compatible function. + */ +typedef int (*t8_geom_tree_compatible_fn) (); + T8_EXTERN_C_BEGIN (); /** Destroy a geometry analytic object. @@ -79,19 +84,30 @@ T8_EXTERN_C_BEGIN (); void t8_geometry_analytic_destroy (t8_geometry_c **geom); -/** Create a new analytical geometry. - * \return A pointer to an allocated geometry struct. - */ +/** + * Create a new analytic geometry. The geometry + * is viable with all tree types and uses a user-provided analytic and + * jacobian function. The actual mappings are done by these functions. + * \param [in] name The name to give this geometry. + * \param [in] analytical The analytical function to use for this geometry. + * \param [in] jacobian The jacobian of \a analytical. + * \param [in] load_tree_data The function that is used to load a tree's data. + * \param [in] tree_negative_volume_in The function that is used to compute if a trees volume is negative. + * \param [in] tree_compatible_in The function that is used to check if a tree is compatible with the geometry. + * \param [in] user_data Additional user data which the geometry can use. Gets retrieved via \ref t8_geom_analytic_get_user_data. + * \return A pointer to an allocated geometry struct. + */ t8_geometry_c * -t8_geometry_analytic_new (int dim, const char *name, t8_geom_analytic_fn analytical, - t8_geom_analytic_jacobian_fn jacobian, t8_geom_load_tree_data_fn load_tree_data, - t8_geom_tree_negative_volume_fn tree_negative_volume, const void *user_data); +t8_geometry_analytic_new (const char *name, t8_geom_analytic_fn analytical, t8_geom_analytic_jacobian_fn jacobian, + t8_geom_load_tree_data_fn load_tree_data, + t8_geom_tree_negative_volume_fn tree_negative_volume, + t8_geom_tree_compatible_fn tree_compatible, const void *user_data); /** * Load vertex data from given tree. * \param [in] cmesh The cmesh. * \param [in] gtreeid The global tree id (in the cmesh). - * \param [out] vertex_out The load tree vertices. + * \param [out] user_data The load tree vertices. */ void t8_geom_load_tree_data_vertices (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const void **user_data); diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.hxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.hxx index 53331b82d9..3ed3701ce5 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.hxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.hxx @@ -38,25 +38,26 @@ struct t8_geometry_analytic: public t8_geometry { public: /** - * Constructor of the analytic geometry with a given dimension. The geometry + * Constructor of the analytic geometry. The geometry * is viable with all tree types and uses a user-provided analytic and * jacobian function. The actual mappings are done by these functions. - * \param [in] dim The dimension of this geometry. * \param [in] name The name to give this geometry. * \param [in] analytical The analytical function to use for this geometry. * \param [in] jacobian The jacobian of \a analytical. * \param [in] load_tree_data The function that is used to load a tree's data. + * \param [in] tree_negative_volume_in The function that is used to compute if a trees volume is negative. + * \param [in] tree_compatible_in The function that is used to check if a tree is compatible with the geometry. */ - t8_geometry_analytic (int dim, std::string name, t8_geom_analytic_fn analytical, - t8_geom_analytic_jacobian_fn jacobian, t8_geom_load_tree_data_fn load_tree_data, - t8_geom_tree_negative_volume_fn tree_negative_volume_in, const void *user_data); + t8_geometry_analytic (std::string name, t8_geom_analytic_fn analytical, t8_geom_analytic_jacobian_fn jacobian, + t8_geom_load_tree_data_fn load_tree_data, + t8_geom_tree_negative_volume_fn tree_negative_volume_in, + t8_geom_tree_compatible_fn tree_compatible_in, const void *user_data); /** * Constructor of the analytic geometry for testing purposes. - * \param [in] dim The dimension of this geometry. * \param [in] name The name to give this geometry. */ - t8_geometry_analytic (int dim, std::string name); + t8_geometry_analytic (std::string name); /** The destructor. */ @@ -70,7 +71,7 @@ struct t8_geometry_analytic: public t8_geometry * \return The type. */ inline t8_geometry_type_t - t8_geom_get_type () const + t8_geom_get_type () const override { return T8_GEOMETRY_TYPE_ANALYTIC; }; @@ -79,19 +80,19 @@ struct t8_geometry_analytic: public t8_geometry * Maps points in the reference space \f$ [0,1]^\mathrm{dim} \to \mathbb{R}^3 \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ - virtual void + void t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords, - double *out_coords) const; + double *out_coords) const override; /** * Compute the jacobian of the \a t8_geom_evaluate map at a point in the reference space \f$ [0,1]^\mathrm{dim} \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] jacobian The jacobian at \a ref_coords. Array of size \f$ \mathrm{dim} \cdot 3 \f$ x \a num_coords. Indices \f$ 3 \cdot i\f$ , \f$ 3 \cdot i+1 \f$ , \f$ 3 \cdot i+2 \f$ * correspond to the \f$ i \f$-th column of the jacobian (Entry \f$ 3 \cdot i + j \f$ is \f$ \frac{\partial f_j}{\partial x_i} \f$). @@ -100,9 +101,9 @@ struct t8_geometry_analytic: public t8_geometry * dim 1: J = (0) dim 2: J = (0 1) dim 3: J = (0 1 0) * (0) (0 0) (0 0 1) */ - virtual void + void t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords, - double *jacobian) const; + double *jacobian) const override; /** * \param[in] forest The forest of the element. @@ -113,10 +114,10 @@ struct t8_geometry_analytic: public t8_geometry * \param[in, out] is_inside Array to fill with flags whether the point is inside or not * \param[in] tolerance Tolerance of the inside-check */ - virtual void + void t8_geom_point_batch_inside_element (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element, const double *points, const int num_points, int *is_inside, - const double tolerance) + const double tolerance) const override { SC_ABORTF ("Function not yet implemented"); } @@ -125,8 +126,18 @@ struct t8_geometry_analytic: public t8_geometry * Check if the currently active tree has a negative volume * \return True (non-zero) if the currently loaded tree has a negative volume. 0 otherwise. */ - virtual bool - t8_geom_tree_negative_volume () const; + bool + t8_geom_tree_negative_volume () const override; + + /** + * Check for compatibility of the currently loaded tree with the geometry. + * If the geometry has limitations these can be checked here. + * This includes for example if only specific tree types or dimensions are supported. + * If all trees are supported, this function should return true. + * \return True if the geometry is compatible with the tree. + */ + bool + t8_geom_check_tree_compatibility () const; /** Update a possible internal data buffer for per tree data. * This function is called before the first coordinates in a new tree are @@ -135,8 +146,8 @@ struct t8_geometry_analytic: public t8_geometry * \param [in] cmesh The cmesh. * \param [in] gtreeid The global tree. */ - virtual void - t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid); + void + t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid) override; inline const void * t8_geom_analytic_get_user_data () @@ -153,11 +164,13 @@ struct t8_geometry_analytic: public t8_geometry t8_geom_tree_negative_volume_fn tree_negative_volume; /**< The function to check for negative volumes. */ + t8_geom_tree_compatible_fn tree_compatible; /**< The function to check if a tree is compatible. */ + const void *tree_data; /** Tree data pointer that can be set in \a load_tree_data and - is passed onto \a analytical_function and \a jacobian. */ + is passed onto \a analytical_function and \a jacobian. */ const void *user_data; /** Additional user data pointer that can be set in constructor - * and modified via \ref t8_geom_analytic_get_user_data. */ + and modified via \ref t8_geom_analytic_get_user_data. */ }; #endif /* !T8_GEOMETRY_ANALYTICAL_HXX */ diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx index bc982865f1..615e8fe259 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx @@ -50,8 +50,7 @@ const int t8_interpolation_coefficient_tet_edge[6] = { 0, 0, 0, 2, 2, 1 }; * For example: face 0 is described by coordinates z and y. */ const int t8_face_ref_coords_tet[4][2] = { { 2, 1 }, { 0, 1 }, { 0, 1 }, { 0, 2 } }; -t8_geometry_cad::t8_geometry_cad (int dim, std::string fileprefix, std::string name_in) - : t8_geometry_with_vertices (dim, name_in + "_" + std::to_string (dim)) +t8_geometry_cad::t8_geometry_cad (std::string fileprefix, std::string name_in): t8_geometry_with_vertices (name_in) { BRep_Builder builder; std::string current_file (fileprefix); @@ -74,8 +73,8 @@ t8_geometry_cad::t8_geometry_cad (int dim, std::string fileprefix, std::string n TopExp::MapShapesAndUniqueAncestors (cad_shape, TopAbs_EDGE, TopAbs_FACE, cad_shape_edge2face_map); } -t8_geometry_cad::t8_geometry_cad (int dim, const TopoDS_Shape cad_shape, std::string name_in) - : t8_geometry_with_vertices (dim, name_in + "_" + std::to_string (dim)) +t8_geometry_cad::t8_geometry_cad (const TopoDS_Shape cad_shape, std::string name_in) + : t8_geometry_with_vertices (name_in) { if (cad_shape.IsNull ()) { SC_ABORTF ("Shape is null. \n"); @@ -87,7 +86,7 @@ t8_geometry_cad::t8_geometry_cad (int dim, const TopoDS_Shape cad_shape, std::st TopExp::MapShapesAndUniqueAncestors (cad_shape, TopAbs_EDGE, TopAbs_FACE, cad_shape_edge2face_map); } -t8_geometry_cad::t8_geometry_cad (int dim): t8_geometry_with_vertices (dim, "t8_geom_cad_" + std::to_string (dim)) +t8_geometry_cad::t8_geometry_cad (): t8_geometry_with_vertices ("t8_geom_cad") { cad_shape.Nullify (); } @@ -1634,11 +1633,11 @@ t8_geometry_cad::t8_geom_is_surface_closed (int geometry_index, int parameter) c T8_EXTERN_C_BEGIN (); /* Satisfy the C interface from t8_geometry_cad.h. - * Create a new geometry with given dimension. */ + * Create a new geometry. */ t8_geometry_cad_c * -t8_geometry_cad_new (int dimension, const char *fileprefix, const char *name_in) +t8_geometry_cad_new (const char *fileprefix, const char *name_in) { - t8_geometry_cad *geom = new t8_geometry_cad (dimension, fileprefix, name_in); + t8_geometry_cad *geom = new t8_geometry_cad (fileprefix, name_in); return (t8_geometry_cad_c *) geom; } diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.h index dfa5901362..2779c10705 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.h +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.h @@ -49,16 +49,15 @@ T8_EXTERN_C_BEGIN (); * The vertices are saved via the \ref t8_cmesh_set_tree_vertices function. * Since the internals of this geometry are finely tuned to the .brep file * it is recommended to only use it with the \ref t8_cmesh_readmshfile function. - * \param [in] dim 0 <= \a dimension <= 3. The dimension. + * \param [in] dim 0 <= tree dimension <= 3. The dimension. * \param [in] fileprefix Prefix of a .brep file from which to extract an cad geometry. * \param [in] name The name to give this geometry. * \return A pointer to an allocated t8_geometry_cad struct, as - * if the \ref t8_geometry_cad (int dim, const *char fileprefix, - * const char *name) + * if the \ref t8_geometry_cad (std::string fileprefix, std::string name) * constructor was called. */ t8_geometry_cad_c * -t8_geometry_cad_new (int dim, const char *fileprefix, const char *name_in); +t8_geometry_cad_new (const char *fileprefix, const char *name_in); /** Destroy a cad geometry that was created with \ref t8_geometry_cad_new. * \param [in,out] geom A cad geometry. Set to NULL on output. diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx index 44c4b8fb18..915485f835 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx @@ -50,39 +50,36 @@ struct t8_geometry_cad: public t8_geometry_with_vertices { public: /** - * Constructor of the cad geometry with a given dimension. The geometry + * Constructor of the cad geometry. The geometry * is currently viable with quad/hex and triangle trees. Tets will be supported soon. * The geometry uses as many vertices as the tree type has, as well as * additional geometry information, which is extracted from a .brep file. * The vertices are saved via the \ref t8_cmesh_set_tree_vertices function. * Since the internals of this geometry are finely tuned to the .brep file * it is recommended to only use it with the \ref t8_cmesh_readmshfile function. - * \param [in] dim The dimension of this geometry. * \param [in] fileprefix Prefix of a .brep file from which to extract an cad geometry. * \param [in] name The name to give this geometry. */ - t8_geometry_cad (int dim, std::string fileprefix, std::string name = "t8_geom_cad"); + t8_geometry_cad (std::string fileprefix, std::string name = "t8_geom_cad"); /** - * Constructor of the cad geometry with a given dimension. The geometry + * Constructor of the cad geometry. The geometry * is currently viable with quad/hex and triangle trees. Tets will be supported soon. * The geometry uses as many vertices as the tree type has, as well as * additional geometry information, which is given via the \a cad_shape. * The vertices are saved via the \ref t8_cmesh_set_tree_vertices function. * This constructor can be used in short scripts or in combination with a * mesh generator, to omit the file IO of the - * \ref t8_geometry_cad (int dim, std::string fileprefix, std::string name) constructor. - * \param [in] dim The dimension of this geometry. + * \ref t8_geometry_cad (std::string fileprefix, std::string name) constructor. * \param [in] cad_shape cad shape geometry. * \param [in] name The name to give this geometry. */ - t8_geometry_cad (int dim, const TopoDS_Shape cad_shape, std::string name = "t8_geom_cad"); + t8_geometry_cad (const TopoDS_Shape cad_shape, std::string name = "t8_geom_cad"); /** * Constructor of the cad geometry for testing purposes. Sets an invalid cad_shape. - * \param [in] dim The dimension of this geometry. */ - t8_geometry_cad (int dim); + t8_geometry_cad (); /** The destructor. */ virtual ~t8_geometry_cad () @@ -104,7 +101,7 @@ struct t8_geometry_cad: public t8_geometry_with_vertices * Maps points in the reference space \f$ [0,1]^\mathrm{dim} \to \mathbb{R}^3 \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -116,7 +113,7 @@ struct t8_geometry_cad: public t8_geometry_with_vertices * Compute the jacobian of the \a t8_geom_evaluate map at a point in the reference space \f$ [0,1]^\mathrm{dim} \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] jacobian The jacobian at \a ref_coords. Array of size \a num_coords x dimension x 3. Indices \f$ 3 \cdot i\f$ , \f$ 3 \cdot i+1 \f$ , \f$ 3 \cdot i+2 \f$ * correspond to the \f$ i \f$-th column of the jacobian (Entry \f$ 3 \cdot i + j \f$ is \f$ \frac{\partial f_j}{\partial x_i} \f$). @@ -135,6 +132,17 @@ struct t8_geometry_cad: public t8_geometry_with_vertices virtual void t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid); + /** + * Check for compatibility of the currently loaded tree with the geometry. + * This geometry supports all element types, hence it returns true. + * \return True if the geometry is compatible with the tree. + */ + bool + t8_geom_check_tree_compatibility () const + { + return true; + } + /** Check if a cad_curve is a line. * \param [in] curve_index The index of the cad_curve. * \return 1 if curve is a line, 0 if curve is not a line. @@ -312,7 +320,7 @@ struct t8_geometry_cad: public t8_geometry_with_vertices * Maps points in the reference space \f$ [0,1]^2 \f$ to \f$ \mathbb{R}^3 \f$. Only for quad trees. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -324,7 +332,7 @@ struct t8_geometry_cad: public t8_geometry_with_vertices * Map a point in the reference space $$[0,1]^3$$ to $$\mathbb R^3$$. Only for tet trees. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords The number of points to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. */ @@ -336,7 +344,7 @@ struct t8_geometry_cad: public t8_geometry_with_vertices * Map a point in the reference space \f$ \f$ [0,1]^3 \f$ \f$ to \f$ \mathbb{R}^3 \f$. Only for hex trees. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -348,7 +356,7 @@ struct t8_geometry_cad: public t8_geometry_with_vertices * Maps points in the reference space \f$ \f$ [0,1]^3 \f$ \f$ to \f$ \mathbb{R}^3 \f$. Only for prism trees. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.cxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.cxx index 31672c465d..04fcadf40f 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.cxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.cxx @@ -20,6 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include #include #include #include @@ -211,7 +212,7 @@ t8_geometry_cubed_spherical_shell::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx const double distance = std::abs (t8_vec_dot (active_tree_vertices, normal)); // Compute actual radius of the sphere. - constexpr double CBRT = std::cbrt (1.0); + const double CBRT = std::cbrt (1.0); const double inner_radius = distance * CBRT; const double shell_thickness = std::abs (t8_vec_dot (active_tree_vertices + t8_eclass_num_vertices[active_tree_class] * 3 / 2, normal)) * CBRT diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.hxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.hxx index 07eb2d08a0..34aa2e98c4 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.hxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.hxx @@ -36,7 +36,7 @@ struct t8_geometry_quadrangulated_disk: public t8_geometry_with_vertices { public: /* Basic constructor that sets the dimension and the name. */ - t8_geometry_quadrangulated_disk (): t8_geometry_with_vertices (2, "t8_quadrangulated_disk_") + t8_geometry_quadrangulated_disk (): t8_geometry_with_vertices ("t8_quadrangulated_disk_") { } @@ -44,7 +44,7 @@ struct t8_geometry_quadrangulated_disk: public t8_geometry_with_vertices * Map five quads to a disk. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords The number of points to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. * @@ -110,7 +110,7 @@ struct t8_geometry_triangulated_spherical_surface: public t8_geometry_with_verti { public: /* Basic constructor that sets the dimension and the name. */ - t8_geometry_triangulated_spherical_surface (): t8_geometry_with_vertices (2, "t8_triangulated_spherical_surface_") + t8_geometry_triangulated_spherical_surface (): t8_geometry_with_vertices ("t8_triangulated_spherical_surface_") { } @@ -123,7 +123,7 @@ struct t8_geometry_triangulated_spherical_surface: public t8_geometry_with_verti * Map the faces of an octahedron/icosahedron to a spherical surface. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords The number of points to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. * @@ -169,7 +169,7 @@ struct t8_geometry_tessellated_spherical_surface: public t8_geometry_with_vertic { public: /* Basic constructor that sets the dimension and the name. */ - t8_geometry_tessellated_spherical_surface (): t8_geometry_with_vertices (2, "t8_tessellated_spherical_surface_") + t8_geometry_tessellated_spherical_surface (): t8_geometry_with_vertices ("t8_tessellated_spherical_surface") { } @@ -182,7 +182,7 @@ struct t8_geometry_tessellated_spherical_surface: public t8_geometry_with_vertic * Map the faces of a cube to a spherical surface. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords The number of points to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. * @@ -227,7 +227,7 @@ struct t8_geometry_cubed_spherical_shell: public t8_geometry_with_vertices { public: /* Basic constructor that sets the dimension and the name. */ - t8_geometry_cubed_spherical_shell (): t8_geometry_with_vertices (3, "t8_cubed_spherical_shell_") + t8_geometry_cubed_spherical_shell (): t8_geometry_with_vertices ("t8_cubed_spherical_shell_") { } @@ -240,7 +240,7 @@ struct t8_geometry_cubed_spherical_shell: public t8_geometry_with_vertices * Map the faces of a cube to a spherical surface. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords The number of points to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. * @@ -285,7 +285,7 @@ struct t8_geometry_prismed_spherical_shell: public t8_geometry_with_vertices { public: /* Basic constructor that sets the dimension and the name. */ - t8_geometry_prismed_spherical_shell (): t8_geometry_with_vertices (3, "t8_prismed_spherical_shell") + t8_geometry_prismed_spherical_shell (): t8_geometry_with_vertices ("t8_prismed_spherical_shell") { } @@ -298,7 +298,7 @@ struct t8_geometry_prismed_spherical_shell: public t8_geometry_with_vertices * Map prism arranged as octahedron (or similar) to a spherical shell. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords The number of points to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. * @@ -343,7 +343,7 @@ struct t8_geometry_cubed_sphere: public t8_geometry_with_vertices { public: /* Basic constructor that sets the dimension and the name. */ - t8_geometry_cubed_sphere (): t8_geometry_with_vertices (3, "t8_geometry_cubed_sphere") + t8_geometry_cubed_sphere (): t8_geometry_with_vertices ("t8_geometry_cubed_sphere") { } @@ -356,7 +356,7 @@ struct t8_geometry_cubed_sphere: public t8_geometry_with_vertices * Maps specifically arranged hexahedrons to a sphere. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords The number of points to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. * diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.cxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.cxx index f151a90ee5..078f5a6284 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.cxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.cxx @@ -32,8 +32,7 @@ #include #include -t8_geometry_lagrange::t8_geometry_lagrange (int dim) - : t8_geometry_with_vertices (dim, "t8_geom_lagrange_" + std::to_string (dim)) +t8_geometry_lagrange::t8_geometry_lagrange (): t8_geometry_with_vertices ("t8_geom_lagrange") { } @@ -47,6 +46,7 @@ t8_geometry_lagrange::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, c { if (num_points != 1) SC_ABORT ("Error: Batch computation of geometry not yet supported."); + T8_ASSERT (t8_geom_check_tree_compatibility ()); const auto basis_functions = t8_geometry_lagrange::t8_geom_compute_basis (ref_coords); const size_t n_vertex = basis_functions.size (); for (size_t i_component = 0; i_component < T8_ECLASS_MAX_DIM; i_component++) { @@ -71,8 +71,9 @@ inline void t8_geometry_lagrange::t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid) { t8_geometry_with_vertices::t8_geom_load_tree_data (cmesh, gtreeid); - t8_locidx_t ltreeid = t8_cmesh_get_local_id (cmesh, gtreeid); - degree = (const int *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE, ltreeid); + const t8_locidx_t ltreeid = t8_cmesh_get_local_id (cmesh, gtreeid); + degree + = (const int *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE_KEY, ltreeid); T8_ASSERT (degree != NULL); } @@ -114,6 +115,25 @@ t8_geometry_lagrange::t8_geom_compute_basis (const double *ref_coords) const } } +bool +t8_geometry_lagrange::t8_geom_check_tree_compatibility () const +{ + if (*degree > T8_GEOMETRY_MAX_POLYNOMIAL_DEGREE) { + t8_debugf ("Lagrange tree with degree %i detected.\n" + "Only degrees up to %i are supported.", + *degree, T8_GEOMETRY_MAX_POLYNOMIAL_DEGREE); + return false; + } + if (active_tree_class != T8_ECLASS_LINE && active_tree_class != T8_ECLASS_TRIANGLE + && active_tree_class != T8_ECLASS_QUAD && active_tree_class != T8_ECLASS_HEX) { + t8_debugf ("Lagrange tree with class %i detected.\n" + "Only lines, triangles, quadrilaterals and hexahedra are supported with the lagrangian geometry.\n", + active_tree_class); + return false; + } + return true; +} + inline std::vector t8_geometry_lagrange::t8_geom_s2_basis (const double *ref_point) const { @@ -270,10 +290,9 @@ t8_lagrange_element::t8_lagrange_element (t8_eclass_t eclass, uint32_t degree, s // if (nodes.size () != parametric_nodes.size ()) // SC_ABORTF ("Provide the 3 coordinates of the nodes.\n"); /* Create a cmesh with a single element */ - int dim = t8_eclass_to_dimension[eclass]; t8_cmesh_init (&cmesh); - t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE, °ree, sizeof (int), 1); - t8_cmesh_register_geometry (cmesh, dim); + t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE_KEY, °ree, sizeof (int), 1); + t8_cmesh_register_geometry (cmesh); t8_cmesh_set_tree_class (cmesh, 0, eclass); t8_cmesh_set_tree_vertices (cmesh, 0, nodes.data (), nodes.size ()); t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); @@ -501,11 +520,11 @@ t8_lagrange_element::write () const T8_EXTERN_C_BEGIN (); /* Satisfy the C interface from t8_geometry_lagrange.h. - * Create a new geometry with given dimension. */ + * Create a new geometry. */ t8_geometry_c * -t8_geometry_lagrange_new (int dimension) +t8_geometry_lagrange_new () { - t8_geometry_lagrange *geom = new t8_geometry_lagrange (dimension); + t8_geometry_lagrange *geom = new t8_geometry_lagrange (); return (t8_geometry_c *) geom; } diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.h index 68e504a2d0..82defbb343 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.h +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.h @@ -39,13 +39,12 @@ T8_EXTERN_C_BEGIN (); * The geometry is compatible with all tree types and uses as many vertices * as the number of Lagrange basis functions used for the mapping. * The vertices are saved via the \ref t8_cmesh_set_tree_vertices function. - * Sets the dimension and the name to "t8_geom_lagrange_{dim}" - * \param [in] dim 0 <= \a dimension <= 3. The dimension. + * Sets the name to "t8_geom_lagrange" * \return A pointer to an allocated t8_geometry_lagrange struct, as - * if the \ref t8_geometry_lagrange (int dim) constructor was called. + * if the \ref t8_geometry_lagrange () constructor was called. */ t8_geometry_c * -t8_geometry_lagrange_new (int dim); +t8_geometry_lagrange_new (); /** Destroy a Lagrange geometry that was created with \ref t8_geometry_lagrange_new. * \param [in,out] geom A Lagrange geometry. Set to NULL on output. diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.hxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.hxx index 3c3bbb4cff..c81f8742ec 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.hxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_lagrange.hxx @@ -81,17 +81,8 @@ struct t8_geometry_lagrange: public t8_geometry_with_vertices * is compatible with all tree types and uses as many vertices as the number of Lagrange * basis functions used for the mapping. * The vertices are saved via the \ref t8_cmesh_set_tree_vertices function. - * \param [in] dim 0 <= \a dim <= 3. Element dimension in the parametric space. - * E.g. \a dim = 2 for a \ref T8_ECLASS_QUAD element. */ - t8_geometry_lagrange (int dim); - - /* Base constructor with no arguments. We need this since it - * is called from derived class constructors. - * Sets dimension and name to invalid values. */ - t8_geometry_lagrange (): t8_geometry_with_vertices () - { - } + t8_geometry_lagrange (); virtual ~t8_geometry_lagrange (); @@ -122,7 +113,7 @@ struct t8_geometry_lagrange: public t8_geometry_with_vertices * * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_points entries, specifying points in the reference space. + * \param [in] ref_coords Array of tree dimension x \a num_points entries, specifying points in the reference space. * \param [in] num_points Number of points to map. Currently, only one point is supported. * \param [out] out_coords Coordinates of the mapped points in physical space of \a ref_coords. The length is \a num_points * 3. */ @@ -134,7 +125,7 @@ struct t8_geometry_lagrange: public t8_geometry_with_vertices * Compute the Jacobian of the \a t8_geom_evaluate map at a point in the reference space. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_points entries, specifying points in the reference space. + * \param [in] ref_coords Array of tree dimension x \a num_points entries, specifying points in the reference space. * \param [in] num_points Number of points to map. * \param [out] jacobian The Jacobian at \a ref_coords. Array of size \a num_points x dimension x 3. Indices \f$ 3 \cdot i\f$ , \f$ 3 \cdot i+1 \f$ , \f$ 3 \cdot i+2 \f$ * correspond to the \f$ i \f$-th column of the Jacobian (Entry \f$ 3 \cdot i + j \f$ is \f$ \frac{\partial f_j}{\partial x_i} \f$). @@ -153,10 +144,18 @@ struct t8_geometry_lagrange: public t8_geometry_with_vertices virtual void t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid); + /** + * Check for compatibility of the currently loaded tree with the geometry. + * This geometry supports lines, triangles, quadrilaterals and hexahedra up to degree 2. + * \return True if the geometry is compatible with the tree. + */ + bool + t8_geom_check_tree_compatibility () const; + private: /** * Evaluates the basis functions of the current tree type at a point. - * \param [in] ref_point Array of \a dimension entries, specifying the point in the reference space. + * \param [in] ref_point Array of tree dimension entries, specifying the point in the reference space. */ inline std::vector t8_geom_compute_basis (const double *ref_point) const; diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.cxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.cxx index b03e54a8f3..c64112da76 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.cxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.cxx @@ -26,8 +26,7 @@ #include #include -t8_geometry_linear::t8_geometry_linear (int dim) - : t8_geometry_with_vertices (dim, "t8_geom_linear_" + std::to_string (dim)) +t8_geometry_linear::t8_geometry_linear (): t8_geometry_with_vertices ("t8_geom_linear") { } @@ -242,11 +241,11 @@ t8_geometry_linear::t8_geom_point_batch_inside_element (t8_forest_t forest, t8_l T8_EXTERN_C_BEGIN (); /* Satisfy the C interface from t8_geometry_linear.h. - * Create a new geometry with given dimension. */ + * Create a new geometry. */ t8_geometry_c * -t8_geometry_linear_new (int dimension) +t8_geometry_linear_new () { - t8_geometry_linear *geom = new t8_geometry_linear (dimension); + t8_geometry_linear *geom = new t8_geometry_linear (); return (t8_geometry_c *) geom; } diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.h index f7da1de826..d91709babc 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.h +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.h @@ -34,16 +34,15 @@ T8_EXTERN_C_BEGIN (); /** - * Create a new linear geometry of a given dimension. + * Create a new linear geometry. * The geometry is only all tree types and as many vertices as the tree type * has. The vertices are saved via the \ref t8_cmesh_set_tree_vertices function. - * Sets the dimension and the name to "t8_geom_linear_{dim}" - * \param [in] dim 0 <= \a dimension <= 3. The dimension. + * Sets the dimension and the name to "t8_geom_linear" * \return A pointer to an allocated t8_geometry_linear struct, as - * if the \ref t8_geometry_linear (int dim) constructor was called. + * if the \ref t8_geometry_linear () constructor was called. */ t8_geometry_c * -t8_geometry_linear_new (int dim); +t8_geometry_linear_new (); /** Destroy a linear geometry that was created with \ref t8_geometry_linear_new. * \param [in,out] geom A linear geometry. Set to NULL on output. diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx index 0141f731a8..a5a1f16a8a 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx @@ -35,20 +35,12 @@ struct t8_geometry_linear: public t8_geometry_with_vertices { public: /** - * Constructor of the linear geometry with a given dimension. The geometry + * Constructor of the linear geometry. The geometry * is viable with all tree types and uses as many vertices as the tree type has. * The vertices are saved via the \ref t8_cmesh_set_tree_vertices function. - * Sets the dimension and the name to "t8_geom_linear_{dim}" - * \param [in] dim 0 <= \a dimension <= 3. The dimension. + * Sets the dimension and the name to "t8_geom_linear" */ - t8_geometry_linear (int dim); - - /* Base constructor with no arguments. We need this since it - * is called from derived class constructors. - * Sets dimension and name to invalid values. */ - t8_geometry_linear (): t8_geometry_with_vertices () - { - } + t8_geometry_linear (); /** The destructor. * Clears the allocated memory. @@ -69,7 +61,7 @@ struct t8_geometry_linear: public t8_geometry_with_vertices * Maps points in the reference space \f$ [0,1]^\mathrm{dim} \to \mathbb{R}^3 \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -81,7 +73,7 @@ struct t8_geometry_linear: public t8_geometry_with_vertices * Compute the jacobian of the \a t8_geom_evaluate map at a point in the reference space \f$ [0,1]^\mathrm{dim} \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] jacobian The jacobian at \a ref_coords. Array of size \a num_coords x dimension x 3. Indices \f$ 3 \cdot i\f$ , \f$ 3 \cdot i+1 \f$ , \f$ 3 \cdot i+2 \f$ * correspond to the \f$ i \f$-th column of the jacobian (Entry \f$ 3 \cdot i + j \f$ is \f$ \frac{\partial f_j}{\partial x_i} \f$). @@ -104,6 +96,17 @@ struct t8_geometry_linear: public t8_geometry_with_vertices const double *points, const int num_points, int *is_inside, const double tolerance) const; + /** + * Check for compatibility of the currently loaded tree with the geometry. + * This geometry supports all element types, hence it returns true. + * \return True if the geometry is compatible with the tree. + */ + bool + t8_geom_check_tree_compatibility () const + { + return true; + } + /* Load tree data is inherited from t8_geometry_with_vertices. */ }; diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.cxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.cxx index 7bc59636e7..394169f390 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.cxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.cxx @@ -42,8 +42,8 @@ correct_point_order (const double tree_vertices[6]) } #endif -t8_geometry_linear_axis_aligned::t8_geometry_linear_axis_aligned (int dim) - : t8_geometry_with_vertices (dim, "t8_geom_linear_axis_aligned_" + std::to_string (dim)) +t8_geometry_linear_axis_aligned::t8_geometry_linear_axis_aligned () + : t8_geometry_with_vertices ("t8_geom_linear_axis_aligned") { } @@ -115,9 +115,9 @@ T8_EXTERN_C_BEGIN (); /* Satisfy the C interface from t8_geometry_linear_axis_aligned.h. * Create a new geometry with given dimension. */ t8_geometry_c * -t8_geometry_linear_axis_aligned_new (int dimension) +t8_geometry_linear_axis_aligned_new () { - t8_geometry_linear_axis_aligned *geom = new t8_geometry_linear_axis_aligned (dimension); + t8_geometry_linear_axis_aligned *geom = new t8_geometry_linear_axis_aligned (); return (t8_geometry_c *) geom; } diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.h index 2e6b16fdd8..fc2c140732 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.h +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.h @@ -39,13 +39,12 @@ T8_EXTERN_C_BEGIN (); * The geometry is only viable for line/quad/hex elements and uses two * vertices (min and max coords) per tree. The vertices are saved via * the \ref t8_cmesh_set_tree_vertices function. - * \param [in] dim 0 <= \a dimension <= 3. The dimension. * \return A pointer to an allocated t8_geometry_linear_axis_aligned - * struct, as if the t8_geometry_linear_axis_aligned - * (int dimension) constructor was called. + * struct, as if the t8_geometry_linear_axis_aligned () + * constructor was called. */ t8_geometry_c * -t8_geometry_linear_axis_aligned_new (int dim); +t8_geometry_linear_axis_aligned_new (); /** Destroy a linear, axis-aligned geometry that was created with * \ref t8_geometry_linear_axis_aligned_new. diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.hxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.hxx index b5eae50f1d..729759ca1f 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.hxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.hxx @@ -39,19 +39,10 @@ struct t8_geometry_linear_axis_aligned: public t8_geometry_with_vertices * Constructor of the linear, axis-aligned geometry with a given dimension. * The geometry is only viable for the line/quad/hex tree types and uses two * vertices (min and max coords) per tree. The vertices are saved via - * the \ref t8_cmesh_set_tree_vertices function. Sets the dimension and the - * name to "t8_geom_linear_axis_aligned_{dim}" - * \param [in] dim 0 <= \a dimension <= 3. The dimension. + * the \ref t8_cmesh_set_tree_vertices function. Sets the + * name to "t8_geom_linear_axis_aligned" */ - t8_geometry_linear_axis_aligned (int dim); - - /* Base constructor with no arguments. We need this since it - * is called from derived class constructors. - * Sets dimension and name to invalid values. */ - - t8_geometry_linear_axis_aligned (): t8_geometry_with_vertices () - { - } + t8_geometry_linear_axis_aligned (); /** The destructor. */ @@ -71,7 +62,7 @@ struct t8_geometry_linear_axis_aligned: public t8_geometry_with_vertices * Maps points in the reference space \f$ [0,1]^\mathrm{dim} \to \mathbb{R}^3 \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. */ @@ -83,7 +74,7 @@ struct t8_geometry_linear_axis_aligned: public t8_geometry_with_vertices * Compute the jacobian of the \a t8_geom_evaluate map at a point in the reference space \f$ [0,1]^\mathrm{dim} \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] jacobian The jacobian at \a ref_coords. Array of size \a num_coords x dimension x 3. Indices \f$ 3 \cdot i\f$ , \f$ 3 \cdot i+1 \f$ , \f$ 3 \cdot i+2 \f$ * correspond to the \f$ i \f$-th column of the jacobian (Entry \f$ 3 \cdot i + j \f$ is \f$ \frac{\partial f_j}{\partial x_i} \f$). @@ -107,11 +98,29 @@ struct t8_geometry_linear_axis_aligned: public t8_geometry_with_vertices const double tolerance) const; /** - * Check if the currently active tree has a negative volume - * \return True (non-zero) if the currently loaded tree has a negative volume. 0 otherwise. + * Check if the currently active tree has a negative volume. + * \return True if the currently loaded tree has a negative volume. */ virtual bool t8_geom_tree_negative_volume () const; + + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only line, quad and hex elements are supported by this geometry. + * \return True if the geometry is compatible with the tree. + */ + bool + t8_geom_check_tree_compatibility () const + { + if (active_tree_class != T8_ECLASS_LINE && active_tree_class != T8_ECLASS_QUAD + && active_tree_class != T8_ECLASS_HEX) { + t8_productionf ("Axis-aligned geometry is not compatible with tree type %s\n It is only compatible with line, " + "quad and hex elements.\n", + t8_eclass_to_string[active_tree_class]); + return false; + } + return true; + } }; #endif /* !T8_GEOMETRY_LINEAR_AXIS_ALIGNED_HXX */ diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.cxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.cxx index aa77de039a..0ea4c0ac98 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.cxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.cxx @@ -22,7 +22,7 @@ #include -t8_geometry_zero::t8_geometry_zero (int dim): t8_geometry (dim, "t8_geom_zero_" + std::to_string (dim)) +t8_geometry_zero::t8_geometry_zero (): t8_geometry ("t8_geom_zero") { } @@ -47,7 +47,8 @@ t8_geometry_zero::t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtree const size_t num_coords, double *jacobian) const { /* Set the jacobian to 0 */ - memset (jacobian, 0, sizeof (double) * 3 * dimension * num_coords); + const int tree_dim = t8_eclass_to_dimension[active_tree_class]; + memset (jacobian, 0, sizeof (double) * 3 * tree_dim * num_coords); } inline void @@ -59,11 +60,11 @@ t8_geometry_zero::t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid) T8_EXTERN_C_BEGIN (); /* Satisfy the C interface from t8_geometry_zero.h. - * Create a new geometry with given dimension. */ + * Create a new geometry. */ t8_geometry_c * -t8_geometry_zero_new (int dimension) +t8_geometry_zero_new () { - t8_geometry_zero *geom = new t8_geometry_zero (dimension); + t8_geometry_zero *geom = new t8_geometry_zero (); return (t8_geometry_c *) geom; } diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.h index 7822280b44..809ae12ea6 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.h +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.h @@ -24,8 +24,8 @@ * This header provides the C interface to create a zero geometry. */ -#ifndef T8_GEOMETRY_zero_H -#define T8_GEOMETRY_zero_H +#ifndef T8_GEOMETRY_ZERO_H +#define T8_GEOMETRY_ZERO_H #include #include @@ -34,16 +34,15 @@ T8_EXTERN_C_BEGIN (); /** - * Create a new zero geometry of a given dimension. + * Create a new zero geometry. * The geometry is only all tree types and as many vertices as the tree type * has. The vertices are saved via the \ref t8_cmesh_set_tree_vertices function. - * Sets the dimension and the name to "t8_geom_zero_{dim}" - * \param [in] dim 0 <= \a dimension <= 3. The dimension. + * Sets the dimension and the name to "t8_geom_zero_" * \return A pointer to an allocated t8_geometry_zero struct, as - * if the \ref t8_geometry_zero (int dim) constructor was called. + * if the \ref t8_geometry_zero () constructor was called. */ t8_geometry_c * -t8_geometry_zero_new (int dim); +t8_geometry_zero_new (); /** Destroy a zero geometry that was created with \ref t8_geometry_zero_new. * \param [in,out] geom A zero geometry. Set to NULL on output. @@ -53,4 +52,4 @@ t8_geometry_zero_destroy (t8_geometry_c **geom); T8_EXTERN_C_END (); -#endif /* !T8_GEOMETRY_zero_H! */ +#endif /* T8_GEOMETRY_ZERO_H */ diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.hxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.hxx index 94b56ecb7c..64ff0b1072 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.hxx +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.hxx @@ -37,20 +37,19 @@ struct t8_geometry_zero: public t8_geometry { public: /** - * Constructor of the zero geometry with a given dimension. The geometry + * Constructor of the zero geometry. The geometry * is viable with all tree types. This geometry maps all points to zero and * is meant for debugging purposes. - * Sets the dimension and the name to "t8_geom_zero_{dim}" - * \param [in] dim 0 <= \a dimension <= 3. The dimension. + * Sets the dimension and the name to "t8_geom_zero" */ - t8_geometry_zero (int dimension); + t8_geometry_zero (); /** * Check if the currently active tree has a negative volume * \return True (non-zero) if the currently loaded tree has a negative volume. 0 otherwise. */ - virtual bool - t8_geom_tree_negative_volume () const + bool + t8_geom_tree_negative_volume () const override { return 0; }; @@ -65,7 +64,7 @@ struct t8_geometry_zero: public t8_geometry * \return The type. */ inline t8_geometry_type_t - t8_geom_get_type () const + t8_geom_get_type () const override { return T8_GEOMETRY_TYPE_ZERO; }; @@ -74,28 +73,28 @@ struct t8_geometry_zero: public t8_geometry * Maps points in the reference space \f$ [0,1]^\mathrm{dim} \to \mathbb{R}^3 \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3. * \note All entries in out_coords will be set to 0. */ - virtual void + void t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords, - double *out_coords) const; + double *out_coords) const override; /** * Compute the jacobian of the \a t8_geom_evaluate map at a point in the reference space \f$ [0,1]^\mathrm{dim} \f$. * \param [in] cmesh The cmesh in which the point lies. * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is. - * \param [in] ref_coords Array of \a dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. + * \param [in] ref_coords Array of tree dimension x \a num_coords many entries, specifying points in \f$ [0,1]^\mathrm{dim} \f$. * \param [in] num_coords Amount of points of \f$ \mathrm{dim} \f$ to map. * \param [out] jacobian The jacobian at \a ref_coords. Array of size \a num_coords x dimension x 3. Indices \f$ 3 \cdot i\f$ , \f$ 3 \cdot i+1 \f$ , \f$ 3 \cdot i+2 \f$ * correspond to the \f$ i \f$-th column of the jacobian (Entry \f$ 3 \cdot i + j \f$ is \f$ \frac{\partial f_j}{\partial x_i} \f$). * \note All entries in \a jacobian will be set to zero. */ - virtual void + void t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords, - double *jacobian) const; + double *jacobian) const override; /** * \param[in] forest The forest of the element. @@ -106,10 +105,10 @@ struct t8_geometry_zero: public t8_geometry * \param[in, out] is_inside Array to fill with flags whether the point is inside or not * \param[in] tolerance Tolerance of the inside-check */ - virtual void + void t8_geom_point_batch_inside_element (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element, const double *points, const int num_points, int *is_inside, - const double tolerance) + const double tolerance) const override { const double zeros[3] = { 0 }; for (int i_point = 0; i_point < num_points; ++i_point) { @@ -125,8 +124,19 @@ struct t8_geometry_zero: public t8_geometry * \param [in] cmesh The cmesh. * \param [in] gtreeid The global tree. */ - virtual inline void - t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid); + inline void + t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid) override; + + /** + * Check for compatibility of the currently loaded tree with the geometry. + * This geometry supports all element types, hence it returns true. + * \return True if the geometry is compatible with the tree. + */ + bool + t8_geom_check_tree_compatibility () const override + { + return true; + } }; -#endif /* !T8_GEOMETRY_ZERO_HXX */ +#endif /* T8_GEOMETRY_ZERO_HXX */ diff --git a/src/t8_geometry/t8_geometry_with_vertices.cxx b/src/t8_geometry/t8_geometry_with_vertices.cxx index 9ef5d14c28..b2f4590e01 100644 --- a/src/t8_geometry/t8_geometry_with_vertices.cxx +++ b/src/t8_geometry/t8_geometry_with_vertices.cxx @@ -32,24 +32,13 @@ void t8_geometry_with_vertices::t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid) { - /* Set active id and eclass */ - t8_locidx_t ltreeid = t8_cmesh_get_local_id (cmesh, gtreeid); - active_tree = gtreeid; - const t8_locidx_t num_local_trees = t8_cmesh_get_num_local_trees (cmesh); - if (0 <= ltreeid && ltreeid < num_local_trees) { - active_tree_class = t8_cmesh_get_tree_class (cmesh, ltreeid); - } - else { - active_tree_class = t8_cmesh_get_ghost_class (cmesh, ltreeid - num_local_trees); - } + t8_geometry::t8_geom_load_tree_data (cmesh, gtreeid); /* Load this trees vertices. */ + const t8_locidx_t ltreeid = t8_cmesh_get_local_id (cmesh, gtreeid); active_tree_vertices = t8_cmesh_get_tree_vertices (cmesh, ltreeid); - - /* Check whether we support this class */ - T8_ASSERT (active_tree_class == T8_ECLASS_VERTEX || active_tree_class == T8_ECLASS_TRIANGLE - || active_tree_class == T8_ECLASS_TET || active_tree_class == T8_ECLASS_QUAD - || active_tree_class == T8_ECLASS_HEX || active_tree_class == T8_ECLASS_LINE - || active_tree_class == T8_ECLASS_PRISM || active_tree_class == T8_ECLASS_PYRAMID); +#if T8_ENABLE_DEBUG + SC_CHECK_ABORTF (active_tree_vertices != NULL, "ERROR: No vertices found for tree %li\n", (long) ltreeid); +#endif } bool @@ -59,6 +48,8 @@ t8_geometry_with_vertices::t8_geom_tree_negative_volume () const /* Only three dimensional eclass do have a volume */ return false; } + T8_ASSERT (t8_eclass_to_dimension[active_tree_class] + == 3); // Should we include 4 dimensional classes, we need to catch that here and implement it. T8_ASSERT (active_tree_class == T8_ECLASS_TET || active_tree_class == T8_ECLASS_HEX || active_tree_class == T8_ECLASS_PRISM || active_tree_class == T8_ECLASS_PYRAMID); diff --git a/src/t8_geometry/t8_geometry_with_vertices.hxx b/src/t8_geometry/t8_geometry_with_vertices.hxx index dbaeb8e3af..471d0b4f9c 100644 --- a/src/t8_geometry/t8_geometry_with_vertices.hxx +++ b/src/t8_geometry/t8_geometry_with_vertices.hxx @@ -39,8 +39,8 @@ T8_EXTERN_C_BEGIN (); struct t8_geometry_with_vertices: public t8_geometry { public: - /* Basic constructor that sets the dimension, the name, and the name for the attribute. */ - t8_geometry_with_vertices (int dimension, std::string name): t8_geometry (dimension, name) + /* Basic constructor that sets the name. */ + t8_geometry_with_vertices (std::string name): t8_geometry (name) { active_tree_vertices = NULL; active_tree = -1; @@ -48,8 +48,8 @@ struct t8_geometry_with_vertices: public t8_geometry /* Base constructor with no arguments. We need this since it * is called from derived class constructors. - * Sets dimension and name to invalid values. */ - t8_geometry_with_vertices (): t8_geometry_with_vertices (-1, "Invalid") + * Sets the name to an invalid value. */ + t8_geometry_with_vertices (): t8_geometry_with_vertices ("Invalid") { active_tree_vertices = NULL; active_tree = -1; @@ -93,8 +93,6 @@ struct t8_geometry_with_vertices: public t8_geometry }; protected: - t8_gloidx_t active_tree; /*< The tree of which currently vertices are loaded. */ - t8_eclass_t active_tree_class; /*< The class of the currently active tree. */ const double* active_tree_vertices; /*< The vertices of the currently active tree. */ }; diff --git a/src/t8_schemes/t8_default/t8_default_common/t8_default_common.hxx b/src/t8_schemes/t8_default/t8_default_common/t8_default_common.hxx index 528840d8d0..e40861ca88 100644 --- a/src/t8_schemes/t8_default/t8_default_common/t8_default_common.hxx +++ b/src/t8_schemes/t8_default/t8_default_common/t8_default_common.hxx @@ -41,20 +41,20 @@ class t8_default_scheme_common_c: public t8_eclass_scheme_c { t8_element_deinit (int length, t8_element_t *elem) const override; /** Compute the number of corners of a given element. */ - virtual int - t8_element_num_corners (const t8_element_t *elem) const; + int + t8_element_num_corners (const t8_element_t *elem) const override; /** Allocate space for a bunch of elements. */ - virtual void - t8_element_new (int length, t8_element_t **elem) const; + void + t8_element_new (int length, t8_element_t **elem) const override; /** Deallocate space for a bunch of elements. */ - virtual void - t8_element_destroy (int length, t8_element_t **elem) const; + void + t8_element_destroy (int length, t8_element_t **elem) const override; /** Return the shape of an element */ - virtual t8_element_shape_t - t8_element_shape (const t8_element_t *elem) const; + t8_element_shape_t + t8_element_shape (const t8_element_t *elem) const override; /** Count how many leaf descendants of a given uniform level an element would produce. * \param [in] t The element to be checked. @@ -64,8 +64,8 @@ class t8_default_scheme_common_c: public t8_eclass_scheme_c { * Each default element (except pyramids) refines into 2^{dim * (level - level(t))} * children. */ - virtual t8_gloidx_t - t8_element_count_leaves (const t8_element_t *t, int level) const; + t8_gloidx_t + t8_element_count_leaves (const t8_element_t *t, int level) const override; /** Compute the number of siblings of an element. That is the number of * Children of its parent. @@ -73,16 +73,16 @@ class t8_default_scheme_common_c: public t8_eclass_scheme_c { * \return The number of siblings of \a element. * Note that this number is >= 1, since we count the element itself as a sibling. */ - virtual int - t8_element_num_siblings (const t8_element_t *elem) const; + int + t8_element_num_siblings (const t8_element_t *elem) const override; /** Count how many leaf descendants of a given uniform level the root element will produce. * \param [in] level A refinement level. * \return The value of \ref t8_element_count_leaves if the input element * is the root (level 0) element. */ - virtual t8_gloidx_t - t8_element_count_leaves_from_root (int level) const; + t8_gloidx_t + t8_element_count_leaves_from_root (int level) const override; /** Compute the integer coordinates of a given element vertex. * The default scheme implements the Morton type SFCs. In these SFCs the @@ -108,9 +108,9 @@ class t8_default_scheme_common_c: public t8_eclass_scheme_c { * \param [out] out_coords The coordinates of the points in the * reference space of the tree. */ - virtual void + void t8_element_reference_coords (const t8_element_t *elem, const double *ref_coords, const size_t num_coords, - double *out_coords) const + double *out_coords) const override = 0; /** Get the integer coordinates of the anchor node of an element. diff --git a/src/t8_vtk/t8_vtk_reader.cxx b/src/t8_vtk/t8_vtk_reader.cxx index 83d827a0d5..059bcc711e 100644 --- a/src/t8_vtk/t8_vtk_reader.cxx +++ b/src/t8_vtk/t8_vtk_reader.cxx @@ -372,7 +372,7 @@ t8_vtkGrid_to_cmesh (vtkSmartPointer vtkGrid, const int partition, c t8_cmesh_set_dimension (cmesh, dim_buf); /* Set the geometry. */ - t8_cmesh_register_geometry (cmesh, dim_buf); + t8_cmesh_register_geometry (cmesh); /* Global-id of the first local tree */ t8_gloidx_t first_tree = 0; diff --git a/src/t8_vtk/t8_vtk_writer.hxx b/src/t8_vtk/t8_vtk_writer.hxx index 6bb94bfe4e..8b992effc5 100644 --- a/src/t8_vtk/t8_vtk_writer.hxx +++ b/src/t8_vtk/t8_vtk_writer.hxx @@ -93,8 +93,8 @@ class vtk_writer { const bool write_ghosts, const bool curved_flag, std::string fileprefix, const int num_data, t8_vtk_data_field_t *data, sc_MPI_Comm comm) : write_treeid (write_treeid), write_mpirank (write_mpirank), write_level (write_level), - write_ghosts (write_ghosts), curved_flag (curved_flag), fileprefix (fileprefix), num_data (num_data), data (data), - comm (comm) + write_element_id (write_element_id), write_ghosts (write_ghosts), curved_flag (curved_flag), + fileprefix (fileprefix), num_data (num_data), data (data), comm (comm) { } diff --git a/src/t8_vtk/t8_vtk_writer_helper.hxx b/src/t8_vtk/t8_vtk_writer_helper.hxx index efe1832ef9..513d1b64bb 100644 --- a/src/t8_vtk/t8_vtk_writer_helper.hxx +++ b/src/t8_vtk/t8_vtk_writer_helper.hxx @@ -31,8 +31,10 @@ /** Lookup table for number of nodes for curved eclasses. */ const int t8_curved_eclass_num_nodes[T8_ECLASS_COUNT] = { 1, 3, 8, 6, 20, 10, 15, 13 }; +#if T8_WITH_VTK /** Lookup table for vtk types of curved elements */ const int t8_curved_eclass_vtk_type[T8_ECLASS_COUNT] = { 1, 21, 23, 22, 25, 24, 26, 27 }; +#endif /** Map vtk element corners to element reference coordinates. The reference * coordinates are defined in such a way, that the linear vtk corners are listed diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 33ce3ffd72..ef9f9ba71a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,13 +7,55 @@ function( add_t8_test ) set( multiValueArgs "SOURCES" ) cmake_parse_arguments( ADD_T8_TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + # Get the path of the second file listed in the SOURCES list (if there is one then from the first) and use it to determine the build directory. + # We use the second file, because the first is t8_gtest_main, which is in the root test dir. The executable will be build in the same directory as the second source file. + list (LENGTH ADD_T8_TEST_SOURCES TEST_SOURCES_LENGTH) + if ( TEST_SOURCES_LENGTH GREATER 1 ) + list(GET ADD_T8_TEST_SOURCES 1 TEST_SOURCE) + else() + list(GET ADD_T8_TEST_SOURCES 0 TEST_SOURCE) + endif() + get_filename_component(TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/${TEST_SOURCE}" DIRECTORY) + file(RELATIVE_PATH TEST_RELATIVE_DIR "${CMAKE_SOURCE_DIR}" "${TEST_SOURCE_DIR}") + set(TEST_BUILD_DIR "${CMAKE_BINARY_DIR}/${TEST_RELATIVE_DIR}") + add_executable( ${ADD_T8_TEST_NAME} ${ADD_T8_TEST_SOURCES} ) - target_link_libraries( ${ADD_T8_TEST_NAME} PRIVATE T8 gtest pthread) + + # Check if test is a Fortran file and if MPI is enabled. + string ( FIND ${ADD_T8_TEST_NAME} "fortran" is_fortran_file ) + if ( (${is_fortran_file} GREATER_EQUAL 0) AND T8CODE_ENABLE_MPI ) + target_include_directories( ${ADD_T8_TEST_NAME} PRIVATE ${CMAKE_BINARY_DIR}/src ) + target_link_libraries( ${ADD_T8_TEST_NAME} PRIVATE T8 gtest pthread MPI::MPI_Fortran ) + else() + target_link_libraries( ${ADD_T8_TEST_NAME} PRIVATE T8 gtest pthread ) + endif () + + set_target_properties(${ADD_T8_TEST_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${TEST_BUILD_DIR}" + LIBRARY_OUTPUT_DIRECTORY "${TEST_BUILD_DIR}" + ARCHIVE_OUTPUT_DIRECTORY "${TEST_BUILD_DIR}" + ) + + if( T8CODE_EXPORT_COMPILE_COMMANDS ) + set_target_properties( ${ADD_T8_TEST_NAME} PROPERTIES EXPORT_COMPILE_COMMANDS ON ) + endif( T8CODE_EXPORT_COMPILE_COMMANDS ) # Split custom test command into a list by whitespace. - separate_arguments (T8CODE_CUSTOM_TEST_COMMAND_LIST NATIVE_COMMAND "${T8CODE_CUSTOM_TEST_COMMAND}") + # If MPI is enabled, and no custom test command is provided, use mpirun -np 4 as the default command. + # If MPI is not enabled, use the custom test command as is. + if ( T8CODE_ENABLE_MPI ) + if (${ADD_T8_TEST_NAME} MATCHES "_serial") + separate_arguments(T8CODE_TEST_COMMAND_LIST NATIVE_COMMAND ${T8CODE_CUSTOM_SERIAL_TEST_COMMAND}) + elseif ( T8CODE_CUSTOM_PARALLEL_TEST_COMMAND STREQUAL "" ) + separate_arguments (T8CODE_TEST_COMMAND_LIST NATIVE_COMMAND "mpirun -np 4") + else ( T8CODE_CUSTOM_PARALLEL_TEST_COMMAND STREQUAL "" ) + separate_arguments (T8CODE_TEST_COMMAND_LIST NATIVE_COMMAND ${T8CODE_CUSTOM_PARALLEL_TEST_COMMAND}) + endif () + else( T8CODE_ENABLE_MPI ) + separate_arguments (T8CODE_TEST_COMMAND_LIST NATIVE_COMMAND ${T8CODE_CUSTOM_SERIAL_TEST_COMMAND}) + endif ( T8CODE_ENABLE_MPI ) - add_test( NAME ${ADD_T8_TEST_NAME} COMMAND ${T8CODE_CUSTOM_TEST_COMMAND_LIST} ./${ADD_T8_TEST_NAME} ) + add_test( NAME ${ADD_T8_TEST_NAME} COMMAND ${T8CODE_TEST_COMMAND_LIST} ${TEST_BUILD_DIR}/${ADD_T8_TEST_NAME} ) endfunction() # Copy test files to build folder so that the t8_test programs can find them. @@ -21,81 +63,85 @@ function( copy_test_file TEST_FILE_NAME ) configure_file(${CMAKE_CURRENT_LIST_DIR}/testfiles/${TEST_FILE_NAME} ${CMAKE_CURRENT_BINARY_DIR}/test/testfiles/${TEST_FILE_NAME} COPYONLY) endfunction() -add_t8_test( NAME t8_gtest_cmesh_bcast SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_bcast.cxx ) -add_t8_test( NAME t8_gtest_eclass SOURCES t8_gtest_main.cxx t8_gtest_eclass.cxx ) -add_t8_test( NAME t8_gtest_vec SOURCES t8_gtest_main.cxx t8_gtest_vec.cxx ) -add_t8_test( NAME t8_gtest_mat SOURCES t8_gtest_main.cxx t8_gtest_mat.cxx ) -add_t8_test( NAME t8_gtest_refcount SOURCES t8_gtest_main.cxx t8_gtest_refcount.cxx ) -add_t8_test( NAME t8_gtest_occ_linkage SOURCES t8_gtest_main.cxx t8_gtest_occ_linkage.cxx ) -add_t8_test( NAME t8_gtest_version SOURCES t8_gtest_main.cxx t8_gtest_version.cxx ) -add_t8_test( NAME t8_gtest_basics SOURCES t8_gtest_main.cxx t8_gtest_basics.cxx ) -add_t8_test( NAME t8_gtest_netcdf_linkage SOURCES t8_gtest_main.cxx t8_gtest_netcdf_linkage.cxx ) -add_t8_test( NAME t8_gtest_vtk_linkage SOURCES t8_gtest_main.cxx t8_gtest_vtk_linkage.cxx ) - -add_t8_test( NAME t8_gtest_hypercube SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_hypercube.cxx ) -add_t8_test( NAME t8_gtest_cmesh_readmshfile SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_readmshfile.cxx ) -add_t8_test( NAME t8_gtest_cmesh_copy SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_copy.cxx ) -add_t8_test( NAME t8_gtest_cmesh_face_is_boundary SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_face_is_boundary.cxx ) -add_t8_test( NAME t8_gtest_cmesh_partition SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_partition.cxx ) -add_t8_test( NAME t8_gtest_cmesh_set_partition_offsets SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_set_partition_offsets.cxx ) -add_t8_test( NAME t8_gtest_cmesh_set_join_by_vertices SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx ) -add_t8_test( NAME t8_gtest_cmesh_add_attributes_when_derive SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_add_attributes_when_derive.cxx ) -add_t8_test( NAME t8_gtest_cmesh_tree_vertices_negative_volume SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_tree_vertices_negative_volume.cxx ) - -add_t8_test( NAME t8_gtest_multiple_attributes SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_multiple_attributes.cxx ) -add_t8_test( NAME t8_gtest_attribute_gloidx_array SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_attribute_gloidx_array.cxx ) - -add_t8_test( NAME t8_gtest_shmem SOURCES t8_gtest_main.cxx t8_data/t8_gtest_shmem.cxx ) - -add_t8_test( NAME t8_gtest_element_volume SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_element_volume.cxx ) -add_t8_test( NAME t8_gtest_search SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_search.cxx ) -add_t8_test( NAME t8_gtest_half_neighbors SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_half_neighbors.cxx ) -add_t8_test( NAME t8_gtest_find_owner SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_find_owner.cxx ) -add_t8_test( NAME t8_gtest_user_data SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_user_data.cxx ) -add_t8_test( NAME t8_gtest_transform SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_transform.cxx ) -add_t8_test( NAME t8_gtest_ghost_exchange SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_ghost_exchange.cxx ) -add_t8_test( NAME t8_gtest_ghost_delete SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_ghost_delete.cxx ) -add_t8_test( NAME t8_gtest_ghost_and_owner SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_ghost_and_owner.cxx ) -add_t8_test( NAME t8_gtest_balance SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_balance.cxx ) -add_t8_test( NAME t8_gtest_forest_commit SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_forest_commit.cxx ) -add_t8_test( NAME t8_gtest_forest_face_normal SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_forest_face_normal.cxx ) -add_t8_test( NAME t8_gtest_element_is_leaf SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_element_is_leaf.cxx ) -add_t8_test( NAME t8_gtest_partition_data SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_partition_data.cxx ) - -add_t8_test( NAME t8_gtest_permute_hole SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_permute_hole.cxx ) -add_t8_test( NAME t8_gtest_recursive SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_recursive.cxx ) -add_t8_test( NAME t8_gtest_iterate_replace SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_iterate_replace.cxx ) -add_t8_test( NAME t8_gtest_empty_local_tree SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_empty_local_tree.cxx ) -add_t8_test( NAME t8_gtest_empty_global_tree SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_empty_global_tree.cxx ) - -add_t8_test( NAME t8_gtest_geometry_cad SOURCES t8_gtest_main.cxx t8_geometry/t8_geometry_implementations/t8_gtest_geometry_cad.cxx ) -add_t8_test( NAME t8_gtest_geometry_linear SOURCES t8_gtest_main.cxx t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear.cxx ) -add_t8_test( NAME t8_gtest_geometry_lagrange SOURCES t8_gtest_main.cxx t8_geometry/t8_geometry_implementations/t8_gtest_geometry_lagrange.cxx ) -add_t8_test( NAME t8_gtest_geometry_triangular_interpolation SOURCES t8_gtest_main.cxx t8_geometry/t8_gtest_geometry_triangular_interpolation.cxx ) -add_t8_test( NAME t8_gtest_geometry_handling SOURCES t8_gtest_main.cxx t8_geometry/t8_gtest_geometry_handling.cxx ) -add_t8_test( NAME t8_gtest_point_inside SOURCES t8_gtest_main.cxx t8_geometry/t8_gtest_point_inside.cxx ) - -add_t8_test( NAME t8_gtest_vtk_reader SOURCES t8_gtest_main.cxx t8_IO/t8_gtest_vtk_reader.cxx ) -add_t8_test( NAME t8_gtest_vtk_writer SOURCES t8_gtest_main.cxx t8_IO/t8_gtest_vtk_writer.cxx ) - -add_t8_test( NAME t8_gtest_nca SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_nca.cxx ) -add_t8_test( NAME t8_gtest_pyra_connectivity SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_pyra_connectivity.cxx ) -add_t8_test( NAME t8_gtest_face_neigh SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_neigh.cxx ) -add_t8_test( NAME t8_gtest_init_linear_id SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_init_linear_id.cxx ) -add_t8_test( NAME t8_gtest_ancestor SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_ancestor.cxx ) -add_t8_test( NAME t8_gtest_element_count_leaves SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_element_count_leaves.cxx ) -add_t8_test( NAME t8_gtest_element_ref_coords SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_element_ref_coords.cxx ) -add_t8_test( NAME t8_gtest_descendant SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_descendant.cxx ) -add_t8_test( NAME t8_gtest_find_parent SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_find_parent.cxx ) -add_t8_test( NAME t8_gtest_equal SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_equal.cxx ) -add_t8_test( NAME t8_gtest_successor SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_successor.cxx ) -add_t8_test( NAME t8_gtest_boundary_extrude SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_boundary_extrude.cxx ) -add_t8_test( NAME t8_gtest_face_descendant SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_descendant.cxx ) -add_t8_test( NAME t8_gtest_default SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default.cxx ) -add_t8_test( NAME t8_gtest_child_parent_face SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_child_parent_face.cxx ) -add_t8_test( NAME t8_gtest_pack_unpack SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_pack_unpack.cxx ) -add_t8_test( NAME t8_gtest_root SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_root.cxx ) -add_t8_test( NAME t8_gtest_scheme_consistency SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_scheme_consistency.cxx ) +add_t8_test( NAME t8_gtest_cmesh_bcast_parallel SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_bcast.cxx ) +add_t8_test( NAME t8_gtest_eclass_serial SOURCES t8_gtest_main.cxx t8_gtest_eclass.cxx ) +add_t8_test( NAME t8_gtest_vec_serial SOURCES t8_gtest_main.cxx t8_gtest_vec.cxx ) +add_t8_test( NAME t8_gtest_mat_serial SOURCES t8_gtest_main.cxx t8_gtest_mat.cxx ) +add_t8_test( NAME t8_gtest_refcount_serial SOURCES t8_gtest_main.cxx t8_gtest_refcount.cxx ) +add_t8_test( NAME t8_gtest_occ_linkage_serial SOURCES t8_gtest_main.cxx t8_gtest_occ_linkage.cxx ) +add_t8_test( NAME t8_gtest_version_serial SOURCES t8_gtest_main.cxx t8_gtest_version.cxx ) +add_t8_test( NAME t8_gtest_basics_serial SOURCES t8_gtest_main.cxx t8_gtest_basics.cxx ) +add_t8_test( NAME t8_gtest_netcdf_linkage_serial SOURCES t8_gtest_main.cxx t8_gtest_netcdf_linkage.cxx ) +add_t8_test( NAME t8_gtest_vtk_linkage_serial SOURCES t8_gtest_main.cxx t8_gtest_vtk_linkage.cxx ) + +add_t8_test( NAME t8_gtest_hypercube_parallel SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_hypercube.cxx ) +add_t8_test( NAME t8_gtest_cmesh_readmshfile_serial SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_readmshfile.cxx ) +add_t8_test( NAME t8_gtest_cmesh_copy_serial SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_copy.cxx ) +add_t8_test( NAME t8_gtest_cmesh_face_is_boundary_parallel SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_face_is_boundary.cxx ) +add_t8_test( NAME t8_gtest_cmesh_partition_parallel SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_partition.cxx ) +add_t8_test( NAME t8_gtest_cmesh_set_partition_offsets_parallel SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_set_partition_offsets.cxx ) +add_t8_test( NAME t8_gtest_cmesh_set_join_by_vertices_serial SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx ) +add_t8_test( NAME t8_gtest_cmesh_add_attributes_when_derive_parallel SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_add_attributes_when_derive.cxx ) +add_t8_test( NAME t8_gtest_cmesh_tree_vertices_negative_volume_serial SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_cmesh_tree_vertices_negative_volume.cxx ) + +add_t8_test( NAME t8_gtest_multiple_attributes_parallel SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_multiple_attributes.cxx ) +add_t8_test( NAME t8_gtest_attribute_gloidx_array_serial SOURCES t8_gtest_main.cxx t8_cmesh/t8_gtest_attribute_gloidx_array.cxx ) + +add_t8_test( NAME t8_gtest_shmem_parallel SOURCES t8_gtest_main.cxx t8_data/t8_gtest_shmem.cxx ) + +add_t8_test( NAME t8_gtest_element_volume_serial SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_element_volume.cxx ) +add_t8_test( NAME t8_gtest_search_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_search.cxx ) +add_t8_test( NAME t8_gtest_half_neighbors_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_half_neighbors.cxx ) +add_t8_test( NAME t8_gtest_find_owner_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_find_owner.cxx ) +add_t8_test( NAME t8_gtest_user_data_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_user_data.cxx ) +add_t8_test( NAME t8_gtest_transform_serial SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_transform.cxx ) +add_t8_test( NAME t8_gtest_ghost_exchange_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_ghost_exchange.cxx ) +add_t8_test( NAME t8_gtest_ghost_delete_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_ghost_delete.cxx ) +add_t8_test( NAME t8_gtest_ghost_and_owner_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_ghost_and_owner.cxx ) +add_t8_test( NAME t8_gtest_balance_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_balance.cxx ) +add_t8_test( NAME t8_gtest_forest_commit_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_forest_commit.cxx ) +add_t8_test( NAME t8_gtest_forest_face_normal_serial SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_forest_face_normal.cxx ) +add_t8_test( NAME t8_gtest_element_is_leaf_serial SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_element_is_leaf.cxx ) +add_t8_test( NAME t8_gtest_partition_data_parallel SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_partition_data.cxx ) + +add_t8_test( NAME t8_gtest_permute_hole_serial SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_permute_hole.cxx ) +add_t8_test( NAME t8_gtest_recursive_serial SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_recursive.cxx ) +add_t8_test( NAME t8_gtest_iterate_replace_serial SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_iterate_replace.cxx ) +add_t8_test( NAME t8_gtest_empty_local_tree_parallel SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_empty_local_tree.cxx ) +add_t8_test( NAME t8_gtest_empty_global_tree_parallel SOURCES t8_gtest_main.cxx t8_forest_incomplete/t8_gtest_empty_global_tree.cxx ) + +add_t8_test( NAME t8_gtest_geometry_cad_serial SOURCES t8_gtest_main.cxx t8_geometry/t8_geometry_implementations/t8_gtest_geometry_cad.cxx ) +add_t8_test( NAME t8_gtest_geometry_linear_serial SOURCES t8_gtest_main.cxx t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear.cxx ) +add_t8_test( NAME t8_gtest_geometry_lagrange_serial SOURCES t8_gtest_main.cxx t8_geometry/t8_geometry_implementations/t8_gtest_geometry_lagrange.cxx ) +add_t8_test( NAME t8_gtest_geometry_triangular_interpolation_serial SOURCES t8_gtest_main.cxx t8_geometry/t8_gtest_geometry_triangular_interpolation.cxx ) +add_t8_test( NAME t8_gtest_geometry_handling_serial SOURCES t8_gtest_main.cxx t8_geometry/t8_gtest_geometry_handling.cxx ) +add_t8_test( NAME t8_gtest_point_inside_serial SOURCES t8_gtest_main.cxx t8_geometry/t8_gtest_point_inside.cxx ) + +add_t8_test( NAME t8_gtest_vtk_reader_parallel SOURCES t8_gtest_main.cxx t8_IO/t8_gtest_vtk_reader.cxx ) +add_t8_test( NAME t8_gtest_vtk_writer_parallel SOURCES t8_gtest_main.cxx t8_IO/t8_gtest_vtk_writer.cxx ) + +add_t8_test( NAME t8_gtest_nca_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_nca.cxx ) +add_t8_test( NAME t8_gtest_pyra_connectivity_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_pyra_connectivity.cxx ) +add_t8_test( NAME t8_gtest_face_neigh_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_neigh.cxx ) +add_t8_test( NAME t8_gtest_init_linear_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_init_linear_id.cxx ) +add_t8_test( NAME t8_gtest_ancestor_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_ancestor.cxx ) +add_t8_test( NAME t8_gtest_element_count_leaves_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_element_count_leaves.cxx ) +add_t8_test( NAME t8_gtest_element_ref_coords_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_element_ref_coords.cxx ) +add_t8_test( NAME t8_gtest_descendant_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_descendant.cxx ) +add_t8_test( NAME t8_gtest_find_parent_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_find_parent.cxx ) +add_t8_test( NAME t8_gtest_equal_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_equal.cxx ) +add_t8_test( NAME t8_gtest_successor_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_successor.cxx ) +add_t8_test( NAME t8_gtest_boundary_extrude_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_boundary_extrude.cxx ) +add_t8_test( NAME t8_gtest_face_descendant_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_descendant.cxx ) +add_t8_test( NAME t8_gtest_default_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default.cxx ) +add_t8_test( NAME t8_gtest_child_parent_face_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_child_parent_face.cxx ) +add_t8_test( NAME t8_gtest_pack_unpack_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_pack_unpack.cxx ) +add_t8_test( NAME t8_gtest_root_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_root.cxx ) +add_t8_test( NAME t8_gtest_scheme_consistency_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_scheme_consistency.cxx ) + +if( T8CODE_BUILD_FORTRAN_INTERFACE AND T8CODE_ENABLE_MPI ) + add_t8_test( NAME t8_test_fortran_mpi_interface_init_parallel SOURCES api/t8_fortran_interface/t8_test_mpi_init.f90 ) +endif() copy_test_file( test_cube_unstructured_1.inp ) copy_test_file( test_cube_unstructured_2.inp ) diff --git a/test/api/t8_fortran_interface/t8_test_mpi_init.f90 b/test/api/t8_fortran_interface/t8_test_mpi_init.f90 new file mode 100644 index 0000000000..665a6d0ec7 --- /dev/null +++ b/test/api/t8_fortran_interface/t8_test_mpi_init.f90 @@ -0,0 +1,51 @@ +!! This file is part of t8code. +!! t8code is a C library to manage a collection (a forest) of multiple +!! connected adaptive space-trees of general element classes in parallel. +!! +!! Copyright (C) 2024 the developers +!! +!! t8code is free software; you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation; either version 2 of the License, or +!! (at your option) any later version. +!! +!! t8code is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with t8code; if not, write to the Free Software Foundation, Inc., +!! 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +!! Description: +!! +!! This program tests if t8code can be initialized from Fortran +!! with given MPI communicator. Works only when MPI is enabled. + +program t8_test_mpi_init + use mpi + use iso_c_binding, only: c_ptr, c_int + use t8_fortran_interface_mod + + implicit none + + integer :: ierror, fcomm + type(c_ptr) :: ccomm + + call MPI_Init (ierror) + + if (ierror /= 0) then + print *, 'MPI initialization failed.' + stop 1 + endif + + fcomm = MPI_COMM_WORLD + ccomm = t8_fortran_mpi_comm_new_f (fcomm) + + call t8_fortran_init_all_f (ccomm) + call t8_fortran_finalize_f () + + print *, 'All good!' + stop 0 +end program diff --git a/test/t8_cmesh/t8_gtest_cmesh_partition.cxx b/test/t8_cmesh/t8_gtest_cmesh_partition.cxx index d5b41e8555..019f374ac4 100644 --- a/test/t8_cmesh/t8_gtest_cmesh_partition.cxx +++ b/test/t8_cmesh/t8_gtest_cmesh_partition.cxx @@ -39,15 +39,7 @@ class t8_cmesh_partition_class: public testing::TestWithParamparam_to_string (name); - - size_t found = name.find (std::string ("t8_cmesh_new_from_class__Pyramid_sc_MPI_COMM_WORLD")); - if (found != std::string::npos) { - /* Test not working for pyramids */ - GTEST_SKIP (); - } - found = GetParam ()->name.find (std::string ("empty")); + size_t found = GetParam ()->name.find (std::string ("empty")); if (found != std::string::npos) { /* Tests not working for empty cmeshes */ GTEST_SKIP (); diff --git a/test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx b/test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx index d6fbd6d773..190d51dc43 100644 --- a/test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx +++ b/test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx @@ -445,11 +445,15 @@ class t8_cmesh_set_join_by_vertices_class: public testing::TestWithParamname.find (std::string ("bigmesh")); if (found != std::string::npos) { - /* skip bigmeshes as they get to large */ + /* skip bigmeshes as they do not have vertices from which to build the connectivity */ GTEST_SKIP (); } cmesh = GetParam ()->cmesh_create (); + if (cmesh->set_partition) { + /* skip partitioned cmeshes, as they do not have all necessary vertex information for the neighbors */ + GTEST_SKIP (); + } } void diff --git a/test/t8_cmesh/t8_gtest_hypercube.cxx b/test/t8_cmesh/t8_gtest_hypercube.cxx index 7062cad8cc..2228263236 100644 --- a/test/t8_cmesh/t8_gtest_hypercube.cxx +++ b/test/t8_cmesh/t8_gtest_hypercube.cxx @@ -63,7 +63,7 @@ TEST_P (cmesh_hypercube_trees, check_cmesh_and_its_trees) ASSERT_EQ (t8_cmesh_get_dimension (cmesh), t8_eclass_to_dimension[eclass]) << "Wrong dimension set for cmesh."; } -/* Use the testing range for eclass with [T8_ECLASS_ZERO, T8_ECLASS_COUNT]. For the generation of the cmesh with or withaout broadcast +/* Use the testing range for eclass with [T8_ECLASS_ZERO, T8_ECLASS_COUNT]. For the generation of the cmesh with or without broadcast * the booleans 0 and 1 are used. Analogue with partition. */ INSTANTIATE_TEST_SUITE_P (t8_gtest_hypercube, cmesh_hypercube_trees, testing::Combine (AllEclasses, testing::Values (0, 1), testing::Values (0, 1))); diff --git a/test/t8_cmesh/t8_gtest_multiple_attributes.cxx b/test/t8_cmesh/t8_gtest_multiple_attributes.cxx index 7e3fad23df..39462ebfb8 100644 --- a/test/t8_cmesh/t8_gtest_multiple_attributes.cxx +++ b/test/t8_cmesh/t8_gtest_multiple_attributes.cxx @@ -124,8 +124,7 @@ TEST_P (cmesh_multiple_attributes, multiple_attributes) t8_locidx_t num_ghosts = t8_cmesh_get_num_ghosts (cmesh_mult_at_from_stash); for (t8_locidx_t ltree_id = 0; ltree_id < num_local_trees + num_ghosts; ltree_id++) { const t8_gloidx_t gtree_id = t8_cmesh_get_global_id (cmesh_mult_at_from_stash, ltree_id); - const double *vertices_partition = (double *) t8_cmesh_get_attribute ( - cmesh_mult_at_from_stash, t8_get_package_id (), T8_CMESH_VERTICES_ATTRIBUTE_KEY, ltree_id); + const double *vertices_partition = t8_cmesh_get_tree_vertices (cmesh_mult_at_from_stash, ltree_id); const t8_eclass_t eclass = (ltree_id < num_local_trees) ? t8_cmesh_get_tree_class (cmesh_one_at, ltree_id) : t8_cmesh_get_ghost_class (cmesh_one_at, ltree_id - num_local_trees); @@ -133,9 +132,12 @@ TEST_P (cmesh_multiple_attributes, multiple_attributes) /* Compare vertices with reference vertices. */ for (int v_id = 0; v_id < 8; v_id++) { - EXPECT_EQ (vertices_partition[v_id * 3], vertices_ref[v_id * 3] + gtree_id); - EXPECT_EQ (vertices_partition[v_id * 3 + 1], vertices_ref[v_id * 3 + 1]); - EXPECT_EQ (vertices_partition[v_id * 3 + 2], vertices_ref[v_id * 3 + 2]); + EXPECT_EQ (vertices_partition[v_id * 3], vertices_ref[v_id * 3] + gtree_id) + << " at tree id " << ltree_id << " and vertex " << v_id; + EXPECT_EQ (vertices_partition[v_id * 3 + 1], vertices_ref[v_id * 3 + 1]) + << " at tree id " << ltree_id << " and rtex " << v_id; + EXPECT_EQ (vertices_partition[v_id * 3 + 2], vertices_ref[v_id * 3 + 2]) + << " at tree id " << ltree_id << " and vertex " << v_id; } /* Compare second attribute with global tree id. */ t8_locidx_t att; @@ -150,4 +152,4 @@ TEST_P (cmesh_multiple_attributes, multiple_attributes) } /* Test for different number of trees. */ -INSTANTIATE_TEST_SUITE_P (t8_gtest_multiple_attributes, cmesh_multiple_attributes, testing::Range (1, 4)); +INSTANTIATE_TEST_SUITE_P (t8_gtest_multiple_attributes, cmesh_multiple_attributes, testing::Range (1, 10)); diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx index e0639fe49d..f43445b0a8 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx @@ -61,7 +61,7 @@ example_set *cmesh_example = (example_set *) new cmesh_cartesian_product_params< std::make_pair (periodic_eclasses.begin (), periodic_eclasses.end ()), std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()), std::make_pair (cmesh_params::do_bcast.begin (), cmesh_params::do_bcast.end ()), - std::make_pair (cmesh_params::no_partition.begin (), cmesh_params::no_partition.end ()), + std::make_pair (cmesh_params::partition.begin (), cmesh_params::partition.end ()), std::make_pair (cmesh_params::periodic.begin (), cmesh_params::periodic.end ()), cmesh_wrapper, param_to_string, "t8_cmesh_new_hypercube_"); @@ -72,7 +72,7 @@ example_set *cmesh_example_pyra = (example_set *) new cmesh_cartesian_product_pa std::make_pair (nonperiodic_eclasses.begin (), nonperiodic_eclasses.end ()), std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()), std::make_pair (cmesh_params::do_bcast.begin (), cmesh_params::do_bcast.end ()), - std::make_pair (cmesh_params::no_partition.begin (), cmesh_params::no_partition.end ()), + std::make_pair (cmesh_params::partition.begin (), cmesh_params::partition.end ()), std::make_pair (cmesh_params::no_periodic.begin (), cmesh_params::no_periodic.end ()), cmesh_wrapper, param_to_string, "t8_cmesh_new_hypercube_"); } // namespace new_hypercube_cmesh diff --git a/test/t8_forest/t8_gtest_element_volume.cxx b/test/t8_forest/t8_gtest_element_volume.cxx index 5edc73ea33..a44c990fe1 100644 --- a/test/t8_forest/t8_gtest_element_volume.cxx +++ b/test/t8_forest/t8_gtest_element_volume.cxx @@ -33,7 +33,6 @@ /** * This file tests the volume-computation of elements. */ -#define epsilon 1e-9 /* Construct a forest of a hypercube with volume 1. If the element are refined uniformly * all elements have volume 1/global_num_elements. */ @@ -109,10 +108,10 @@ TEST_P (t8_forest_volume, volume_check) const double volume = t8_forest_element_volume (forest, itree, element); if (eclass == T8_ECLASS_PYRAMID) { const double shape_volume = pyramid_control_volume ((t8_dpyramid_t *) element); - EXPECT_NEAR (volume, shape_volume, epsilon); + EXPECT_NEAR (volume, shape_volume, T8_PRECISION_SQRT_EPS); } else { - EXPECT_NEAR (volume, control_volume, epsilon); + EXPECT_NEAR (volume, control_volume, T8_PRECISION_SQRT_EPS); } } } diff --git a/test/t8_forest/t8_gtest_forest_commit.cxx b/test/t8_forest/t8_gtest_forest_commit.cxx index 0fb6be0b67..3ab727f497 100644 --- a/test/t8_forest/t8_gtest_forest_commit.cxx +++ b/test/t8_forest/t8_gtest_forest_commit.cxx @@ -30,7 +30,7 @@ #include "test/t8_cmesh_generator/t8_cmesh_example_sets.hxx" #include -/* In this test, we adapt, balance and partition a uniform forest. +/* In this test we adapt, balance and partition a uniform forest. * We do this in two ways: * 1st All operations are performed in one single call to t8_forest_commit * 2nd Each intermediate step is performed in a separate commit diff --git a/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_cad.cxx b/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_cad.cxx index 843a6a74d6..6f512a062c 100644 --- a/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_cad.cxx +++ b/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_cad.cxx @@ -217,13 +217,13 @@ t8_create_cad_hypercube (double *rot_vec, int face, int edge, double *parameters T8_ASSERT (face < 0 || edge < 0); if (face >= 0) { faces[face] = 1; - t8_cmesh_register_geometry (cmesh, 3, t8_create_cad_surface_shape_x_z ()); + t8_cmesh_register_geometry (cmesh, t8_create_cad_surface_shape_x_z ()); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + face, parameters, 8 * sizeof (double), 0); } else if (edge >= 0) { edges[edge] = 1; - t8_cmesh_register_geometry (cmesh, 3, t8_create_cad_curve_shape ()); + t8_cmesh_register_geometry (cmesh, t8_create_cad_curve_shape ()); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + edge, parameters, 2 * sizeof (double), 0); } @@ -232,7 +232,7 @@ t8_create_cad_hypercube (double *rot_vec, int face, int edge, double *parameters * we have to create a geometry. Hence a cad geometry can only be created * with an actual shape, we just create a geometry with a curve and do not * link the curve to any edge. */ - t8_cmesh_register_geometry (cmesh, 3, t8_create_cad_curve_shape ()); + t8_cmesh_register_geometry (cmesh, t8_create_cad_curve_shape ()); } t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces, 6 * sizeof (int), 0); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int), 0); @@ -424,13 +424,13 @@ t8_create_cad_reference_tet (int face, int edge, double *parameters) T8_ASSERT (face < 0 || edge < 0); if (face >= 0) { faces[face] = 1; - t8_cmesh_register_geometry (cmesh, 3, t8_create_cad_surface_shape_x_z ()); + t8_cmesh_register_geometry (cmesh, t8_create_cad_surface_shape_x_z ()); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + face, parameters, 6 * sizeof (double), 0); } else if (edge >= 0) { edges[edge] = 1; - t8_cmesh_register_geometry (cmesh, 3, t8_create_cad_curve_shape ()); + t8_cmesh_register_geometry (cmesh, t8_create_cad_curve_shape ()); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + edge, parameters, 2 * sizeof (double), 0); } @@ -439,7 +439,7 @@ t8_create_cad_reference_tet (int face, int edge, double *parameters) * we have to create a geometry. Hence a cad geometry can only be created * with an actual shape, we just create a geometry with a curve and do not * link the curve to any edge. */ - t8_cmesh_register_geometry (cmesh, 3, t8_create_cad_curve_shape ()); + t8_cmesh_register_geometry (cmesh, t8_create_cad_curve_shape ()); } t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces, 4 * sizeof (int), 0); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges, 12 * sizeof (int), 0); @@ -671,7 +671,7 @@ TEST_P (class_2d_element_cad_curve, t8_check_2d_element_cad_curve) t8_cmesh_init (&cmesh); t8_cmesh_set_tree_class (cmesh, 0, eclass); - t8_cmesh_register_geometry (cmesh, 2, (curvature == 0 ? shape_linear : shape_curved)); + t8_cmesh_register_geometry (cmesh, (curvature == 0 ? shape_linear : shape_curved)); t8_cmesh_set_tree_vertices ( cmesh, 0, (eclass == T8_ECLASS_QUAD ? vertices_quad + orientation : vertices_tri + orientation), num_vertices); @@ -791,7 +791,7 @@ TEST_P (class_2d_element_linear_cad_surface, t8_check_2d_element_linear_cad_surf (eclass == T8_ECLASS_QUAD ? params_quad : params_tri), 2 * num_vertices * sizeof (double), 0); /* Register the geometry */ - t8_cmesh_register_geometry (cmesh, 2, shape); + t8_cmesh_register_geometry (cmesh, shape); /* Commit the cmesh */ t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); @@ -858,7 +858,7 @@ class class_2d_element_curved_cad_surface: public testing::TestWithParam (cmesh, 2, shape); + t8_cmesh_register_geometry (cmesh, shape); } void @@ -965,13 +965,13 @@ t8_create_cad_reference_prism (int face, int edge, double *parameters) if (face >= 0) { faces[face] = 1; t8_cmesh_register_geometry ( - cmesh, 3, (face <= 2 ? t8_create_cad_surface_shape_x_z () : t8_create_cad_surface_shape_x_y ())); + cmesh, (face <= 2 ? t8_create_cad_surface_shape_x_z () : t8_create_cad_surface_shape_x_y ())); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + face, parameters, 2 * face_vertices * sizeof (double), 0); } else if (edge >= 0) { edges[edge] = 1; - t8_cmesh_register_geometry (cmesh, 3, t8_create_cad_curve_shape ()); + t8_cmesh_register_geometry (cmesh, t8_create_cad_curve_shape ()); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + edge, parameters, 2 * sizeof (double), 0); } @@ -980,7 +980,7 @@ t8_create_cad_reference_prism (int face, int edge, double *parameters) * we have to create a geometry. Hence a cad geometry can only be created * with an actual shape, we just create a geometry with a curve and do not * link the curve to any edge. */ - t8_cmesh_register_geometry (cmesh, 3, t8_create_cad_curve_shape ()); + t8_cmesh_register_geometry (cmesh, t8_create_cad_curve_shape ()); } t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces, 5 * sizeof (int), 0); t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges, 18 * sizeof (int), 0); diff --git a/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_lagrange.cxx b/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_lagrange.cxx index 8fd697abff..4c1d69b18a 100644 --- a/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_lagrange.cxx +++ b/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_lagrange.cxx @@ -35,9 +35,8 @@ #include #include #include -#include +#include #include - #include #include #include @@ -250,3 +249,70 @@ INSTANTIATE_TEST_SUITE_P (t8_gtest_geometry_lagrange, LagrangeCmesh, << "_degree" << std::get<1> (info.param); return test_name.str ();}); /* clang-format on */ + +#if T8_ENABLE_DEBUG + +/** + * Tests the compatibility checking for the Lagrange geometry. + * The geometry should throw assertions if the geometry is not compatible with an assigned tree. + */ +TEST (test_geometry_lagrange, incompatible_geometry) +{ + t8_cmesh_t cmesh; + int degree = 1; + + t8_debugf ("Testing geometry compatibility checking for lagrange geometry.\n"); + + /* Build a simple set geometries for the tree. */ + t8_cmesh_init (&cmesh); + t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD); + t8_cmesh_set_tree_vertices (cmesh, 0, *t8_element_corner_ref_coords[T8_ECLASS_QUAD], 4); + t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE_KEY, °ree, sizeof (degree), + 0); + + /* Commit the cmesh */ + t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); + /* Register the t8_geometry_lagrange geometry to this cmesh. */ + t8_cmesh_register_geometry (cmesh); + /* Should return true since the t8_geometry_lagrange geometry is compatible with quads. */ + ASSERT_TRUE (t8_cmesh_validate_geometry (cmesh)); + t8_cmesh_destroy (&cmesh); + + /* Build a simple set geometries for the tree. */ + t8_cmesh_init (&cmesh); + t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_HEX); + t8_cmesh_set_tree_vertices (cmesh, 0, *t8_element_corner_ref_coords[T8_ECLASS_HEX], 8); + t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE_KEY, °ree, sizeof (degree), + 0); + t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_PRISM); + t8_cmesh_set_tree_vertices (cmesh, 1, *t8_element_corner_ref_coords[T8_ECLASS_PRISM], 6); + t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE_KEY, °ree, sizeof (degree), + 0); + /* Commit the cmesh */ + t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); + /* Register the t8_geometry_lagrange to this cmesh. + * We register it after committing because it would throw an assertion and we do not have death tests.*/ + t8_cmesh_register_geometry (cmesh); + /* Check validity after committing to circumvent the assertion. + * Should return false since the t8_geometry_lagrange geometry is not compatible with prisms. */ + ASSERT_FALSE (t8_cmesh_validate_geometry (cmesh)); + t8_cmesh_destroy (&cmesh); + + degree = T8_GEOMETRY_MAX_POLYNOMIAL_DEGREE + 1; + /* Build a simple set geometries for the tree. */ + t8_cmesh_init (&cmesh); + t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_HEX); + t8_cmesh_set_tree_vertices (cmesh, 0, *t8_element_corner_ref_coords[T8_ECLASS_HEX], 8); + t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_LAGRANGE_POLY_DEGREE_KEY, °ree, sizeof (degree), + 0); + /* Commit the cmesh */ + t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); + /* Register the t8_geometry_lagrange to this cmesh. + * We register it after committing because it would throw an assertion and we do not have death tests.*/ + t8_cmesh_register_geometry (cmesh); + /* Check validity after committing to circumvent the assertion. + * Should return false since the maximum polynomial degree is exceeded. */ + ASSERT_FALSE (t8_cmesh_validate_geometry (cmesh)); + t8_cmesh_destroy (&cmesh); +} +#endif /* T8_ENABLE_DEBUG */ diff --git a/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear.cxx b/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear.cxx index a3979dad77..ee453aadce 100644 --- a/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear.cxx +++ b/test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear.cxx @@ -66,17 +66,17 @@ class geometry_test: public testing::TestWithParam> { } switch (geom_int) { case T8_GEOMETRY_TYPE_LINEAR: - geom = new t8_geometry_linear (t8_eclass_to_dimension[eclass]); - t8_cmesh_register_geometry (cmesh, t8_eclass_to_dimension[eclass]); + geom = new t8_geometry_linear (); + t8_cmesh_register_geometry (cmesh); break; case T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED: - geom = new t8_geometry_linear_axis_aligned (t8_eclass_to_dimension[eclass]); + geom = new t8_geometry_linear_axis_aligned (); /* Copy last vertex to the second position*/ vertices[3] = vertices[3 * (num_vertices - 1)]; vertices[4] = vertices[3 * (num_vertices - 1) + 1]; vertices[5] = vertices[3 * (num_vertices - 1) + 2]; - t8_cmesh_register_geometry (cmesh, t8_eclass_to_dimension[eclass]); + t8_cmesh_register_geometry (cmesh); break; default: break; @@ -160,3 +160,40 @@ INSTANTIATE_TEST_SUITE_P ( t8_gtest_geometry, geometry_test, ::testing::Combine (::testing::Values (T8_GEOMETRY_TYPE_LINEAR, T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED), AllEclasses), print_test); + +#ifdef T8_ENABLE_DEBUG +TEST (test_geometry_linear, incompatible_geometry) +{ + t8_cmesh_t cmesh; + + t8_debugf ("Testing geometry compatibility checking for linear axis aligned geometry.\n"); + + /* Build a simple set geometries for the tree. */ + t8_cmesh_init (&cmesh); + t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD); + t8_cmesh_set_tree_vertices (cmesh, 0, *t8_element_corner_ref_coords[T8_ECLASS_QUAD], 4); + /* Commit the cmesh */ + t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); + /* Register the t8_geometry_linear_axis_aligned geometry to this cmesh. */ + t8_cmesh_register_geometry (cmesh); + /* Should return true since the t8_geometry_linear_axis_aligned geometry is compatible with quads. */ + ASSERT_TRUE (t8_cmesh_validate_geometry (cmesh)); + t8_cmesh_destroy (&cmesh); + + /* Build a simple set geometries for the tree. */ + t8_cmesh_init (&cmesh); + t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TRIANGLE); + t8_cmesh_set_tree_vertices (cmesh, 0, *t8_element_corner_ref_coords[T8_ECLASS_TRIANGLE], 3); + t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_QUAD); + t8_cmesh_set_tree_vertices (cmesh, 1, *t8_element_corner_ref_coords[T8_ECLASS_QUAD], 4); + /* Commit the cmesh */ + t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); + /* Register the linear axis aligned geometry to this cmesh. + * We register it after committing because it would throw an assertion and do not have death tests.*/ + t8_cmesh_register_geometry (cmesh); + /* Check validity after committing to circumvent the assertion. + * Should return false since the t8_geometry_linear_axis_aligned geometry is not compatible with triangles. */ + ASSERT_FALSE (t8_cmesh_validate_geometry (cmesh)); + t8_cmesh_destroy (&cmesh); +} +#endif /* T8_ENABLE_DEBUG */ diff --git a/test/t8_geometry/t8_gtest_geometry_handling.cxx b/test/t8_geometry/t8_gtest_geometry_handling.cxx index 3591972a8e..55028a7160 100644 --- a/test/t8_geometry/t8_gtest_geometry_handling.cxx +++ b/test/t8_geometry/t8_gtest_geometry_handling.cxx @@ -54,19 +54,15 @@ TEST (test_geometry, test_geometry_handler_register) t8_debugf ("Testing geometry handler register and get geometry.\n"); /* Throw every implemented geometry at the handler and let it search for it. */ std::vector geometries; - for (int idim = 0; idim <= T8_ECLASS_MAX_DIM; ++idim) { - /* Register the geometries with dimension. */ - geometries.push_back (geom_handler.register_geometry (idim)); - geometries.push_back (geom_handler.register_geometry (idim)); + geometries.push_back (geom_handler.register_geometry ()); + geometries.push_back (geom_handler.register_geometry ()); #if T8_WITH_OCC - geometries.push_back (geom_handler.register_geometry (idim)); + geometries.push_back (geom_handler.register_geometry ()); #endif /* T8_WITH_OCC */ - geometries.push_back (geom_handler.register_geometry (idim, "analytic_geom")); - geometries.push_back (geom_handler.register_geometry (idim)); - geometries.push_back (geom_handler.register_geometry (idim)); - } - /* Register the geometries without dimension. */ + geometries.push_back (geom_handler.register_geometry ("analytic_geom")); + geometries.push_back (geom_handler.register_geometry ()); + geometries.push_back (geom_handler.register_geometry ()); geometries.push_back (geom_handler.register_geometry ()); geometries.push_back (geom_handler.register_geometry ()); geometries.push_back (geom_handler.register_geometry ()); @@ -83,9 +79,6 @@ TEST (test_geometry, test_geometry_handler_register) /* The hash should also be equal. */ ASSERT_EQ (found_geom->t8_geom_get_hash (), geom->t8_geom_get_hash ()) << "Could not find geometry with hash " << geom->t8_geom_get_hash (); - /* Same for the dimension */ - ASSERT_EQ (found_geom->t8_geom_get_dimension (), geom->t8_geom_get_dimension ()) - << "Could not find geometry with dimension " << geom->t8_geom_get_dimension (); } /* Check that we can find the geometries by hash. */ @@ -97,9 +90,6 @@ TEST (test_geometry, test_geometry_handler_register) /* The name should also be equal. */ ASSERT_EQ (found_geom->t8_geom_get_name (), geom->t8_geom_get_name ()) << "Could not find geometry with name " << geom->t8_geom_get_name (); - /* Same for the dimension */ - ASSERT_EQ (found_geom->t8_geom_get_dimension (), geom->t8_geom_get_dimension ()) - << "Could not find geometry with dimension " << geom->t8_geom_get_dimension (); } /* Try to find a different geometry via the name. Must return nullptr. */ @@ -120,10 +110,12 @@ TEST (test_geometry, cmesh_two_trees_and_geometries) /* Build a simple 2 tree cmesh and set geometries for the trees. */ t8_cmesh_init (&cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD); + /* We will assign a linear geometry, so we need vertices. */ + t8_cmesh_set_tree_vertices (cmesh, 0, *t8_element_corner_ref_coords[T8_ECLASS_QUAD], 4); t8_cmesh_set_tree_class (cmesh, 1, T8_ECLASS_TRIANGLE); /* Register the linear geometry and zero geometry to this cmesh. */ - auto linear_geom = t8_cmesh_register_geometry (cmesh, 2); - auto zero_geom = t8_cmesh_register_geometry (cmesh, 2); + auto linear_geom = t8_cmesh_register_geometry (cmesh); + auto zero_geom = t8_cmesh_register_geometry (cmesh); /* Set the id geometry for the trees. */ t8_cmesh_set_tree_geometry (cmesh, 0, linear_geom); t8_cmesh_set_tree_geometry (cmesh, 1, zero_geom); @@ -138,9 +130,6 @@ TEST (test_geometry, cmesh_two_trees_and_geometries) /* Name should also be equal. */ ASSERT_EQ (found_geom->t8_geom_get_name (), linear_geom->t8_geom_get_name ()) << "Could not find linear tree geometry at tree 0."; - /* Same for the dimension */ - ASSERT_EQ (found_geom->t8_geom_get_dimension (), linear_geom->t8_geom_get_dimension ()) - << "Could not find linear tree geometry at tree 0."; found_geom = t8_cmesh_get_tree_geometry (cmesh, 1); /* Hash should be equal. */ @@ -149,9 +138,6 @@ TEST (test_geometry, cmesh_two_trees_and_geometries) /* Name should also be equal. */ ASSERT_EQ (found_geom->t8_geom_get_name (), zero_geom->t8_geom_get_name ()) << "Could not find zero tree geometry at tree 0."; - /* Same for the dimension */ - ASSERT_EQ (found_geom->t8_geom_get_dimension (), zero_geom->t8_geom_get_dimension ()) - << "Could not find zero tree geometry at tree 0."; /* clean-up */ t8_cmesh_destroy (&cmesh); @@ -163,11 +149,11 @@ TEST (test_geometry, cmesh_geometry_unique) t8_debugf ("Testing cmesh tree geometry get with unique geometry.\n"); - /* Build a simple 2 tree cmesh and set geometries for the trees. */ + /* Build a simple 1 tree cmesh and set geometry for the trees. */ t8_cmesh_init (&cmesh); t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD); /* Register the linear_geometry to this cmesh. */ - auto provided_geom = t8_cmesh_register_geometry (cmesh, 2); + auto provided_geom = t8_cmesh_register_geometry (cmesh); /* Commit the cmesh */ t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); diff --git a/test/t8_geometry/t8_gtest_point_inside.cxx b/test/t8_geometry/t8_gtest_point_inside.cxx index da28c40a05..c12f634ac2 100644 --- a/test/t8_geometry/t8_gtest_point_inside.cxx +++ b/test/t8_geometry/t8_gtest_point_inside.cxx @@ -56,7 +56,7 @@ TEST (t8_point_inside, test_point_inside_specific_triangle) t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TRIANGLE); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 3); /* We use standard linear geometry */ - t8_cmesh_register_geometry (cmesh, 2); + t8_cmesh_register_geometry (cmesh); t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), 0, 0, sc_MPI_COMM_WORLD); @@ -97,7 +97,7 @@ TEST (t8_point_inside, test_point_inside_specific_quad) t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD); t8_cmesh_set_tree_vertices (cmesh, 0, vertices, 4); /* We use standard linear geometry */ - t8_cmesh_register_geometry (cmesh, 2); + t8_cmesh_register_geometry (cmesh); t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD); t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), 0, 0, sc_MPI_COMM_WORLD); diff --git a/tutorials/CMakeLists.txt b/tutorials/CMakeLists.txt index ec38320344..8e749f3854 100644 --- a/tutorials/CMakeLists.txt +++ b/tutorials/CMakeLists.txt @@ -4,13 +4,35 @@ function( add_t8_tutorial ) set( multiValueArgs "SOURCES" ) cmake_parse_arguments( ADD_T8_TUTORIAL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + # Get the path of the first file listed in the SOURCES list and use it to determine the build directory. + # The executable will be build in the same directory as the first source file. + list(GET ADD_T8_TUTORIAL_SOURCES 0 FIRST_SOURCE) + get_filename_component(TUTORIAL_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/${FIRST_SOURCE}" DIRECTORY) + file(RELATIVE_PATH TUTORIAL_RELATIVE_DIR "${CMAKE_SOURCE_DIR}" "${TUTORIAL_SOURCE_DIR}") + set(TUTORIAL_BUILD_DIR "${CMAKE_BINARY_DIR}/${TUTORIAL_RELATIVE_DIR}") + add_executable( ${ADD_T8_TUTORIAL_NAME} ${ADD_T8_TUTORIAL_SOURCES} ) target_link_libraries( ${ADD_T8_TUTORIAL_NAME} PRIVATE T8 SC::SC ) target_include_directories( ${ADD_T8_TUTORIAL_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/.. ) + + set_target_properties(${ADD_T8_TUTORIAL_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${TUTORIAL_BUILD_DIR}" + LIBRARY_OUTPUT_DIRECTORY "${TUTORIAL_BUILD_DIR}" + ARCHIVE_OUTPUT_DIRECTORY "${TUTORIAL_BUILD_DIR}" + ) + + if( T8CODE_EXPORT_COMPILE_COMMANDS ) + set_target_properties( ${ADD_T8_TUTORIAL_NAME} PROPERTIES EXPORT_COMPILE_COMMANDS ON ) + endif( T8CODE_EXPORT_COMPILE_COMMANDS ) install( TARGETS ${ADD_T8_TUTORIAL_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin ) endfunction() +#copy tutorial files to the exact same location in the builddir as they are in the source dir +function( copy_tutorial_file TUTORIAL_FILE_NAME_SUBPATH ) + configure_file(${CMAKE_CURRENT_LIST_DIR}/${TUTORIAL_FILE_NAME_SUBPATH} ${CMAKE_CURRENT_BINARY_DIR}/${TUTORIAL_FILE_NAME_SUBPATH} COPYONLY) +endfunction() + add_t8_tutorial( NAME t8_step0_helloworld SOURCES general/t8_step0_helloworld.cxx ) add_t8_tutorial( NAME t8_step1_coarsemesh SOURCES general/t8_step1_coarsemesh.cxx ) add_t8_tutorial( NAME t8_step2_uniform_forest SOURCES general/t8_step2_uniform_forest.cxx ) @@ -21,4 +43,9 @@ add_t8_tutorial( NAME t8_step6_stencil SOURCES general/t8_step6 add_t8_tutorial( NAME t8_step7_interpolation SOURCES general/t8_step7_main.cxx general/t8_step7_interpolation.cxx ) add_t8_tutorial( NAME t8_tutorial_build_cmesh SOURCES general/t8_tutorial_build_cmesh.cxx general/t8_tutorial_build_cmesh_main.cxx) add_t8_tutorial( NAME t8_tutorial_search SOURCES general/t8_tutorial_search.cxx general/t8_step3_adapt_forest.cxx ) -add_t8_tutorial( NAME t8_features_curved_meshes SOURCES features/t8_features_curved_meshes.cxx) \ No newline at end of file +add_t8_tutorial( NAME t8_features_curved_meshes SOURCES features/t8_features_curved_meshes.cxx) + +copy_tutorial_file (features/t8_features_curved_meshes_generate_cmesh_hex.geo) +copy_tutorial_file (features/t8_features_curved_meshes_generate_cmesh_quad.geo) +copy_tutorial_file (features/t8_features_curved_meshes_generate_cmesh_tet.geo) +copy_tutorial_file (features/t8_features_curved_meshes_generate_cmesh_tri.geo) diff --git a/tutorials/features/t8_features_curved_meshes.cxx b/tutorials/features/t8_features_curved_meshes.cxx index 1e9bb47078..9c3f6cffb4 100644 --- a/tutorials/features/t8_features_curved_meshes.cxx +++ b/tutorials/features/t8_features_curved_meshes.cxx @@ -393,8 +393,8 @@ main (int argc, char **argv) /* initialize command line argument parser */ opt = sc_options_new (argv[0]); sc_options_add_switch (opt, 'h', "help", &helpme, "Display a short help message."); - sc_options_add_string (opt, 'f', "fileprefix", &fileprefix, "./naca6412", - "Fileprefix of the msh and brep files. Default: \"./naca6412\""); + sc_options_add_string (opt, 'f', "fileprefix", &fileprefix, "./airfoil_windtunnel_hexahedra", + "Fileprefix of the msh and brep files. Default: \"./airfoil_windtunnel_hexahedra\""); sc_options_add_int (opt, 'd', "dimension", &dim, 3, "The dimension of the mesh. Default: 3"); sc_options_add_switch (opt, 'g', "geometry", &geometry, "Refine the forest based on the geometries the elements lie on. " @@ -427,7 +427,7 @@ main (int argc, char **argv) if (!plane && !geometry) { t8_global_productionf ("%s\n", help); t8_global_productionf ("\n\tERROR: Wrong usage.\n" - "\tPlease specify either the '-p' or the '-s' option as described above.\n\n"); + "\tPlease specify either the '-p' or the '-g' option as described above.\n\n"); } else { t8_global_productionf ("\n\tERROR: Wrong usage.\n\n"); diff --git a/tutorials/general/t8_step0_helloworld.cxx b/tutorials/general/t8_step0_helloworld.cxx index 8f3a533d25..db49959ec3 100644 --- a/tutorials/general/t8_step0_helloworld.cxx +++ b/tutorials/general/t8_step0_helloworld.cxx @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* See also: https://github.com/holke/t8code/wiki/Step-0---Hello-World +/* See also: https://github.com/DLR-AMR/t8code/wiki/Step-0---Hello-World * * In this example we initialize t8code and print a small welcome message. * This is the t8code equivalent of HelloWorld. */ diff --git a/tutorials/general/t8_step1_coarsemesh.cxx b/tutorials/general/t8_step1_coarsemesh.cxx index 8723922c89..c21a7b26c9 100644 --- a/tutorials/general/t8_step1_coarsemesh.cxx +++ b/tutorials/general/t8_step1_coarsemesh.cxx @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* See also: https://github.com/holke/t8code/wiki/Step-1---Creating-a-coarse-mesh +/* See also: https://github.com/DLR-AMR/t8code/wiki/Step-1---Creating-a-coarse-mesh * * In this example we build a coarse mesh with a cube geometry. * The cube is meshed with 6 coarse tetrahedra. diff --git a/tutorials/general/t8_step2_uniform_forest.cxx b/tutorials/general/t8_step2_uniform_forest.cxx index 40bc03e2ed..8f50c99f2f 100644 --- a/tutorials/general/t8_step2_uniform_forest.cxx +++ b/tutorials/general/t8_step2_uniform_forest.cxx @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* See also: https://github.com/holke/t8code/wiki/Step-2---Creating-a-uniform-forest +/* See also: https://github.com/DLR-AMR/t8code/wiki/Step-2---Creating-a-uniform-forest * * After we learned how to create a cmesh in step1, we will * now build our first partitioned forest, get its local and global diff --git a/tutorials/general/t8_step4_partition_balance_ghost.cxx b/tutorials/general/t8_step4_partition_balance_ghost.cxx index 2c75649751..c844ff59d8 100644 --- a/tutorials/general/t8_step4_partition_balance_ghost.cxx +++ b/tutorials/general/t8_step4_partition_balance_ghost.cxx @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* See also: https://github.com/holke/t8code/wiki/Step-4---Partition,-Balance,-Ghost +/* See also: https://github.com/DLR-AMR/t8code/wiki/Step-4---Partition,-Balance,-Ghost * * This is step4 of the t8code tutorials. * After generating a coarse mesh (step1), building a uniform forest diff --git a/tutorials/general/t8_step5_element_data.cxx b/tutorials/general/t8_step5_element_data.cxx index 25f3cda356..ad39d288de 100644 --- a/tutorials/general/t8_step5_element_data.cxx +++ b/tutorials/general/t8_step5_element_data.cxx @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* See also: https://github.com/holke/t8code/wiki/Step-5---Store-element-data +/* See also: https://github.com/DLR-AMR/t8code/wiki/Step-5---Store-element-data * * This is step5 of the t8code tutorials. * In the following we will store data in the individual elements of our forest. diff --git a/tutorials/general/t8_step5_element_data_c_interface.c b/tutorials/general/t8_step5_element_data_c_interface.c index a32596f4ce..b10d637696 100644 --- a/tutorials/general/t8_step5_element_data_c_interface.c +++ b/tutorials/general/t8_step5_element_data_c_interface.c @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* See also: https://github.com/holke/t8code/wiki/Step-5---Store-element-data +/* See also: https://github.com/DLR-AMR/t8code/wiki/Step-5---Store-element-data * * This is step5 of the t8code tutorials using the C interface of t8code. * In the following we will store data in the individual elements of our forest. diff --git a/tutorials/general/t8_tutorial_build_cmesh.cxx b/tutorials/general/t8_tutorial_build_cmesh.cxx index 3ca1c67f79..122636fc49 100644 --- a/tutorials/general/t8_tutorial_build_cmesh.cxx +++ b/tutorials/general/t8_tutorial_build_cmesh.cxx @@ -157,7 +157,7 @@ t8_cmesh_new_periodic_hybrid_2d (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* 3. Definition of the geometry */ - t8_cmesh_register_geometry (cmesh, 2); + t8_cmesh_register_geometry (cmesh); ; /* Use linear geometry */ /* 4. Definition of the classes of the different trees */ @@ -253,7 +253,7 @@ t8_cmesh_new_hybrid_gate_3d (sc_MPI_Comm comm) * t8_cmesh_init (&cmesh); * * // 3. Definition of the geometry - * t8_cmesh_register_geometry (cmesh, 3);; // Use linear geometry + * t8_cmesh_register_geometry (cmesh); // Use linear geometry * * // 4. Definition of the classes of the different trees * t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_TET); @@ -300,7 +300,7 @@ t8_cmesh_new_hybrid_gate_3d (sc_MPI_Comm comm) t8_cmesh_init (&cmesh); /* Definition of the geometry */ - t8_cmesh_register_geometry (cmesh, 3); + t8_cmesh_register_geometry (cmesh); /* Use linear geometry */ /* Defitition of the classes of the different trees */ @@ -457,8 +457,8 @@ int t8_tutorial_build_cmesh_main (int argc, char **argv) { /* The prefix for our output files. */ - const char *prefix_2D = "t8_step8_user_defined_mesh_2D"; - const char *prefix_3D = "t8_step8_user_defined_mesh_3D"; + const char *prefix_2D = "t8_user_defined_mesh_2D"; + const char *prefix_3D = "t8_user_defined_mesh_3D"; /* * Initialization. diff --git a/tutorials/general/t8_tutorial_search.cxx b/tutorials/general/t8_tutorial_search.cxx index 8a056468e9..adf6164192 100644 --- a/tutorials/general/t8_tutorial_search.cxx +++ b/tutorials/general/t8_tutorial_search.cxx @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* See also: https://github.com/holke/t8code/wiki/Tutorial:-Search +/* See also: https://github.com/DLR-AMR/t8code/wiki/Tutorial:-Search * In this tutorial we discuss t8code's search algorithm. * search is a powerful tool to identify leaf elements that match a given condition * and execute a function on them.