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/mattermost_issue.yml b/.github/workflows/mattermost_issue.yml index b118ebb084..a0126646b5 100644 --- a/.github/workflows/mattermost_issue.yml +++ b/.github/workflows/mattermost_issue.yml @@ -44,20 +44,26 @@ jobs: - name: debug_before_build run: echo ${{ env.message_build}} # build the message depending on different types of events and event actions. Message is written into mattermost.json + - name: dispatch_run + if: github.event_name == 'workflow_dispatch' + run: | + echo message_build=1 >> $GITHUB_ENV && + echo message_content='User ${{github.actor}} triggered the workflow_dispatch' >> $GITHUB_ENV - name: closed_message if: github.event.action == 'closed' run: | echo message_build=1 >> $GITHUB_ENV && - echo message_content='Issue ${{ github.event.issue.number }} has been closed. See ${{ github.event.issue.html_url }} for more details.' >> $GITHUB_ENV -# Would like to have this message read "User X closed issue ...". -# How can we get the user name? Tried ${{ github.event.issue.user.name }} and others, did not work. + echo message_content='User ${{ github.actor }} closed issue ${{ github.event.issue.number }}. See ${{ github.event.issue.html_url }} for more details.' >> $GITHUB_ENV - name: opened_message - if: github.event.action == 'opened' || github.event.action == 'reopened' + if: github.event.action == 'opened' + run: | + echo message_build=1 >> $GITHUB_ENV && + echo message_content='User ${{ github.actor }} opened issue ${{ github.event.issue.number }}. See ${{ github.event.issue.html_url }} for more details.' >> $GITHUB_ENV + - name: reopened_message + if: github.event.action == 'reopened' run: | echo message_build=1 >> $GITHUB_ENV && - echo message_content='Issue ${{ github.event.issue.number }} was (re-)opened. See ${{ github.event.issue.html_url }} for more details.' >> $GITHUB_ENV -# Would like to have this message read "User X (re-)opened issue ...". -# How can we get the user name? Tried ${{ github.event.issue.user.name }} and others, did not work. + echo message_content='User ${{ github.actor }} reopened issue ${{ github.event.issue.number }}. See ${{ github.event.issue.html_url }} for more details.' >> $GITHUB_ENV - name: debug_after_build run: echo ${{ env.message_build }} # if a message has been written send the message to the mattermost-channel described in the secrets 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/.typos.toml b/.typos.toml index d67249fee1..6ed99410d9 100644 --- a/.typos.toml +++ b/.typos.toml @@ -3,4 +3,4 @@ eles = "eles" packageid = "packageid" [files] -extend-exclude = ["scripts/t8indent", "thirdparty/", "t8code_logo.png"] +extend-exclude = ["scripts/t8indent", "thirdparty/", "t8code_logo.png", "cmake/FindOpenCASCADE.cmake"] diff --git a/CMakeLists.txt b/CMakeLists.txt index 48d4892e39..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 ) @@ -45,8 +54,15 @@ set( CMAKE_CXX_STANDARD 17 ) set( CMAKE_CXX_STANDARD_REQUIRED ON ) 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() @@ -55,17 +71,32 @@ if( T8CODE_ENABLE_MPI ) endif() if( T8CODE_ENABLE_VTK ) - find_package( VTK REQUIRED ) -endif() + 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) +endif( T8CODE_ENABLE_VTK ) if( T8CODE_ENABLE_OCC ) - find_package( OpenCASCADE REQUIRED ) -endif() + find_package( OpenCASCADE REQUIRED COMPONENTS + TKBO TKPrim TKTopAlgo + TKGeomAlgo TKBRep + TKG3d TKG2d TKMath TKernel ) + if(OpenCASCADE_FOUND) + message("Found OpenCASCADE") + endif (OpenCASCADE_FOUND) +endif( T8CODE_ENABLE_OCC ) if( T8CODE_ENABLE_NETCDF ) find_package( netCDF REQUIRED ) - include(cmake/CheckNetCDFPar.cmake) -endif() + if(netCDF_FOUND) + message("Found netCDF") + include(cmake/CheckNetCDFPar.cmake) + 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" ) @@ -111,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/benchmarks/ExtremeScaling/bunny.cxx b/benchmarks/ExtremeScaling/bunny.cxx index 278f6c20fb..25a53a3f9c 100644 --- a/benchmarks/ExtremeScaling/bunny.cxx +++ b/benchmarks/ExtremeScaling/bunny.cxx @@ -24,7 +24,8 @@ #include #include #include -#include +#include + #include #include #include diff --git a/benchmarks/time_forest_partition.cxx b/benchmarks/time_forest_partition.cxx index 4c0c7b1356..674ee56734 100644 --- a/benchmarks/time_forest_partition.cxx +++ b/benchmarks/time_forest_partition.cxx @@ -28,7 +28,8 @@ #include #include #include -#include +#include + #include #include #include @@ -420,11 +421,12 @@ main (int argc, char *argv[]) /* check for wrong usage of arguments */ if (first_argc < 0 || first_argc != argc || dim < 2 || dim > 3 || (cmeshfileprefix == NULL && mshfileprefix == NULL && test_tet == 0 && test_cad_cylinder == 0 - && test_linear_cylinder == 0 && test_hybrid_cube == 0 && test_hex_cube == 0 ) + && test_linear_cylinder == 0 && test_hybrid_cube == 0 && test_hex_cube == 0) || stride <= 0 || (num_files - 1) * stride >= mpisize || cfl < 0 || T <= 0 || test_tet + test_linear_cylinder + test_cad_cylinder + test_hybrid_cube + test_hex_cube > 1 || (cmesh_level >= 0 && (!test_linear_cylinder && !test_cad_cylinder && !test_hybrid_cube && !test_hex_cube)) - || ((mshfileprefix != NULL || cmeshfileprefix != NULL) && (test_linear_cylinder || test_cad_cylinder || test_tet || test_hybrid_cube || test_hex_cube)) + || ((mshfileprefix != NULL || cmeshfileprefix != NULL) + && (test_linear_cylinder || test_cad_cylinder || test_tet || test_hybrid_cube || test_hex_cube)) || (mshfileprefix == NULL && use_cad)) { sc_options_print_usage (t8_get_package_id (), SC_LP_ERROR, opt, NULL); return 1; @@ -459,12 +461,12 @@ main (int argc, char *argv[]) sc_intpow (2, cmesh_level), sc_intpow (2, cmesh_level), test_cad_cylinder); test_linear_cylinder ? vtu_prefix = "test_linear_cylinder" : vtu_prefix = "test_cad_cylinder"; } - else if (test_hybrid_cube){ + else if (test_hybrid_cube) { cmesh = t8_cmesh_new_hypercube_hybrid (sc_MPI_COMM_WORLD, 0, 0); vtu_prefix = "test_hypercube_hybrid"; } - else if (test_hex_cube){ - cmesh = t8_cmesh_new_hypercube(T8_ECLASS_HEX, sc_MPI_COMM_WORLD, 0, 0, 0); + else if (test_hex_cube) { + cmesh = t8_cmesh_new_hypercube (T8_ECLASS_HEX, sc_MPI_COMM_WORLD, 0, 0, 0); vtu_prefix = "test_hypercube_hex"; } else { diff --git a/benchmarks/time_partition.cxx b/benchmarks/time_partition.cxx index df5c8704bf..0a37576257 100644 --- a/benchmarks/time_partition.cxx +++ b/benchmarks/time_partition.cxx @@ -26,7 +26,8 @@ #include #include #include -#include +#include + #include #include "t8_cmesh/t8_cmesh_types.h" #include 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 new file mode 100644 index 0000000000..6eb5c10c22 --- /dev/null +++ b/cmake/FindOpenCASCADE.cmake @@ -0,0 +1,140 @@ +# Taken and adapted from the heekscad project: https://github.com/Heeks + +# HeeksCAD is covered by the new BSD license + +# Copyright (c) 2008, Daniel Heeks +# All rights reserved. + +# Once done, this will define +# OpenCASCADE_FOUND - true if OCC has been found +# OpenCASCADE_INCLUDE_DIR - the OCC include dir +# OpenCASCADE_LIBRARIES - names of OCC libraries +# OpenCASCADE_LINK_DIRECTORY - location of OCC libraries + +# ${OpenCASCADE_FOUND} is cached, so once OCC is found this block shouldn't have to run again +IF( NOT OpenCASCADE_FOUND ) + + set(CASROOT $ENV{CASROOT} CACHE PATH "Additional include path for package search") + + # 32 bit or 64 bit? + IF( CMAKE_SIZEOF_VOID_P EQUAL 4 ) + IF( _firsttime STREQUAL TRUE ) + MESSAGE( STATUS "This is a 32-bit system." ) + ENDIF( _firsttime STREQUAL TRUE ) + set(BITS 32) + ELSE( CMAKE_SIZEOF_VOID_P EQUAL 4 ) + IF( _firsttime STREQUAL TRUE ) + MESSAGE( STATUS "This is a 64-bit system. Adding appropriate compiler flags for OCC." ) + ENDIF( _firsttime STREQUAL TRUE ) + ADD_DEFINITIONS( -D_OCC64 ) + IF (UNIX) + ADD_DEFINITIONS( -m64 ) + ENDIF (UNIX) + set(BITS 64) + 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 ) + ELSE(UNIX) + IF (WIN32) + 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) + 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 MATCHES "NOTFOUND" ) + SET( OpenCASCADE_FOUND FALSE CACHE BOOL FORCE ) + 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. + # Requiring that all libs be in the same directory reduces the risk. + 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 MATCHES "NOTFOUND") + SET( OpenCASCADE_FOUND FALSE CACHE BOOL FORCE ) + 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 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 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 MATCHES "NOTFOUND" ) + endif(WIN32) + + # everything was found + SET( OpenCASCADE_FOUND TRUE CACHE BOOL "Has OCC been found?" FORCE ) + SET( _firsttime TRUE ) #so that messages are only printed once + MESSAGE( STATUS "Found OCC include dir: ${OpenCASCADE_INCLUDE_DIR}" ) + MESSAGE( STATUS "Found OCC lib dir: ${OpenCASCADE_LINK_DIRECTORY}" ) + if(WIN32) + MESSAGE( STATUS "Found OCC dll dir: ${OpenCASCADE_DLL_DIRECTORY}" ) + endif(WIN32) + +ELSE( NOT OpenCASCADE_FOUND ) + SET( _firsttime FALSE ) #so that messages are only printed once +ENDIF( NOT OpenCASCADE_FOUND ) + +IF( OpenCASCADE_FOUND ) + + # get version + IF(OpenCASCADE_INCLUDE_DIR) + FOREACH(_occ_version_header Standard_Version.hxx) + IF(EXISTS "${OpenCASCADE_INCLUDE_DIR}/${_occ_version_header}") + FILE(STRINGS "${OpenCASCADE_INCLUDE_DIR}/${_occ_version_header}" occ_version_str REGEX "^#define[\t ]+OCC_VERSION_COMPLETE[\t ]+\".*\"") + + STRING(REGEX REPLACE "^#define[\t ]+OCC_VERSION_COMPLETE[\t ]+\"([^\"]*)\".*" "\\1" OCC_VERSION_STRING "${occ_version_str}") + UNSET(occ_version_str) + BREAK() + ENDIF() + ENDFOREACH(_occ_version_header) + IF(NOT ${OpenCASCADE_FIND_VERSION} STREQUAL "") + IF(${OCC_VERSION_STRING} VERSION_LESS ${OpenCASCADE_FIND_VERSION}) + MESSAGE(FATAL_ERROR "The found opencascade version is too old (version ${OCC_VERSION_STRING}). Required is at least version ${OpenCASCADE_FIND_VERSION}.") + ENDIF() + ENDIF() + ENDIF() + IF( _firsttime STREQUAL TRUE ) + MESSAGE(STATUS "OCC Version: ${OCC_VERSION_STRING}") + ENDIF( _firsttime STREQUAL TRUE ) + + IF( DEFINED OpenCASCADE_FIND_COMPONENTS ) + FOREACH( _libname ${OpenCASCADE_FIND_COMPONENTS} ) + #look for libs in OpenCASCADE_LINK_DIRECTORY + FIND_LIBRARY( ${_libname}_OCCLIB ${_libname} ${OpenCASCADE_LINK_DIRECTORY} NO_DEFAULT_PATH) + MARK_AS_ADVANCED( ${_libname}_OCCLIB ) + SET( _foundlib ${${_libname}_OCCLIB} ) + IF( _foundlib STREQUAL ${_libname}_OCCLIB-NOTFOUND ) + MESSAGE( FATAL_ERROR "Cannot find ${_libname}. Is it spelled correctly? Correct capitalization? Do you have another package with similarly-named libraries, installed at ${OpenCASCADE_LINK_DIRECTORY}? (That is where this script thinks the OCC libs are.)" ) + ENDIF( _foundlib STREQUAL ${_libname}_OCCLIB-NOTFOUND ) + SET( OpenCASCADE_LIBRARIES ${OpenCASCADE_LIBRARIES} ${_foundlib} ) + ENDFOREACH( _libname ${OpenCASCADE_FIND_COMPONENTS} ) + + IF (UNIX) + ADD_DEFINITIONS( -DLIN -DLININTEL -DHAVE_CONFIG_H) + ENDIF (UNIX) + + if (WIN32) + ADD_DEFINITIONS( -DWNT ) + endif(WIN32) + + ADD_DEFINITIONS( -DHAVE_IOSTREAM -DHAVE_FSTREAM -DHAVE_LIMITS_H -DHAVE_IOMANIP ) + ELSE( DEFINED OpenCASCADE_FIND_COMPONENTS ) + MESSAGE( AUTHOR_WARNING "Developer must specify required libraries to link against in the cmake file, i.e. find_package( OpenCASCADE REQUIRED COMPONENTS TKernel TKBRep) . Otherwise no libs will be added - linking against ALL OCC libraries is slow!") + ENDIF( DEFINED OpenCASCADE_FIND_COMPONENTS ) +ENDIF( OpenCASCADE_FOUND ) diff --git a/cmake/FindOpenCASCADE.license b/cmake/FindOpenCASCADE.license new file mode 100644 index 0000000000..ec083f29c1 --- /dev/null +++ b/cmake/FindOpenCASCADE.license @@ -0,0 +1,26 @@ +The file FindOpenCASCADE.cmake is taken and adapted from the HeeksCAD project (https://github.com/Heeks/heekscad). +The original file is covered by the new BSD license: + +HeeksCAD is covered by the new BSD license + +Copyright (c) 2008, Daniel Heeks +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Daniel Heeks nor the names of its contributors may be used to endorse + or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file 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/CMakeLists.txt b/doc/CMakeLists.txt index 2e77222ebd..0939b09a69 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -32,7 +32,6 @@ if(T8CODE_BUILD_DOCUMENTATION) endif(T8CODE_BUILD_DOCUMENTATION) if (T8CODE_BUILD_DOCUMENTATION_SPHINX) - set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) find_package(Sphinx REQUIRED) configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) 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 d8a662474a..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 @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include @@ -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/cmesh/t8_cmesh_load_save.cxx b/example/IO/cmesh/t8_cmesh_load_save.cxx index 45f2bfcfc8..c4d2aa8a5d 100644 --- a/example/IO/cmesh/t8_cmesh_load_save.cxx +++ b/example/IO/cmesh/t8_cmesh_load_save.cxx @@ -22,9 +22,9 @@ #include #include -#include -#include +#include #include +#include #include static void diff --git a/example/IO/cmesh/tetgen/t8_forest_from_tetgen.cxx b/example/IO/cmesh/tetgen/t8_forest_from_tetgen.cxx index 313be2947c..b6a86273c7 100644 --- a/example/IO/cmesh/tetgen/t8_forest_from_tetgen.cxx +++ b/example/IO/cmesh/tetgen/t8_forest_from_tetgen.cxx @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/example/IO/cmesh/tetgen/t8_read_tetgen_file.cxx b/example/IO/cmesh/tetgen/t8_read_tetgen_file.cxx index 824722f64a..4089c31dac 100644 --- a/example/IO/cmesh/tetgen/t8_read_tetgen_file.cxx +++ b/example/IO/cmesh/tetgen/t8_read_tetgen_file.cxx @@ -25,7 +25,7 @@ #include #include #include -#include +#include void t8_read_tetgen_file_build_cmesh (const char *prefix, int do_dup, int do_partition) diff --git a/example/IO/cmesh/triangle/t8_read_triangle_file.cxx b/example/IO/cmesh/triangle/t8_read_triangle_file.cxx index c38498e0fc..b1a21c6c08 100644 --- a/example/IO/cmesh/triangle/t8_read_triangle_file.cxx +++ b/example/IO/cmesh/triangle/t8_read_triangle_file.cxx @@ -24,7 +24,8 @@ #include #include #include -#include +#include + #include void diff --git a/example/IO/cmesh/vtk/t8_cmesh_read_from_vtk.cxx b/example/IO/cmesh/vtk/t8_cmesh_read_from_vtk.cxx index af3a6c2713..05a742f18f 100644 --- a/example/IO/cmesh/vtk/t8_cmesh_read_from_vtk.cxx +++ b/example/IO/cmesh/vtk/t8_cmesh_read_from_vtk.cxx @@ -17,7 +17,7 @@ along with t8code; if not, write to the Free Software Foundation, Inc., */ #include -#include +#include #include #include #include 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/advect/t8_advection.cxx b/example/advect/t8_advection.cxx index 5239dafee1..e72603eb68 100644 --- a/example/advect/t8_advection.cxx +++ b/example/advect/t8_advection.cxx @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/example/cmesh/t8_cmesh_create_partitioned.cxx b/example/cmesh/t8_cmesh_create_partitioned.cxx index 0f889e72dd..319ab07a5a 100644 --- a/example/cmesh/t8_cmesh_create_partitioned.cxx +++ b/example/cmesh/t8_cmesh_create_partitioned.cxx @@ -20,7 +20,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include +#include /* Create a coarse mesh that is partitioned across two processes * (if mpisize >= 2). diff --git a/example/cmesh/t8_cmesh_geometry_examples.cxx b/example/cmesh/t8_cmesh_geometry_examples.cxx index 588109d04a..99575d20d1 100644 --- a/example/cmesh/t8_cmesh_geometry_examples.cxx +++ b/example/cmesh/t8_cmesh_geometry_examples.cxx @@ -27,7 +27,8 @@ #include /* Forest definition and basic interface. */ #include /* Forest-related geometry operations. */ #include /* Default refinement scheme. */ -#include /* Write file in vtu file */ +#include +/* Write file in vtu file */ #include #include @@ -114,17 +115,17 @@ main (int argc, char **argv) const char *prefix_forest = "t8_quadrangulated_disk_forest"; const int uniform_level = 5; - const double radius = 1.0; + const double radius = 5.0; t8_cmesh_t cmesh = t8_cmesh_new_quadrangulated_disk (radius, comm); t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); - t8_global_productionf ("Wrote %s.\n", prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); t8_write_forest_to_vtu (forest, prefix_forest); - t8_global_productionf ("Wrote %s.\n\n", prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); t8_forest_unref (&forest); } @@ -141,10 +142,10 @@ main (int argc, char **argv) t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); - t8_global_productionf ("Wrote %s.\n", prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); t8_write_forest_to_vtu (forest, prefix_forest); - t8_global_productionf ("Wrote %s.\n\n", prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); t8_forest_unref (&forest); } @@ -161,10 +162,30 @@ main (int argc, char **argv) t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); - t8_global_productionf ("Wrote %s.\n", prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); t8_write_forest_to_vtu (forest, prefix_forest); - t8_global_productionf ("Wrote %s.\n\n", prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); + + t8_forest_unref (&forest); + } + + { + const char *prefix_cmesh = "t8_triangulated_spherical_surface_cube_cmesh"; + const char *prefix_forest = "t8_triangulated_spherical_surface_cube_forest"; + + const int uniform_level = 4; + const double radius = 42.0; + + t8_cmesh_t cmesh = t8_cmesh_new_triangulated_spherical_surface_cube (radius, comm); + + t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); + + t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); + + t8_write_forest_to_vtu (forest, prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); t8_forest_unref (&forest); } @@ -181,10 +202,10 @@ main (int argc, char **argv) t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); - t8_global_productionf ("Wrote %s.\n", prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); t8_write_forest_to_vtu (forest, prefix_forest); - t8_global_productionf ("Wrote %s.\n\n", prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); t8_forest_unref (&forest); } @@ -206,10 +227,10 @@ main (int argc, char **argv) t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); - t8_global_productionf ("Wrote %s.\n", prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); t8_write_forest_to_vtu (forest, prefix_forest); - t8_global_productionf ("Wrote %s.\n\n", prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); t8_forest_unref (&forest); } @@ -218,7 +239,7 @@ main (int argc, char **argv) const char *prefix_cmesh = "t8_prismed_spherical_shell_octahedron_cmesh"; const char *prefix_forest = "t8_prismed_spherical_shell_octahedron_forest"; - const int uniform_level = 3; + const int uniform_level = 2; const double inner_radius = 42.0; const double shell_thickness = 5.0; const int num_levels = 2; @@ -230,10 +251,10 @@ main (int argc, char **argv) t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); - t8_global_productionf ("Wrote %s.\n", prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); t8_write_forest_to_vtu (forest, prefix_forest); - t8_global_productionf ("Wrote %s.\n\n", prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); t8_forest_unref (&forest); } @@ -242,7 +263,7 @@ main (int argc, char **argv) const char *prefix_cmesh = "t8_prismed_spherical_shell_icosahedron_cmesh"; const char *prefix_forest = "t8_prismed_spherical_shell_icosahedron_forest"; - const int uniform_level = 3; + const int uniform_level = 2; const double inner_radius = 42.0; const double shell_thickness = 5.0; const int num_levels = 2; @@ -254,10 +275,10 @@ main (int argc, char **argv) t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); - t8_global_productionf ("Wrote %s.\n", prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); t8_write_forest_to_vtu (forest, prefix_forest); - t8_global_productionf ("Wrote %s.\n\n", prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); t8_forest_unref (&forest); } @@ -267,17 +288,17 @@ main (int argc, char **argv) const char *prefix_forest = "t8_cubed_sphere_forest"; const int uniform_level = 2; - const double radius = 1.0; + const double radius = 5.0; t8_cmesh_t cmesh = t8_cmesh_new_cubed_sphere (radius, comm); t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), uniform_level, 0, comm); t8_cmesh_vtk_write_file (cmesh, prefix_cmesh); - t8_global_productionf ("Wrote %s.\n", prefix_cmesh); + t8_global_productionf ("Wrote %s.pvtu\n", prefix_cmesh); t8_write_forest_to_vtu (forest, prefix_forest); - t8_global_productionf ("Wrote %s.\n\n", prefix_forest); + t8_global_productionf ("Wrote %s.pvtu\n\n", prefix_forest); t8_forest_unref (&forest); } diff --git a/example/cmesh/t8_cmesh_hypercube_pad.cxx b/example/cmesh/t8_cmesh_hypercube_pad.cxx index 14c3222052..8e9ca6021b 100644 --- a/example/cmesh/t8_cmesh_hypercube_pad.cxx +++ b/example/cmesh/t8_cmesh_hypercube_pad.cxx @@ -22,11 +22,11 @@ #include #include -#include +#include + #include #include #include -#include int main (int argc, char **argv) { diff --git a/example/cmesh/t8_cmesh_partition.cxx b/example/cmesh/t8_cmesh_partition.cxx index a2dec53aa0..fe2d8d7755 100644 --- a/example/cmesh/t8_cmesh_partition.cxx +++ b/example/cmesh/t8_cmesh_partition.cxx @@ -23,7 +23,8 @@ #include #include #include -#include +#include + #include #include #include diff --git a/example/forest/t8_test_face_iterate.cxx b/example/forest/t8_test_face_iterate.cxx index 6dacc5ecc1..b469afbc0f 100644 --- a/example/forest/t8_test_face_iterate.cxx +++ b/example/forest/t8_test_face_iterate.cxx @@ -31,9 +31,9 @@ #include #include #include -#include #include #include +#include typedef struct { diff --git a/example/forest/t8_test_ghost.cxx b/example/forest/t8_test_ghost.cxx index cc3833d0cb..63468d9faa 100644 --- a/example/forest/t8_test_ghost.cxx +++ b/example/forest/t8_test_ghost.cxx @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/example/forest/t8_test_ghost_large_level_diff.cxx b/example/forest/t8_test_ghost_large_level_diff.cxx index e2e93a40c9..02481ff90a 100644 --- a/example/forest/t8_test_ghost_large_level_diff.cxx +++ b/example/forest/t8_test_ghost_large_level_diff.cxx @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include 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/check_if_file_indented.scp b/scripts/check_if_file_indented.scp index bf5f402ee7..8c9b8d85a5 100755 --- a/scripts/check_if_file_indented.scp +++ b/scripts/check_if_file_indented.scp @@ -31,8 +31,7 @@ FORMAT_OPTIONS="--dry-run --Werror --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/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 b562792f1d..c5a4c823b5 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 @@ -50,13 +54,13 @@ endif() if( T8CODE_ENABLE_VTK ) target_compile_definitions( T8 PUBLIC T8_VTK_VERSION_USED="${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}" ) target_compile_definitions( T8 PUBLIC T8_WITH_VTK=1 ) - target_include_directories( T8 PUBLIC ${VTK_INCLUDE_DIRS} ) + target_include_directories( T8 PUBLIC ${VTK_INCLUDE_DIR} ) target_link_libraries( T8 PUBLIC ${VTK_LIBRARIES} ) endif() if( T8CODE_ENABLE_OCC ) target_compile_definitions( T8 PUBLIC T8_WITH_OCC=1 ) - target_include_directories( T8 PUBLIC ${OpenCASCADE_INCLUDE_DIRS} ) + target_include_directories( T8 PUBLIC ${OpenCASCADE_INCLUDE_DIR} ) target_link_libraries( T8 PUBLIC ${OpenCASCADE_LIBRARIES} ) endif() @@ -86,12 +90,11 @@ target_sources( T8 PRIVATE t8_cmesh/t8_cmesh.cxx t8_cmesh/t8_cmesh_cad.cxx t8_cmesh/t8_cmesh_triangle.cxx - t8_cmesh/t8_cmesh_vtk_writer.c t8_cmesh/t8_cmesh_stash.c 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 @@ -105,7 +108,7 @@ target_sources( T8 PRIVATE t8_forest/t8_forest_adapt.cxx t8_forest/t8_forest_partition.cxx t8_forest/t8_forest.cxx - t8_forest/t8_forest_private.c + t8_forest/t8_forest_private.cxx t8_forest/t8_forest_vtk.cxx t8_forest/t8_forest_ghost.cxx t8_forest/t8_forest_iterate.cxx @@ -148,6 +151,9 @@ target_sources( T8 PRIVATE t8_vtk/t8_vtk_unstructured.cxx t8_vtk/t8_vtk_parallel.cxx t8_vtk/t8_vtk_reader.cxx + t8_vtk/t8_vtk_writer.cxx + t8_vtk/t8_vtk_write_ASCII.cxx + t8_vtk/t8_vtk_writer_helper.cxx ) target_compile_definitions( T8 PUBLIC T8_CMAKE_BUILD ) @@ -177,7 +183,6 @@ install( FILES t8_cmesh_tetgen.h t8_cmesh_triangle.h t8_cmesh_vtk_reader.hxx - t8_cmesh_vtk_writer.h t8_eclass.h t8_element.h t8_element_c_interface.h diff --git a/src/Makefile.am b/src/Makefile.am index e572ef74b1..cf8bb2cffe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,6 @@ libt8_installed_headers = \ src/t8_element_c_interface.h \ src/t8_refcount.h src/t8_cmesh.hxx src/t8_cmesh.h src/t8_cmesh_triangle.h \ src/t8_cmesh_tetgen.h src/t8_cmesh_readmshfile.h \ - src/t8_cmesh_vtk_writer.h \ src/t8_cmesh_vtk_reader.hxx \ src/t8_vec.h \ src/t8_mat.h \ @@ -86,7 +85,8 @@ libt8_installed_headers_geometry_impl = \ libt8_installed_headers_vtk = \ src/t8_vtk/t8_vtk_reader.hxx \ src/t8_vtk/t8_vtk_writer.hxx \ - src/t8_vtk/t8_vtk_types.h + src/t8_vtk/t8_vtk_types.h \ + src/t8_vtk/t8_vtk_writer.h libt8_installed_headers_schemes_default = libt8_installed_headers_default_common = libt8_installed_headers_default_vertex = @@ -108,18 +108,19 @@ libt8_internal_headers = \ src/t8_forest/t8_forest_balance.h src/t8_forest/t8_forest_types.h \ src/t8_forest/t8_forest_private.h \ src/t8_windows.h \ - src/t8_vtk/t8_vtk_writer_helper.hxx + src/t8_vtk/t8_vtk_writer_helper.hxx \ + src/t8_vtk/t8_vtk_write_ASCII.hxx libt8_compiled_sources = \ src/t8.c src/t8_eclass.c src/t8_mesh.c \ src/t8_element.cxx \ src/t8_element_c_interface.cxx \ src/t8_refcount.c src/t8_cmesh/t8_cmesh.cxx \ src/t8_cmesh/t8_cmesh_cad.cxx src/t8_cmesh/t8_cmesh_triangle.cxx \ - src/t8_cmesh/t8_cmesh_vtk_writer.c src/t8_cmesh/t8_cmesh_stash.c \ + src/t8_cmesh/t8_cmesh_stash.c \ 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_partition.cxx\ src/t8_cmesh/t8_cmesh_copy.c src/t8_data/t8_shmem.c \ src/t8_cmesh/t8_cmesh_geometry.cxx \ @@ -141,7 +142,7 @@ libt8_compiled_sources = \ src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.cxx \ src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.cxx \ src/t8_forest/t8_forest_partition.cxx src/t8_forest/t8_forest.cxx \ - src/t8_forest/t8_forest_private.c src/t8_forest/t8_forest_vtk.cxx \ + src/t8_forest/t8_forest_private.c \ src/t8_forest/t8_forest_ghost.cxx src/t8_forest/t8_forest_iterate.cxx \ src/t8_version.c \ src/t8_vtk.c src/t8_forest/t8_forest_balance.cxx \ @@ -151,7 +152,10 @@ libt8_compiled_sources = \ src/t8_vtk/t8_vtk_polydata.cxx \ src/t8_vtk/t8_vtk_unstructured.cxx \ src/t8_vtk/t8_vtk_parallel.cxx \ - src/t8_vtk/t8_vtk_reader.cxx + src/t8_vtk/t8_vtk_reader.cxx \ + src/t8_vtk/t8_vtk_writer.cxx \ + src/t8_vtk/t8_vtk_write_ASCII.cxx \ + src/t8_vtk/t8_vtk_writer_helper.cxx # this variable is used for headers that are not publicly installed 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 f4684d19a3..4ab894c0fb 100644 --- a/src/t8_cmesh/t8_cmesh.cxx +++ b/src/t8_cmesh/t8_cmesh.cxx @@ -124,15 +124,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 */ @@ -400,7 +430,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); } @@ -582,39 +611,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 65dc12751c..1e2abb2089 100644 --- a/src/t8_cmesh/t8_cmesh_commit.cxx +++ b/src/t8_cmesh/t8_cmesh_commit.cxx @@ -84,7 +84,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; @@ -94,6 +94,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); @@ -112,9 +113,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++; } } @@ -167,7 +172,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); @@ -198,7 +203,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; @@ -375,7 +379,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 @@ -473,7 +477,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 45260908cc..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. */ @@ -3114,6 +3112,90 @@ t8_cmesh_new_triangulated_spherical_surface_icosahedron (const double radius, sc return cmesh; } +t8_cmesh_t +t8_cmesh_new_triangulated_spherical_surface_cube (const double radius, sc_MPI_Comm comm) +{ + // Initialization of the mesh. + t8_cmesh_t cmesh; + t8_cmesh_init (&cmesh); + + t8_cmesh_register_geometry (cmesh); + + 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. + + 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]; + t8_eclass_t all_eclasses[ntrees]; + + // Defitition of the tree class. + for (int itree = 0; itree < ntrees; itree++) { + t8_cmesh_set_tree_class (cmesh, itree, T8_ECLASS_TRIANGLE); + all_eclasses[itree] = T8_ECLASS_TRIANGLE; + } + + 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 } }; + + const double face_angles[] = { 0.0, 0.5 * M_PI, M_PI, 1.5 * M_PI }; + const double cube_angles[] = { 0.0, 0.5 * M_PI, 0.5 * M_PI, M_PI, -0.5 * M_PI, -0.5 * M_PI }; + const int cube_rot_axis[] = { 0, 0, 1, 1, 0, 1 }; + + // Set the vertices. + int itree = 0; + for (int icube_rot = 0; icube_rot < ncube_rot; ++icube_rot) { + double cube_rot_mat[3][3]; + double cube_rot_vertices[3][3]; + + if (cube_rot_axis[icube_rot] == 0) { + t8_mat_init_xrot (cube_rot_mat, cube_angles[icube_rot]); + } + else { + t8_mat_init_yrot (cube_rot_mat, cube_angles[icube_rot]); + } + + for (int iface_rot = 0; iface_rot < nface_rot; ++iface_rot) { + double face_rot_mat[3][3]; + double face_rot_vertices[3][3]; + + t8_mat_init_zrot (face_rot_mat, face_angles[iface_rot]); + + // Rotate around z-axis to create a quadratic face. + for (int ivert = 0; ivert < nverts; ivert++) { + t8_mat_mult_vec (face_rot_mat, &(vertices[ivert][0]), &(face_rot_vertices[ivert][0])); + } + + // Rotate to one of the cube's faces. + for (int ivert = 0; ivert < nverts; ivert++) { + t8_mat_mult_vec (cube_rot_mat, &(face_rot_vertices[ivert][0]), &(cube_rot_vertices[ivert][0])); + } + + t8_cmesh_set_tree_vertices (cmesh, itree, (double *) cube_rot_vertices, nverts); + + for (int ivert = 0; ivert < nverts; ivert++) { + for (int icoord = 0; icoord < T8_ECLASS_MAX_DIM; icoord++) { + all_verts[T8_3D_TO_1D (ntrees, T8_ECLASS_MAX_CORNERS, T8_ECLASS_MAX_DIM, itree, ivert, icoord)] + = cube_rot_vertices[ivert][icoord]; + } + } + + ++itree; + } + } + + // Face connectivity. + t8_cmesh_set_join_by_vertices (cmesh, ntrees, all_eclasses, all_verts, NULL, 0); + + // Commit the mesh. + t8_cmesh_commit (cmesh, comm); + return cmesh; +} + t8_cmesh_t t8_cmesh_new_quadrangulated_spherical_surface (const double radius, sc_MPI_Comm comm) { @@ -3121,7 +3203,7 @@ t8_cmesh_new_quadrangulated_spherical_surface (const double radius, sc_MPI_Comm t8_cmesh_t cmesh; t8_cmesh_init (&cmesh); - t8_cmesh_register_geometry (cmesh); /* Use spherical geometry */ + t8_cmesh_register_geometry (cmesh); /* Use spherical geometry */ const int ntrees = 6; /* Number of cmesh elements resp. trees. */ const int nverts = 4; /* Number of cmesh element vertices. */ @@ -3136,8 +3218,8 @@ t8_cmesh_new_quadrangulated_spherical_surface (const double radius, sc_MPI_Comm all_eclasses[itree] = T8_ECLASS_QUAD; } - const double _SQRT3 = 1.7320508075688772; - const double r = radius / _SQRT3; + 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 } }; @@ -3319,12 +3401,105 @@ t8_cmesh_new_prismed_spherical_shell_octahedron (const double inner_radius, cons } t8_cmesh_t -t8_cmesh_new_cubed_spherical_shell (const double inner_radius, const double shell_thickness, const int num_levels, +t8_cmesh_new_cubed_spherical_shell (const double inner_radius, const double shell_thickness, const int num_trees, const int num_layers, sc_MPI_Comm comm) { - return t8_cmesh_new_spherical_shell (T8_ECLASS_HEX, new t8_geometry_cubed_spherical_shell (), - t8_cmesh_new_quadrangulated_spherical_surface, inner_radius, shell_thickness, - num_levels, num_layers, comm); + /* Initialization of the mesh */ + t8_cmesh_t cmesh; + t8_cmesh_init (&cmesh); + + t8_cmesh_register_geometry (cmesh); /* Use spherical geometry. */ + + /* clang-format off */ + const int nrotas = t8_eclass_num_faces[T8_ECLASS_HEX]; /* Number of 3D cmesh elements resp. trees. */ + const int ntrees = nrotas * num_trees * num_trees * num_layers; /* Number of 3D cmesh elements resp. trees. */ + const int nverts = t8_eclass_num_vertices[T8_ECLASS_HEX]; /* Number of vertices per cmesh element. */ + + /* Arrays for the face connectivity computations via vertices. */ + double *all_verts = T8_ALLOC(double, ntrees * T8_ECLASS_MAX_CORNERS * T8_ECLASS_MAX_DIM); + t8_eclass_t *all_eclasses = T8_ALLOC(t8_eclass_t, ntrees); + + /* Defitition of the tree class. */ + for (int itree = 0; itree < ntrees; itree++) { + t8_cmesh_set_tree_class (cmesh, itree, T8_ECLASS_HEX); + all_eclasses[itree] = T8_ECLASS_HEX; + } + + const double outer_radius = inner_radius + shell_thickness; + + const double _CBRT = 1.7320508075688772; + + const double r = inner_radius / _CBRT; + const double R = outer_radius / _CBRT; + + // Vertices of the template hex. + const double vertices[][3] = { + { -r, -r, r }, { r, -r, r }, { -r, r, r }, { r, r, r }, + { -R, -R, R }, { R, -R, R }, { -R, R, R }, { R, R, R } + }; + + const double angles[] = { 0.0 , 0.5 * M_PI, 0.5 * M_PI, M_PI, -0.5 * M_PI, -0.5 * M_PI }; + const int rot_axis[] = { 0, 0, 1, 1, 0, 1 }; + + const double h = 1.0 / num_layers; + const double w = 1.0 / num_trees; + const double l = 1.0 / num_trees; + + int itree = 0; + for (int irot = 0; irot < nrotas; irot++) { + + double rot_mat[3][3]; + + if (rot_axis[irot] == 0) { + t8_mat_init_xrot (rot_mat, angles[irot]); + } + else { + t8_mat_init_yrot (rot_mat, angles[irot]); + } + + for (int k = 0; k < num_layers; k++) { + for (int j = 0; j < num_trees; j++) { + for (int i = 0; i < num_trees; i++) { + const double I = i + 1; + const double J = j + 1; + const double K = k + 1; + double ref_coords[][3] = { + { i*w, j*l, k*h }, { I*w, j*l, k*h }, { i*w, J*l, k*h }, { I*w, J*l, k*h }, + { i*w, j*l, K*h }, { I*w, j*l, K*h }, { i*w, J*l, K*h }, { I*w, J*l, K*h } + }; + + double tile_vertices[8][3]; + t8_geom_compute_linear_geometry (T8_ECLASS_HEX, (double *) vertices, (double *) ref_coords, nverts, (double *) tile_vertices); + + double rot_vertices[8][3]; + for (int ivert = 0; ivert < nverts; ivert++) { + t8_mat_mult_vec (rot_mat, &(tile_vertices[ivert][0]), &(rot_vertices[ivert][0])); + } + + t8_cmesh_set_tree_vertices (cmesh, itree, (double *) rot_vertices, nverts); + + for (int ivert = 0; ivert < nverts; ivert++) { + for (int icoord = 0; icoord < T8_ECLASS_MAX_DIM; icoord++) { + all_verts[T8_3D_TO_1D (ntrees, T8_ECLASS_MAX_CORNERS, T8_ECLASS_MAX_DIM, itree, ivert, icoord)] + = rot_vertices[ivert][icoord]; + } + } + + ++itree; + } + } + } + } + + /* Face connectivity. */ + t8_cmesh_set_join_by_vertices (cmesh, ntrees, all_eclasses, all_verts, NULL, 0); + + T8_FREE (all_verts); + T8_FREE (all_eclasses); + + /* Commit the mesh */ + t8_cmesh_commit (cmesh, comm); + return cmesh; } t8_cmesh_t @@ -3337,12 +3512,13 @@ t8_cmesh_new_cubed_sphere (const double radius, sc_MPI_Comm comm) const double inner_radius = 0.6 * radius; const double outer_radius = radius; - const double SQRT3 = 1.7320508075688772; - const double inner_x = inner_radius / SQRT3; + const double _CBRT = std::cbrt(1.0); + + const double inner_x = inner_radius / _CBRT; const double inner_y = inner_x; const double inner_z = inner_x; - const double outer_x = outer_radius / SQRT3; + const double outer_x = outer_radius / _CBRT; const double outer_y = outer_x; const double outer_z = outer_x; diff --git a/src/t8_cmesh/t8_cmesh_examples.h b/src/t8_cmesh/t8_cmesh_examples.h index 2047f4df20..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 @@ -406,6 +406,14 @@ t8_cmesh_new_triangulated_spherical_surface_octahedron (const double radius, sc_ t8_cmesh_t t8_cmesh_new_triangulated_spherical_surface_icosahedron (const double radius, sc_MPI_Comm comm); +/** Construct a triangulated spherical surface of given radius: cube version. + * \param [in] radius Radius of the sphere. + * \param [in] comm The MPI communicator used to commit the cmesh + * \return A cmesh representing the spherical surface. + */ +t8_cmesh_t +t8_cmesh_new_triangulated_spherical_surface_cube (const double radius, sc_MPI_Comm comm); + /** Construct a quadrangulated spherical surface of given radius. * \param [in] radius Radius of the sphere. * \param [in] comm The MPI communicator used to commit the cmesh @@ -441,14 +449,13 @@ t8_cmesh_new_prismed_spherical_shell_icosahedron (const double inner_radius, con /** Construct a cubed spherical shell of given inner radius and thickness. * \param [in] inner_radius Radius of the inner side of the shell. * \param [in] shell_thickness Thickness of the shell. - * \param [in] num_levels Number of trees per patch in longitudinal and latitudinal direction - given as level of refinement: 4^num_levels. + * \param [in] num_trees Number of trees per patch in longitudinal and latitudinal direction. * \param [in] num_layers Number of layers of the shell. * \param [in] comm The MPI communicator used to commit the cmesh * \return A cmesh representing the spherical surface. */ t8_cmesh_t -t8_cmesh_new_cubed_spherical_shell (const double inner_radius, const double shell_thickness, const int num_levels, +t8_cmesh_new_cubed_spherical_shell (const double inner_radius, const double shell_thickness, const int num_trees, const int num_layers, sc_MPI_Comm comm); /** Construct a cubed sphere of given radius. 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 854d80c471..4022a4a006 100644 --- a/src/t8_cmesh/t8_cmesh_types.h +++ b/src/t8_cmesh/t8_cmesh_types.h @@ -59,9 +59,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_cmesh/t8_cmesh_vtk_reader.cxx b/src/t8_cmesh/t8_cmesh_vtk_reader.cxx index 48e9616aa6..e27d1a1c8c 100644 --- a/src/t8_cmesh/t8_cmesh_vtk_reader.cxx +++ b/src/t8_cmesh/t8_cmesh_vtk_reader.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ /** \file t8_cmesh_vtk_reader.cxx diff --git a/src/t8_cmesh/t8_cmesh_vtk_writer.c b/src/t8_cmesh/t8_cmesh_vtk_writer.c deleted file mode 100644 index bed01ef3f4..0000000000 --- a/src/t8_cmesh/t8_cmesh_vtk_writer.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - 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) 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. -*/ - -#include -#include -#include "t8_cmesh_trees.h" -#include "t8_cmesh_types.h" - -/* Return the local number of vertices in a cmesh. - * \param [in] cmesh The cmesh to be considered. - * \param [in] count_ghosts If true, we also count the vertices of the ghost trees. - * \return The number of vertices associated to \a cmesh. - * \a cmesh must be committed before calling this function. - */ -static t8_gloidx_t -t8_cmesh_get_num_vertices (const t8_cmesh_t cmesh, const int count_ghosts) -{ - int iclass; - t8_eclass_t ghost_class; - t8_gloidx_t num_vertices = 0; - t8_locidx_t ighost; - T8_ASSERT (cmesh != NULL); - T8_ASSERT (cmesh->committed); - - for (iclass = T8_ECLASS_ZERO; iclass < T8_ECLASS_COUNT; iclass++) { - num_vertices += t8_eclass_num_vertices[iclass] * cmesh->num_local_trees_per_eclass[iclass]; - } - if (count_ghosts) { - /* Also count the vertices of the ghost trees */ - for (ighost = 0; ighost < t8_cmesh_get_num_ghosts (cmesh); ighost++) { - ghost_class = t8_cmesh_get_ghost_class (cmesh, ighost); - num_vertices += t8_eclass_num_vertices[ghost_class]; - } - } - - return num_vertices; -} - -static int -t8_cmesh_vtk_write_file_ext (const t8_cmesh_t cmesh, const char *fileprefix, const int write_ghosts) -{ - T8_ASSERT (cmesh != NULL); - T8_ASSERT (t8_cmesh_is_committed (cmesh)); - T8_ASSERT (fileprefix != NULL); - - if (cmesh->mpirank == 0) { - /* Write the pvtu header file. */ - int num_ranks_that_write = cmesh->set_partition ? cmesh->mpisize : 1; - if (t8_write_pvtu (fileprefix, num_ranks_that_write, 1, 1, 0, 0, 0, NULL)) { - SC_ABORTF ("Error when writing file %s.pvtu\n", fileprefix); - } - } - /* If the cmesh is replicated only rank 0 prints it, - * otherwise each process prints its part of the cmesh.*/ - if (cmesh->mpirank == 0 || cmesh->set_partition) { - char vtufilename[BUFSIZ]; - FILE *vtufile; - t8_locidx_t num_vertices, ivertex; - t8_locidx_t num_trees; - t8_ctree_t tree; - double x, y, z; - double *vertices, *vertex; - int k, sk; - long long offset, count_vertices; - t8_locidx_t ighost, num_ghosts = 0, num_loc_trees; -#ifdef T8_ENABLE_DEBUG - t8_cghost_t ghost; -#endif - t8_eclass_t eclass; - - num_vertices = t8_cmesh_get_num_vertices (cmesh, write_ghosts); - num_trees = t8_cmesh_get_num_local_trees (cmesh); - if (write_ghosts) { - num_trees += t8_cmesh_get_num_ghosts (cmesh); - } - - snprintf (vtufilename, BUFSIZ, "%s_%04d.vtu", fileprefix, cmesh->mpirank); - vtufile = fopen (vtufilename, "wb"); - if (vtufile == NULL) { - t8_global_errorf ("Could not open file %s for output.\n", vtufilename); - return -1; - } - fprintf (vtufile, "\n"); - fprintf (vtufile, "\n"); -#else - fprintf (vtufile, " byte_order=\"LittleEndian\">\n"); -#endif - fprintf (vtufile, " \n"); - fprintf (vtufile, " \n", (long long) num_vertices, - (long long) num_trees); - fprintf (vtufile, " \n"); - - /* write point position data */ - fprintf (vtufile, - " \n", - T8_VTK_FLOAT_NAME, T8_VTK_FORMAT_STRING); - - for (tree = t8_cmesh_get_first_tree (cmesh); tree != NULL; tree = t8_cmesh_get_next_tree (cmesh, tree)) { - /* TODO: Use new geometry here. Need cmesh_get_reference coords function. */ - vertices = t8_cmesh_get_tree_vertices (cmesh, tree->treeid); - for (ivertex = 0; ivertex < t8_eclass_num_vertices[tree->eclass]; ivertex++) { - vertex = vertices + 3 * t8_eclass_t8_to_vtk_corner_number[tree->eclass][ivertex]; - x = vertex[0]; - y = vertex[1]; - z = vertex[2]; -#ifdef T8_VTK_DOUBLES - fprintf (vtufile, " %24.16e %24.16e %24.16e\n", x, y, z); -#else - fprintf (vtufile, " %16.8e %16.8e %16.8e\n", x, y, z); -#endif - } - } /* end tree loop */ - if (write_ghosts) { - - /* Write the vertices of the ghost trees */ - num_ghosts = t8_cmesh_get_num_ghosts (cmesh); - num_loc_trees = t8_cmesh_get_num_local_trees (cmesh); - for (ighost = 0; ighost < num_ghosts; ighost++) { - /* Get the eclass of this ghost */ - eclass = t8_cmesh_get_ghost_class (cmesh, ighost); - /* Get a pointer to this ghosts vertices */ - vertices = (double *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), 0, ighost + num_loc_trees); - T8_ASSERT (vertices != NULL); - /* TODO: This code is duplicated above */ - for (ivertex = 0; ivertex < t8_eclass_num_vertices[eclass]; ivertex++) { - vertex = vertices + 3 * t8_eclass_vtk_to_t8_corner_number[eclass][ivertex]; - x = vertex[0]; - y = vertex[1]; - z = vertex[2]; -#ifdef T8_VTK_DOUBLES - fprintf (vtufile, " %24.16e %24.16e %24.16e\n", x, y, z); -#else - fprintf (vtufile, " %16.8e %16.8e %16.8e\n", x, y, z); -#endif - } - } /* end ghost loop */ - } - fprintf (vtufile, " \n"); - fprintf (vtufile, " \n"); - fprintf (vtufile, " \n"); - - /* write connectivity data */ - fprintf (vtufile, - " \n", - T8_VTK_LOCIDX, T8_VTK_FORMAT_STRING); - for (tree = t8_cmesh_get_first_tree (cmesh), count_vertices = 0; tree != NULL; - tree = t8_cmesh_get_next_tree (cmesh, tree)) { - fprintf (vtufile, " "); - for (k = 0; k < t8_eclass_num_vertices[tree->eclass]; ++k, count_vertices++) { - fprintf (vtufile, " %lld", count_vertices); - } - fprintf (vtufile, "\n"); - } - if (write_ghosts) { - /* Write the ghost connectivity */ - for (ighost = 0; ighost < num_ghosts; ighost++) { - eclass = t8_cmesh_get_ghost_class (cmesh, ighost); - fprintf (vtufile, " "); - for (k = 0; k < t8_eclass_num_vertices[eclass]; ++k, count_vertices++) { - fprintf (vtufile, " %lld", count_vertices); - } - fprintf (vtufile, "\n"); - } - } - fprintf (vtufile, " \n"); - - /* write offset data */ - fprintf (vtufile, - " \n", - T8_VTK_LOCIDX, T8_VTK_FORMAT_STRING); - fprintf (vtufile, " "); - for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1, offset = 0; tree != NULL; - tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) { - offset += t8_eclass_num_vertices[tree->eclass]; - fprintf (vtufile, " %lld", offset); - if (!(sk % 8)) - fprintf (vtufile, "\n "); - } - if (write_ghosts) { - /* ghost offset data */ - for (ighost = 0; ighost < num_ghosts; ighost++, ++sk) { - eclass = t8_cmesh_get_ghost_class (cmesh, ighost); - offset += t8_eclass_num_vertices[eclass]; - fprintf (vtufile, " %lld", offset); - if (!(sk % 8)) - fprintf (vtufile, "\n "); - } - } - fprintf (vtufile, "\n"); - fprintf (vtufile, " \n"); - /* write type data */ - fprintf (vtufile, - " \n", - T8_VTK_FORMAT_STRING); - fprintf (vtufile, " "); - for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1; tree != NULL; - tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) { - fprintf (vtufile, " %d", t8_eclass_vtk_type[tree->eclass]); - if (!(sk % 20) && tree->treeid != (cmesh->num_local_trees - 1)) - fprintf (vtufile, "\n "); - } - if (write_ghosts) { - /* ghost offset types */ - for (ighost = 0; ighost < num_ghosts; ighost++, ++sk) { - eclass = t8_cmesh_get_ghost_class (cmesh, ighost); - fprintf (vtufile, " %d", t8_eclass_vtk_type[eclass]); - if (!(sk % 20) && ighost != (num_ghosts - 1)) - fprintf (vtufile, "\n "); - } - } - fprintf (vtufile, "\n"); - fprintf (vtufile, " \n"); - fprintf (vtufile, " \n"); - /* write treeif data */ - fprintf (vtufile, " \n"); - fprintf (vtufile, - " \n", - T8_VTK_GLOIDX, T8_VTK_FORMAT_STRING); - fprintf (vtufile, " "); - for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1, offset = 0; tree != NULL; - tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) { - /* Since tree_id is actually 64 Bit but we store it as 32, we have to check - * that we do not get into conversion errors */ - /* TODO: We switched to 32 Bit because Paraview could not handle 64 well enough. - */ - T8_ASSERT (tree->treeid + cmesh->first_tree == (t8_gloidx_t) ((long) tree->treeid + cmesh->first_tree)); - fprintf (vtufile, " %ld", (long) tree->treeid + cmesh->first_tree); - if (!(sk % 8)) - fprintf (vtufile, "\n "); - } - if (write_ghosts) { - /* ghost offset types */ - for (ighost = 0; ighost < num_ghosts; ighost++, ++sk) { -#ifdef T8_ENABLE_DEBUG - ghost = t8_cmesh_trees_get_ghost (cmesh->trees, ighost); - /* Check for conversion errors */ - T8_ASSERT (ghost->treeid == (t8_gloidx_t) ((long) ghost->treeid)); -#endif - /* Write -1 as tree_id so that we can distinguish ghosts from normal trees - * in the vtk file */ - fprintf (vtufile, " %ld", (long) -1); - if (!(sk % 8)) - fprintf (vtufile, "\n "); - } - } - fprintf (vtufile, "\n"); - fprintf (vtufile, " \n"); - /* write mpirank data */ - fprintf (vtufile, - " \n", - "Int32", T8_VTK_FORMAT_STRING); - fprintf (vtufile, " "); - for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1, offset = 0; tree != NULL; - tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) { - fprintf (vtufile, " %i", cmesh->mpirank); - if (!(sk % 8)) - fprintf (vtufile, "\n "); - } - if (write_ghosts) { - /* write our rank for each ghost */ - for (ighost = 0; ighost < num_ghosts; ighost++, ++sk) { - fprintf (vtufile, " %i", cmesh->mpirank); - if (!(sk % 8)) - fprintf (vtufile, "\n "); - } - } - fprintf (vtufile, "\n"); - fprintf (vtufile, " \n"); - fprintf (vtufile, " \n"); - /* write type data */ - fprintf (vtufile, " \n"); - fprintf (vtufile, " \n"); - fprintf (vtufile, "\n"); - fclose (vtufile); - } - return 0; -} - -int -t8_cmesh_vtk_write_file (const t8_cmesh_t cmesh, const char *fileprefix) -{ - return t8_cmesh_vtk_write_file_ext (cmesh, fileprefix, 1); -} diff --git a/src/t8_cmesh_vtk_reader.hxx b/src/t8_cmesh_vtk_reader.hxx index 7c0ef85331..9ae9dac0fe 100644 --- a/src/t8_cmesh_vtk_reader.hxx +++ b/src/t8_cmesh_vtk_reader.hxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ /** \file t8_cmesh_vtk_reader.hxx diff --git a/src/t8_cmesh_vtk_writer.h b/src/t8_cmesh_vtk_writer.h deleted file mode 100644 index 7283bc7471..0000000000 --- a/src/t8_cmesh_vtk_writer.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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) 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. -*/ - -/** file t8_cmesh_vtk.h - */ -/* TODO: document this file */ - -#ifndef T8_CMESH_VTK_H -#define T8_CMESH_VTK_H - -#include - -/* typedef and macros */ - -T8_EXTERN_C_BEGIN (); -/* function declarations */ - -/* TODO: document this function */ -int -t8_cmesh_vtk_write_file (t8_cmesh_t cmesh, const char *fileprefix); - -T8_EXTERN_C_END (); - -#endif /* !T8_CMESH_VTK_H */ diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index dc44505a77..0fd3f5a12f 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include @@ -1441,52 +1441,6 @@ t8_forest_copy_trees (t8_forest_t forest, t8_forest_t from, int copy_elements) } } -/* Search for a linear element id (at forest->maxlevel) in a sorted array of - * elements. If the element does not exist, return the largest index i - * such that the element at position i has a smaller id than the given one. - * If no such i exists, return -1. - */ -/* TODO: should return t8_locidx_t */ -static t8_locidx_t -t8_forest_bin_search_lower (const t8_element_array_t *elements, const t8_linearidx_t element_id, const int maxlevel) -{ - t8_linearidx_t query_id; - t8_locidx_t low, high, guess; - - const t8_eclass_scheme_c *ts = t8_element_array_get_scheme (elements); - /* At first, we check whether any element has smaller id than the - * given one. */ - const t8_element_t *query = t8_element_array_index_int (elements, 0); - query_id = ts->t8_element_get_linear_id (query, maxlevel); - if (query_id > element_id) { - /* No element has id smaller than the given one */ - return -1; - } - - /* We now perform the binary search */ - low = 0; - high = t8_element_array_get_count (elements) - 1; - while (low < high) { - guess = (low + high + 1) / 2; - query = t8_element_array_index_int (elements, guess); - query_id = ts->t8_element_get_linear_id (query, maxlevel); - if (query_id == element_id) { - /* we are done */ - return guess; - } - else if (query_id > element_id) { - /* look further left */ - high = guess - 1; - } - else { - /* look further right, but keep guess in the search range */ - low = guess; - } - } - T8_ASSERT (low == high); - return low; -} - t8_eclass_t t8_forest_element_neighbor_eclass (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *elem, int face) { @@ -3690,11 +3644,10 @@ t8_forest_get_element (t8_forest_t forest, t8_locidx_t lelement_id, t8_locidx_t const t8_element_t * t8_forest_get_element_in_tree (t8_forest_t forest, t8_locidx_t ltreeid, t8_locidx_t leid_in_tree) { - t8_tree_t tree; T8_ASSERT (t8_forest_is_committed (forest)); T8_ASSERT (0 <= ltreeid && ltreeid < t8_forest_get_num_local_trees (forest)); - tree = t8_forest_get_tree (forest, ltreeid); + const t8_tree_t tree = t8_forest_get_tree (forest, ltreeid); const t8_element_t *element = t8_forest_get_tree_element (tree, leid_in_tree); T8_ASSERT (t8_forest_element_is_leaf (forest, element, ltreeid)); return element; @@ -4168,6 +4121,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 45c821e577..436c86460d 100644 --- a/src/t8_forest/t8_forest_ghost.cxx +++ b/src/t8_forest/t8_forest_ghost.cxx @@ -303,6 +303,55 @@ t8_forest_ghost_tree_num_elements (t8_forest_t forest, t8_locidx_t lghost_tree) return t8_element_array_get_count (&ghost_tree->elements); } +const t8_element_t * +t8_ghost_get_ghost_in_tree (t8_forest_t forest, t8_locidx_t lghost_tree, t8_linearidx_t linear_id, int element_level, + t8_locidx_t *loc_ghost_id) +{ + T8_ASSERT (t8_forest_is_committed (forest)); + const t8_element_array_t *ghost_elements = t8_forest_ghost_get_tree_elements (forest, lghost_tree); + T8_ASSERT (ghost_elements != NULL); + /* Search for the element. + * The search returns the largest index i, + * such that the element at position i has a smaller id than the given one. + * If no such i exists, it returns -1. */ + *loc_ghost_id = t8_forest_bin_search_lower (ghost_elements, linear_id, element_level); + if (*loc_ghost_id >= 0) { + /* The element was found */ + return t8_element_array_index_locidx (ghost_elements, *loc_ghost_id); + } + return nullptr; +} + +t8_locidx_t +t8_ghost_get_ghost_id_in_tree (t8_forest_t forest, t8_locidx_t lghost_tree, t8_element_t *ghost_element) +{ + T8_ASSERT (t8_forest_is_committed (forest)); + const t8_element_array_t *ghost_elements = t8_forest_ghost_get_tree_elements (forest, lghost_tree); + T8_ASSERT (ghost_elements != NULL); + /* In order to find the element, we need to compute its linear id. + * To do so, we need the scheme and the level of the element. */ + const t8_eclass_scheme_c *scheme = t8_element_array_get_scheme (ghost_elements); + const int ghost_level = scheme->t8_element_level (ghost_element); + /* Compute the linear id. */ + const t8_linearidx_t element_id = scheme->t8_element_get_linear_id (ghost_element, ghost_level); + /* Search for the element */ + int loc_ghost_id; + const t8_element_t *found_ghost + = t8_ghost_get_ghost_in_tree (forest, lghost_tree, element_id, ghost_level, &loc_ghost_id); + if (loc_ghost_id < 0) { + /* The element was not found */ + return -1; + } + /* An element was found but it may not be the candidate element. + * To identify whether the element was found, we compare these two. */ + if (scheme->t8_element_equal (ghost_element, found_ghost)) { + return loc_ghost_id; + } + else { + return -1; + } +} + t8_element_array_t * t8_forest_ghost_get_tree_elements (const t8_forest_t forest, const t8_locidx_t lghost_tree) { @@ -510,9 +559,7 @@ typedef struct static int t8_forest_ghost_search_boundary (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element, - const int is_leaf, const t8_element_array_t *leaves, const t8_locidx_t tree_leaf_index, - void *query, sc_array_t *query_indices, int *query_matches, - const size_t num_active_queries) + const int is_leaf, const t8_element_array_t *leaves, const t8_locidx_t tree_leaf_index) { t8_forest_ghost_boundary_data_t *data = (t8_forest_ghost_boundary_data_t *) t8_forest_get_user_data (forest); int num_faces, iface, faces_totally_owned, level; @@ -599,11 +646,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; } } @@ -1888,9 +1931,9 @@ t8_forest_ghost_destroy (t8_forest_ghost_t *pghost) /** * Implementation of the ghost-interface - * Wrapper for the abstracte base classes + * Wrapper for the abstract base class * Implementation of the communication steps - * and implementation of the dreived class search + * and implementation of the derived class search. */ t8_ghost_type_t diff --git a/src/t8_forest/t8_forest_ghost.h b/src/t8_forest/t8_forest_ghost.h index 8431874ece..e7703da12f 100644 --- a/src/t8_forest/t8_forest_ghost.h +++ b/src/t8_forest/t8_forest_ghost.h @@ -69,6 +69,30 @@ t8_forest_ghost_get_tree_element_offset (t8_forest_t forest, t8_locidx_t lghost_ t8_locidx_t t8_forest_ghost_tree_num_elements (t8_forest_t forest, t8_locidx_t lghost_tree); +/** Retrieves the ghost index of an element in a specific ghost tree. + * + * \param [in] forest The forest object. + * \param [in] lghost_tree The local index of the ghost tree. + * \param [in] linear_id The linear id of the element. + * \param [in] element_level The level of the element. + * \param [out] loc_ghost_id The local id of the ghost. -1 if no ghost was found. + * \return The ghost element. nullptr if no ghost was found. + */ +const t8_element_t * +t8_ghost_get_ghost_in_tree (t8_forest_t forest, t8_locidx_t lghost_tree, t8_linearidx_t linear_id, int element_level, + t8_locidx_t *loc_ghost_id); + +/** Retrieves the ghost index of an element in a specific ghost tree. + * + * \param [in] forest The forest object. + * \param [in] lghost_tree The local index of the ghost tree. + * \param [in] ghost_element The ghost element. + * \return The local index of the element in the ghost element array of the ghost tree. + * -1 if no ghost element was found. + */ +t8_locidx_t +t8_ghost_get_ghost_id_in_tree (t8_forest_t forest, t8_locidx_t lghost_tree, t8_element_t *ghost_element); + /** Get a pointer to the ghost element array of a ghost tree. * \param [in] forest The forest. Ghost layer must exist. * \param [in] lghost_tree The ghost tree id of a ghost tree. diff --git a/src/t8_forest/t8_forest_iterate.cxx b/src/t8_forest/t8_forest_iterate.cxx index 2134b4a817..e6abca40ea 100644 --- a/src/t8_forest/t8_forest_iterate.cxx +++ b/src/t8_forest/t8_forest_iterate.cxx @@ -172,8 +172,8 @@ t8_forest_iterate_faces (t8_forest_t forest, t8_locidx_t ltreeid, const t8_eleme static void t8_forest_search_recursion (t8_forest_t forest, const t8_locidx_t ltreeid, t8_element_t *element, const t8_eclass_scheme_c *ts, t8_element_array_t *leaf_elements, - const t8_locidx_t tree_lindex_of_first_leaf, t8_forest_search_query_fn search_fn, - t8_forest_search_query_fn query_fn, sc_array_t *queries, sc_array_t *active_queries) + const t8_locidx_t tree_lindex_of_first_leaf, t8_forest_search_fn search_fn, + t8_forest_query_fn query_fn, sc_array_t *queries, sc_array_t *active_queries) { /* Assertions to check for necessary requirements */ /* The forest must be committed */ @@ -209,8 +209,7 @@ t8_forest_search_recursion (t8_forest_t forest, const t8_locidx_t ltreeid, t8_el } } /* Call the callback function for the element */ - const int ret - = search_fn (forest, ltreeid, element, is_leaf, leaf_elements, tree_lindex_of_first_leaf, NULL, NULL, NULL, 0); + const int ret = search_fn (forest, ltreeid, element, is_leaf, leaf_elements, tree_lindex_of_first_leaf); if (!ret) { /* The function returned false. We abort the recursion */ @@ -288,8 +287,8 @@ t8_forest_search_recursion (t8_forest_t forest, const t8_locidx_t ltreeid, t8_el /* Perform a top-down search in one tree of the forest */ static void -t8_forest_search_tree (t8_forest_t forest, t8_locidx_t ltreeid, t8_forest_search_query_fn search_fn, - t8_forest_search_query_fn query_fn, sc_array_t *queries, sc_array_t *active_queries) +t8_forest_search_tree (t8_forest_t forest, t8_locidx_t ltreeid, t8_forest_search_fn search_fn, + t8_forest_query_fn query_fn, sc_array_t *queries, sc_array_t *active_queries) { /* Get the element class, scheme and leaf elements of this tree */ @@ -315,8 +314,7 @@ t8_forest_search_tree (t8_forest_t forest, t8_locidx_t ltreeid, t8_forest_search } void -t8_forest_search (t8_forest_t forest, t8_forest_search_query_fn search_fn, t8_forest_search_query_fn query_fn, - sc_array_t *queries) +t8_forest_search (t8_forest_t forest, t8_forest_search_fn search_fn, t8_forest_query_fn query_fn, sc_array_t *queries) { /* If we have queries build a list of all active queries, * thus all queries in the array */ diff --git a/src/t8_forest/t8_forest_iterate.h b/src/t8_forest/t8_forest_iterate.h index 9211ec41e7..cbca823f13 100644 --- a/src/t8_forest/t8_forest_iterate.h +++ b/src/t8_forest/t8_forest_iterate.h @@ -36,28 +36,49 @@ typedef int (*t8_forest_iterate_face_fn) (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element, int face, void *user_data, t8_locidx_t tree_leaf_index); -/* +/** + * A call-back function used by \ref t8_forest_search describing a search-criterion. Is called on an element and the + * search criterion should be checked on that element. Return true if the search criterion is met, false otherwise. + * + * + * \param[in] forest the forest + * \param[in] ltreeid the local tree id of the current tree + * \param[in] element the element for which the search criterion is checked. + * \param[in] is_leaf true if and only if \a element is a leaf element + * \param[in] leaf_elements the leaf elements in \a forest that are descendants of \a element (or the element + * itself if \a is_leaf is true) + * \param[in] tree_leaf_index the local index of the first leaf in \a leaf_elements + * \returns non-zero if the search criterion is met, zero otherwise. + */ +typedef int (*t8_forest_search_fn) (t8_forest_t forest, const t8_locidx_t ltreeid, const t8_element_t *element, + const int is_leaf, const t8_element_array_t *leaf_elements, + const t8_locidx_t tree_leaf_index); + +/** + * A call-back function used by \ref t8_forest_search for queries. Is called on an element and all queries are checked + * on that element. All positive queries are passed further down to the children of the element up to leaf elements of + * the tree. The results of the check are stored in \a query_matches. + * * \param[in] forest the forest * \param[in] ltreeid the local tree id of the current tree - * \param[in] element the element for which the query is executed + * \param[in] element the element for which the queries are executed * \param[in] is_leaf true if and only if \a element is a leaf element * \param[in] leaf_elements the leaf elements in \a forest that are descendants of \a element (or the element * itself if \a is_leaf is true) * \param[in] tree_leaf_index the local index of the first leaf in \a leaf_elements - * \param[in] queries if not NULL, a query that is passed through from the search function - * \param[in] query_indices if \a query is not NULL the indices of \a query in the \a queries array from \ref - * t8_forest_search - * \param[in, out] query_matches if \a query is not NULL: true at the i-th index if and only if the element 'matches' - * the query of the i-th query index. - * if \a query is NULL: true if and only if the search should continue with the - * children of \a element and the queries should be performed for this element. - * \param[in] num_active_queries The number of currently active queries. Does not have to be equal to query->elem_count, - * since some queries might have been deactivated from previous calls + * \param[in] queries An array of queries that are checked by the function + * \param[in] query_indices An array of size_t entries, where each entry is an index of a query in \q queries. + * \param[in, out] query_matches An array of length \a num_active_queries. + * If the element is not a leave must be set to true or false at the i-th index for + * each query, specifying whether the element 'matches' the query of the i-th query + * index or not. When the element is a leaf we can return before all entries are set. + * \param[in] num_active_queries The number of currently active queries (equals the number of entries of + * \a query_matches and entries of \a query_indices). */ -typedef int (*t8_forest_search_query_fn) (t8_forest_t forest, const t8_locidx_t ltreeid, const t8_element_t *element, - const int is_leaf, const t8_element_array_t *leaf_elements, - const t8_locidx_t tree_leaf_index, void *query, sc_array_t *query_indices, - int *query_matches, const size_t num_active_queries); +typedef void (*t8_forest_query_fn) (t8_forest_t forest, const t8_locidx_t ltreeid, const t8_element_t *element, + const int is_leaf, const t8_element_array_t *leaf_elements, + const t8_locidx_t tree_leaf_index, sc_array_t *queries, sc_array_t *query_indices, + int *query_matches, const size_t num_active_queries); T8_EXTERN_C_BEGIN (); @@ -85,8 +106,7 @@ t8_forest_iterate_faces (t8_forest_t forest, t8_locidx_t ltreeid, const t8_eleme * To pass user data to the search_fn function use \ref t8_forest_set_user_data */ void -t8_forest_search (t8_forest_t forest, t8_forest_search_query_fn search_fn, t8_forest_search_query_fn query_fn, - sc_array_t *queries); +t8_forest_search (t8_forest_t forest, t8_forest_search_fn search_fn, t8_forest_query_fn query_fn, sc_array_t *queries); /** Given two forest where the elements in one forest are either direct children or * parents of the elements in the other forest 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_forest/t8_forest_private.c b/src/t8_forest/t8_forest_private.cxx similarity index 60% rename from src/t8_forest/t8_forest_private.c rename to src/t8_forest/t8_forest_private.cxx index 6febf22cc1..6e09489e26 100644 --- a/src/t8_forest/t8_forest_private.c +++ b/src/t8_forest/t8_forest_private.cxx @@ -23,6 +23,9 @@ #include #include #include +#include + +T8_EXTERN_C_BEGIN (); const t8_element_t* t8_forest_get_tree_element (t8_tree_t tree, t8_locidx_t elem_in_tree) @@ -52,3 +55,45 @@ t8_forest_get_tree_element_array_mutable (const t8_forest_t forest, t8_locidx_t { return (t8_element_array_t*) t8_forest_get_tree_element_array (forest, ltreeid); } + +t8_locidx_t +t8_forest_bin_search_lower (const t8_element_array_t* elements, const t8_linearidx_t element_id, const int maxlevel) +{ + t8_linearidx_t query_id; + t8_locidx_t low, high, guess; + + const t8_eclass_scheme_c* ts = t8_element_array_get_scheme (elements); + /* At first, we check whether any element has smaller id than the + * given one. */ + const t8_element_t* query = t8_element_array_index_int (elements, 0); + query_id = ts->t8_element_get_linear_id (query, maxlevel); + if (query_id > element_id) { + /* No element has id smaller than the given one */ + return -1; + } + + /* We now perform the binary search */ + low = 0; + high = t8_element_array_get_count (elements) - 1; + while (low < high) { + guess = (low + high + 1) / 2; + query = t8_element_array_index_int (elements, guess); + query_id = ts->t8_element_get_linear_id (query, maxlevel); + if (query_id == element_id) { + /* we are done */ + return guess; + } + else if (query_id > element_id) { + /* look further left */ + high = guess - 1; + } + else { + /* look further right, but keep guess in the search range */ + low = guess; + } + } + T8_ASSERT (low == high); + return low; +} + +T8_EXTERN_C_END (); diff --git a/src/t8_forest/t8_forest_private.h b/src/t8_forest/t8_forest_private.h index f43e244631..4d03aeffaa 100644 --- a/src/t8_forest/t8_forest_private.h +++ b/src/t8_forest/t8_forest_private.h @@ -195,6 +195,18 @@ t8_forest_get_tree_element_array (t8_forest_t forest, t8_locidx_t ltreeid); t8_element_array_t * t8_forest_get_tree_element_array_mutable (const t8_forest_t forest, t8_locidx_t ltreeid); +/** Search for a linear element id (at forest->maxlevel) in a sorted array of + * elements. If the element does not exist, return the largest index i + * such that the element at position i has a smaller id than the given one. + * If no such i exists, return -1. + * \note This search does not work for subelements. + * \param [in] elements The array of elements. + * \param [in] element_id The linear id of the element to search for. + * \param [in] maxlevel The maximum level of the elements. + */ +t8_locidx_t +t8_forest_bin_search_lower (const t8_element_array_t *elements, const t8_linearidx_t element_id, const int maxlevel); + /** Find the owner process of a given element, deprecated version. * Use t8_forest_element_find_owner instead. * \param [in] forest The forest. diff --git a/src/t8_forest/t8_forest_to_vtkUnstructured.hxx b/src/t8_forest/t8_forest_to_vtkUnstructured.hxx deleted file mode 100644 index 450f0fcf5d..0000000000 --- a/src/t8_forest/t8_forest_to_vtkUnstructured.hxx +++ /dev/null @@ -1,68 +0,0 @@ -/* -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) 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. -*/ - -#ifndef T8_FOREST_VTK_UNSTRUCTURED_API_HXX -#define T8_FOREST_VTK_UNSTRUCTURED_API_HXX - -#include -#include - -#if T8_WITH_VTK -#include -#endif - -T8_EXTERN_C_BEGIN (); - -#if T8_WITH_VTK -/** Write the forest in .pvtu file format. Writes one .vtu file per - * process and a meta .pvtu file. - * This function uses the vtk library. t8code must be configured with - * "--with-vtk" in order to use it. - * Currently does not support pyramid elements. - * \param [in] forest The forest. - * \param [in,out] unstructuredGrid A pointer to a vtkUnstructuredGrid, which is going to be filled with the elements - * and data of the \a forest. - * \param [in] write_treeid If true, the global tree id is written for each element. - * \param [in] write_mpirank If true, the mpirank is written for each element. - * \param [in] write_level If true, the refinement level is written for each element. - * \param [in] write_element_id If true, the global element id is written for each element. - * \param [in] curved_flag If true, write the elements as curved element types from vtk. - * \param [in] write_ghosts If true, write ghost elements. - * \param [in] num_data Number of user defined double valued data fields to write. - * \param [in] data Array of t8_vtk_data_field_t of length \a num_data - * providing the user defined per element data. - * If scalar and vector fields are used, all scalar fields - * must come first in the array. - * \return True if successful, false if not (process local). - * \note If t8code was not configured with vtk, use \ref t8_forest_vtk_write_file - */ -void -t8_forest_to_vtkUnstructuredGrid (t8_forest_t forest, vtkSmartPointer unstructuredGrid, - const int write_treeid, const int write_mpirank, const int write_level, - const int write_element_id, const int curved_flag, const int write_ghosts, - const int num_data, t8_vtk_data_field_t *data); - -#endif - -T8_EXTERN_C_END (); - -#endif /* T8_FOREST_VTK_UNSTRUCTURED_API_HXX */ 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_helpers.c b/src/t8_geometry/t8_geometry_helpers.c index c3c7a4d5f4..17b3eb3516 100644 --- a/src/t8_geometry/t8_geometry_helpers.c +++ b/src/t8_geometry/t8_geometry_helpers.c @@ -29,6 +29,11 @@ void t8_geom_linear_interpolation (const double *coefficients, const double *corner_values, const int corner_value_dim, const int interpolation_dim, double *evaluated_function) { + T8_ASSERT (0 <= corner_value_dim && corner_value_dim <= 3); + T8_ASSERT (1 <= interpolation_dim && interpolation_dim <= 3); + + /* Temporary storage for result. Using this allows evaluated_function to use the same space as + * coefficients or corner_values if needed. */ double temp[3] = { 0 }; for (int i_dim = 0; i_dim < corner_value_dim; i_dim++) { temp[i_dim] = corner_values[0 * corner_value_dim + i_dim] * (1 - coefficients[0]) /* x=0 y=0 z=0 */ @@ -57,10 +62,16 @@ void t8_geom_triangular_interpolation (const double *coefficients, const double *corner_values, const int corner_value_dim, const int interpolation_dim, double *evaluated_function) { + T8_ASSERT (0 <= corner_value_dim && corner_value_dim <= 3); + T8_ASSERT (2 <= interpolation_dim && interpolation_dim <= 3); + /* The algorithm is able to calculate any point in a triangle or tetrahedron using cartesian coordinates. * All points are calculated by the sum of each corner point (e.g. p1 -> corner point 1) multiplied by a * scalar, which in this case are the reference coordinates (ref_coords). */ + + /* Temporary storage for result. Using this allows evaluated_function to use the same space as + * coefficients or corner_values if needed. */ double temp[3] = { 0 }; for (int i_dim = 0; i_dim < corner_value_dim; i_dim++) { 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 f7de39c5aa..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 @@ -118,13 +119,6 @@ t8_geom_evaluate_sphere_tri_prism (const double *active_tree_vertices, const t8_ } } -/** - * Map the faces of an octahedron 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 many entries, specifying a point in [0,1]^dimension. - * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. - */ void t8_geometry_triangulated_spherical_surface::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords, @@ -133,13 +127,6 @@ t8_geometry_triangulated_spherical_surface::t8_geom_evaluate (t8_cmesh_t cmesh, t8_geom_evaluate_sphere_tri_prism (active_tree_vertices, T8_ECLASS_TRIANGLE, ref_coords, num_coords, out_coords); } -/** - * Map the prismed faces of an octahedron 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 many entries, specifying a point in [0,1]^dimension. - * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. - */ void t8_geometry_prismed_spherical_shell::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords, double *out_coords) const @@ -148,90 +135,130 @@ t8_geometry_prismed_spherical_shell::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloi t8_geom_evaluate_sphere_tri_prism (active_tree_vertices, T8_ECLASS_PRISM, ref_coords, num_coords, out_coords); } -/** - * Map the faces of a unit 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 many entries, specifying a point in [0,1]^dimension. - * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. - */ void -t8_geometry_quadrangulated_spherical_surface::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, - const double *ref_coords, const size_t num_coords, - double *out_coords) const +t8_geometry_tessellated_spherical_surface::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 position[3]; /* Position vector in the element. */ + // Note, all elements are aligned such that the face normal follows the + // outward radial direction of the sphere. - /* All elements are aligned such that the face normal follows the - * outward radial direction of the sphere. */ - const double radius = t8_vec_norm (active_tree_vertices); + // These three vectors resemble a tripod. + double normal[3]; // Normal vector. + double tangent1[3]; // First tangent vector. + double tangent2[3]; // Second tangent vector. - for (size_t i_coord = 0; i_coord < num_coords; i_coord++) { - const size_t offset_2d = 2 * i_coord; - const size_t offset_3d = 3 * i_coord; + // Compute normal vector of the current cmesh cell. + t8_vec_tri_normal (active_tree_vertices, active_tree_vertices + 3, active_tree_vertices + 6, normal); + t8_vec_normalize (normal); + + // Compute sphere's radius over cube root which is the shortest distance to the origin (0,0,0). + const double distance = std::abs (t8_vec_dot (active_tree_vertices, normal)); - double corr_ref_coords[3]; /* Corrected reference coordinates. */ + // Compute actual radius of the sphere. + const double radius = distance * std::cbrt (1.0); - /* Shorthand for code readability. `ref_coords` go from 0 to 1. */ - const double x = ref_coords[offset_2d + 0]; - const double y = ref_coords[offset_2d + 1]; + // Compute orthogonal coordinate system anchored on the cmesh element. + t8_vec_orthogonal_tripod (normal, tangent1, tangent2); - /* tldr: Correction in order to rectify elements near the corners. - * This is necessary, since due to the transformation from the unit cube - * to the sphere elements near the face centers expand while near the - * corners they shrink. Following correction alleviates this. - */ - corr_ref_coords[0] = tan (0.5 * M_PI * (x - 0.5)) * 0.5 + 0.5; - corr_ref_coords[1] = tan (0.5 * M_PI * (y - 0.5)) * 0.5 + 0.5; - corr_ref_coords[2] = 0; + // Compute anchor of the tripod on the cmesh element's plane. + double anchor[3]; + t8_vec_axy (normal, anchor, distance); - t8_geom_linear_interpolation (corr_ref_coords, active_tree_vertices, 3, 2, position); - t8_vec_normalize (position); - t8_vec_axy (position, out_coords + offset_3d, radius); + // Loop over given reference coordinates. + for (size_t i_coord = 0; i_coord < num_coords; i_coord++) { + const size_t offset_2d = 2 * i_coord; + const size_t offset_3d = 3 * i_coord; + + // Compute the the position vector in the cmesh element. + double position[3]; + t8_geom_compute_linear_geometry (active_tree_class, active_tree_vertices, ref_coords + offset_2d, 1, position); + + // Compute difference vector between position and tripod's anchor. + double diff_vec[3]; + t8_vec_diff (position, anchor, diff_vec); + + // Compute the coefficients of the difference vector in the local + // coordinate system of the tripod and apply equi-angular correction. + const double alpha1 = distance * tan (0.25 * M_PI * t8_vec_dot (tangent1, diff_vec) / distance); + const double alpha2 = distance * tan (0.25 * M_PI * t8_vec_dot (tangent2, diff_vec) / distance); + + // Compute the final transformed coordinates. + double *out_vec = out_coords + offset_3d; + t8_vec_copy (anchor, out_vec); + t8_vec_axpy (tangent1, out_vec, alpha1); + t8_vec_axpy (tangent2, out_vec, alpha2); + t8_vec_rescale (out_vec, radius); } } -/** - * Maps six hexaeders arranged into cube 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 many entries, specifying a point in [0,1]^dimension. - * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. - */ void t8_geometry_cubed_spherical_shell::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 position[3]; /* Position vector in the element. */ - - /* All elements are aligned such that the reference z-direction follows the - * outward radial direction of the sphere. Hence the element height is equal to - * the shell thickness. */ - const double inner_radius = t8_vec_norm (active_tree_vertices); - const double shell_thickness = t8_vec_norm (active_tree_vertices + 4 * 3) - inner_radius; + // Note, all elements are aligned such that the face normal follows the + // outward radial direction of the sphere. + + // These three vectors resemble a tripod. + double normal[3]; // Normal vector. + double tangent1[3]; // First tangent vector. + double tangent2[3]; // Second tangent vector. + + // Compute normal vector of the current cmesh cell. + t8_vec_tri_normal (active_tree_vertices, active_tree_vertices + 3, active_tree_vertices + 6, normal); + t8_vec_normalize (normal); + + // Compute sphere's radius over cube root which is the shortest distance to the origin (0,0,0). + const double distance = std::abs (t8_vec_dot (active_tree_vertices, normal)); + + // Compute actual radius of the sphere. + 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 + - inner_radius; + + // Compute orthogonal coordinate system anchored on the cmesh element. + t8_vec_orthogonal_tripod (normal, tangent1, tangent2); + + // Compute anchor of the tripod on the cmesh element's plane. + double anchor[3]; + t8_vec_axy (normal, anchor, distance); + + t8_eclass_t interpolation_eclass; + switch (active_tree_class) { + case T8_ECLASS_HEX: + interpolation_eclass = T8_ECLASS_QUAD; + break; + case T8_ECLASS_PRISM: + interpolation_eclass = T8_ECLASS_TRIANGLE; + break; + default: + SC_ABORT_NOT_REACHED (); + } for (size_t i_coord = 0; i_coord < num_coords; i_coord++) { - const size_t offset = 3 * i_coord; + const size_t offset_3d = 3 * i_coord; - double corr_ref_coords[3]; /* Corrected reference coordinates. */ - - /* Shorthand for code readability. `ref_coords` go from 0 to 1. */ - const double x = ref_coords[offset + 0]; - const double y = ref_coords[offset + 1]; - const double z = ref_coords[offset + 2]; - - /* tldr: Correction in order to rectify elements near the corners. - * This is necessary, since due to the transformation from the unit cube - * to the sphere elements near the face centers expand while near the - * corners they shrink. Following correction alleviates this. - */ - corr_ref_coords[0] = tan (0.5 * M_PI * (x - 0.5)) * 0.5 + 0.5; - corr_ref_coords[1] = tan (0.5 * M_PI * (y - 0.5)) * 0.5 + 0.5; - corr_ref_coords[2] = z; - - t8_geom_linear_interpolation (corr_ref_coords, active_tree_vertices, 3, 3, position); - t8_vec_normalize (position); - t8_vec_axy (position, out_coords + offset, inner_radius + z * shell_thickness); + // Compute the the position vector in the cmesh element. + double position[3]; + t8_geom_compute_linear_geometry (interpolation_eclass, active_tree_vertices, ref_coords + offset_3d, 1, position); + + // Compute difference vector between position and tripod's anchor. + double diff_vec[3]; + t8_vec_diff (position, anchor, diff_vec); + + // Compute the coefficients of the difference vector in the local + // coordinate system of the tripod and apply equi-angular correction. + const double alpha1 = distance * tan (0.25 * M_PI * t8_vec_dot (tangent1, diff_vec) / distance); + const double alpha2 = distance * tan (0.25 * M_PI * t8_vec_dot (tangent2, diff_vec) / distance); + + // Compute the final transformed coordinates. + double *out_vec = out_coords + offset_3d; + t8_vec_copy (anchor, out_vec); + t8_vec_axpy (tangent1, out_vec, alpha1); + t8_vec_axpy (tangent2, out_vec, alpha2); + t8_vec_rescale (out_vec, inner_radius + ref_coords[offset_3d + 2] * shell_thickness); } } @@ -338,9 +365,9 @@ t8_geometry_prismed_spherical_shell_new () } t8_geometry_c * -t8_geometry_quadrangulated_spherical_surface_new () +t8_geometry_tessellated_spherical_surface_new () { - t8_geometry_quadrangulated_spherical_surface *geom = new t8_geometry_quadrangulated_spherical_surface (); + t8_geometry_tessellated_spherical_surface *geom = new t8_geometry_tessellated_spherical_surface (); return (t8_geometry_c *) geom; } diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.h index 8af8d89a90..8bcaa6c59a 100644 --- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.h +++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.h @@ -50,11 +50,11 @@ t8_geometry_quadrangulated_disk_new (); t8_geometry_c * t8_geometry_triangulated_spherical_surface_new (); -/** Create a new quadrangulated_spherical_surface geometry. +/** Create a new tessellated_spherical_surface geometry. * \return A pointer to an allocated geometry struct. */ t8_geometry_c * -t8_geometry_quadrangulated_spherical_surface_new (); +t8_geometry_tessellated_spherical_surface_new (); /** Create a new cubed_spherical_shell geometry. * \return A pointer to an allocated geometry struct. 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 203dec3872..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. * @@ -84,6 +84,23 @@ struct t8_geometry_quadrangulated_disk: public t8_geometry_with_vertices return T8_GEOMETRY_TYPE_UNDEFINED; }; + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only quad 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_QUAD) { + t8_productionf ("t8_geometry_quadrangulated_disk is not compatible with tree type %s\n" + "It is only compatible with quad elements.\n", + t8_eclass_to_string[active_tree_class]); + return true; + } + return false; + } + /* Load tree data is inherited from t8_geometry_with_vertices. */ }; @@ -93,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_") { } @@ -106,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. * @@ -126,21 +143,38 @@ struct t8_geometry_triangulated_spherical_surface: public t8_geometry_with_verti SC_ABORT_NOT_REACHED (); } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only triangle 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_TRIANGLE) { + t8_productionf ("t8_geometry_triangulated_spherical_surface is not compatible with tree type %s\n" + "It is only compatible with triangle elements.\n", + t8_eclass_to_string[active_tree_class]); + return true; + } + return false; + } + /* Load tree data is inherited from t8_geometry_with_vertices. */ }; -/** This geometry maps the faces of a cube to a spherical surface. +/** This geometry maps the faces of a cube made of quads and/or triangles to a spherical surface. */ -struct t8_geometry_quadrangulated_spherical_surface: public t8_geometry_with_vertices +struct t8_geometry_tessellated_spherical_surface: public t8_geometry_with_vertices { public: /* Basic constructor that sets the dimension and the name. */ - t8_geometry_quadrangulated_spherical_surface (): t8_geometry_with_vertices (2, "t8_quadrangulated_spherical_surface_") + t8_geometry_tessellated_spherical_surface (): t8_geometry_with_vertices ("t8_tessellated_spherical_surface") { } /* The destructor. */ - virtual ~t8_geometry_quadrangulated_spherical_surface () + virtual ~t8_geometry_tessellated_spherical_surface () { } @@ -148,7 +182,7 @@ struct t8_geometry_quadrangulated_spherical_surface: public t8_geometry_with_ver * 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. * @@ -167,6 +201,23 @@ struct t8_geometry_quadrangulated_spherical_surface: public t8_geometry_with_ver SC_ABORT_NOT_REACHED (); } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only quad 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_QUAD) { + t8_productionf ("t8_geometry_quadrangulated_spherical_surface is not compatible with tree type %s\n" + "It is only compatible with quad elements.\n", + t8_eclass_to_string[active_tree_class]); + return true; + } + return false; + } + /* Load tree data is inherited from t8_geometry_with_vertices. */ }; @@ -176,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_") { } @@ -189,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. * @@ -208,6 +259,23 @@ struct t8_geometry_cubed_spherical_shell: public t8_geometry_with_vertices SC_ABORT_NOT_REACHED (); } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only 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_HEX) { + t8_productionf ("t8_geometry_cubed_spherical_shell is not compatible with tree type %s\n" + "It is only compatible with hex elements.\n", + t8_eclass_to_string[active_tree_class]); + return true; + } + return false; + } + /* Load tree data is inherited from t8_geometry_with_vertices. */ }; @@ -217,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") { } @@ -230,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. * @@ -249,6 +317,23 @@ struct t8_geometry_prismed_spherical_shell: public t8_geometry_with_vertices SC_ABORT_NOT_REACHED (); } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only prism 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_PRISM) { + t8_productionf ("t8_geometry_prismed_spherical_shell is not compatible with tree type %s\n" + "It is only compatible with prism elements.\n", + t8_eclass_to_string[active_tree_class]); + return true; + } + return false; + } + /* Load tree data is inherited from t8_geometry_with_vertices. */ }; @@ -258,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") { } @@ -271,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. * @@ -290,6 +375,23 @@ struct t8_geometry_cubed_sphere: public t8_geometry_with_vertices SC_ABORT_NOT_REACHED (); } + /** + * Check for compatibility of the currently loaded tree with the geometry. + * Only 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_HEX) { + t8_productionf ("t8_geometry_cubed_sphere is not compatible with tree type %s\n" + "It is only compatible with hex elements.\n", + t8_eclass_to_string[active_tree_class]); + return true; + } + return false; + } + /* Load tree data is inherited from t8_geometry_with_vertices. */ }; 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_vec.h b/src/t8_vec.h index eaa534bc3a..6db681486f 100644 --- a/src/t8_vec.h +++ b/src/t8_vec.h @@ -245,6 +245,25 @@ t8_vec_tri_normal (const double p1[3], const double p2[3], const double p3[3], d t8_vec_cross (a, b, normal); } +/** Compute an orthogonal coordinate system from a given vector. + * \param [in] v1 3D vector. + * \param [out] v2 3D vector. + * \param [out] v3 3D vector. + */ +static inline void +t8_vec_orthogonal_tripod (const double v1[3], double v2[3], double v3[3]) +{ + v2[0] = v1[1]; + v2[1] = v1[2]; + v2[2] = -v1[0]; + + t8_vec_axpy (v1, v2, -t8_vec_dot (v1, v2)); + t8_vec_cross (v1, v2, v3); + + t8_vec_normalize (v2); + t8_vec_normalize (v3); +} + /** Swap the components of two vectors. * \param [in,out] p1 A 3D vector. * \param [in,out] p2 A 3D vector. diff --git a/src/t8_vtk/t8_vtk_parallel.cxx b/src/t8_vtk/t8_vtk_parallel.cxx index ffd7e6b62b..8652db46cc 100644 --- a/src/t8_vtk/t8_vtk_parallel.cxx +++ b/src/t8_vtk/t8_vtk_parallel.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2023 the developers + Copyright (C) 2023 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 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. + 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. + 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. */ #include "t8_vtk_parallel.hxx" diff --git a/src/t8_vtk/t8_vtk_parallel.hxx b/src/t8_vtk/t8_vtk_parallel.hxx index 31890200a6..383e3e55f0 100644 --- a/src/t8_vtk/t8_vtk_parallel.hxx +++ b/src/t8_vtk/t8_vtk_parallel.hxx @@ -1,23 +1,23 @@ /* -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. + 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) 2023 the developers + Copyright (C) 2023 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 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. + 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. + 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. */ #ifndef T8_VTK_PARALLEL_HXX diff --git a/src/t8_vtk/t8_vtk_polydata.cxx b/src/t8_vtk/t8_vtk_polydata.cxx index d95e1af570..dd38d55e87 100644 --- a/src/t8_vtk/t8_vtk_polydata.cxx +++ b/src/t8_vtk/t8_vtk_polydata.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ #include "t8_vtk_polydata.hxx" diff --git a/src/t8_vtk/t8_vtk_polydata.hxx b/src/t8_vtk/t8_vtk_polydata.hxx index d23e96da70..dd20e803c9 100644 --- a/src/t8_vtk/t8_vtk_polydata.hxx +++ b/src/t8_vtk/t8_vtk_polydata.hxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ /** diff --git a/src/t8_vtk/t8_vtk_reader.cxx b/src/t8_vtk/t8_vtk_reader.cxx index b5d9a00040..059bcc711e 100644 --- a/src/t8_vtk/t8_vtk_reader.cxx +++ b/src/t8_vtk/t8_vtk_reader.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2023 the developers + Copyright (C) 2023 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 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. + 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. + 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. */ #include @@ -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_reader.hxx b/src/t8_vtk/t8_vtk_reader.hxx index 34b7235c59..8c320106be 100644 --- a/src/t8_vtk/t8_vtk_reader.hxx +++ b/src/t8_vtk/t8_vtk_reader.hxx @@ -1,23 +1,23 @@ /* -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. + 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) 2023 the developers + Copyright (C) 2023 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 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. + 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. + 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. */ #ifndef T8_VTK_READER diff --git a/src/t8_vtk/t8_vtk_types.h b/src/t8_vtk/t8_vtk_types.h index e8355e5836..b610dc333f 100644 --- a/src/t8_vtk/t8_vtk_types.h +++ b/src/t8_vtk/t8_vtk_types.h @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ #ifndef T8_VTK_TYPES diff --git a/src/t8_vtk/t8_vtk_unstructured.cxx b/src/t8_vtk/t8_vtk_unstructured.cxx index 3d026d70b3..e45ca9780f 100644 --- a/src/t8_vtk/t8_vtk_unstructured.cxx +++ b/src/t8_vtk/t8_vtk_unstructured.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ #include "t8_vtk/t8_vtk_unstructured.hxx" diff --git a/src/t8_vtk/t8_vtk_unstructured.hxx b/src/t8_vtk/t8_vtk_unstructured.hxx index 2ae3925cc0..994c1a0968 100644 --- a/src/t8_vtk/t8_vtk_unstructured.hxx +++ b/src/t8_vtk/t8_vtk_unstructured.hxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ #ifndef T8_CMESH_VTK_UNSTRUCTURED_READER diff --git a/src/t8_forest/t8_forest_vtk.cxx b/src/t8_vtk/t8_vtk_write_ASCII.cxx similarity index 61% rename from src/t8_forest/t8_forest_vtk.cxx rename to src/t8_vtk/t8_vtk_write_ASCII.cxx index c97044ef88..f2b7f45a24 100644 --- a/src/t8_forest/t8_forest_vtk.cxx +++ b/src/t8_vtk/t8_vtk_write_ASCII.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 classes 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 @@ -20,48 +20,15 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include -#include +#include "t8_vtk/t8_vtk_write_ASCII.hxx" +#include "t8_vtk/t8_vtk_writer_helper.hxx" #include #include #include #include -#include "t8_forest_types.h" -#if T8_WITH_VTK -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if T8_ENABLE_MPI -#include -#include -#include -#endif -#endif -#include -#include -#include -#include - -/* We want to export the whole implementation to be callable from "C" */ -T8_EXTERN_C_BEGIN (); +#include "t8_forest/t8_forest_types.h" +#include "t8_cmesh/t8_cmesh_trees.h" +#include "t8_cmesh/t8_cmesh_types.h" /* TODO: Currently we only use ASCII mode and no data compression. * We also do not use sc_io to buffer our output stream. */ @@ -112,458 +79,6 @@ typedef int (*t8_forest_vtk_cell_data_kernel) (t8_forest_t forest, const t8_loci t8_eclass_scheme_c *ts, const int is_ghost, FILE *vtufile, int *columns, void **data, T8_VTK_KERNEL_MODUS modus); -#define T8_FOREST_VTK_QUADRATIC_ELEMENT_MAX_CORNERS 20 -/** 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 }; - -/** 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 }; - -/** Map vtk element corners to element reference coordinates. The reference - * coordinates are defined in such a way, that the linear vtk corners are listed - * first and then the curved coords. This way, this array can be used for linear - * vtk elements as well as quadratic vtk elements. - */ -const double t8_forest_vtk_point_to_element_ref_coords[T8_ECLASS_COUNT][T8_FOREST_VTK_QUADRATIC_ELEMENT_MAX_CORNERS][3] - = { { /* T8_ECLASS_VERTEX */ - { 0, 0, 0 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 } }, - { /* T8_ECLASS_LINE */ - { 0, 0, 0 }, { 1, 0, 0 }, { 0.5, 0, 0 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 } }, - { /* T8_ECLASS_QUAD */ - { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, { 0.5, 0, 0 }, { 1, 0.5, 0 }, { 0.5, 1, 0 }, - { 0, 0.5, 0 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 } }, - { /* T8_ECLASS_TRIANGLE */ - { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0.5, 0, 0 }, { 1, 0.5, 0 }, { 0.5, 0.5, 0 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 } }, - { /* T8_ECLASS_HEX */ - { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, - { 0, 1, 1 }, { 0.5, 0, 0 }, { 1, 0.5, 0 }, { 0.5, 1, 0 }, { 0, 0.5, 0 }, { 0.5, 0, 1 }, { 1, 0.5, 1 }, - { 0.5, 1, 1 }, { 0, 0.5, 1 }, { 0, 0, 0.5 }, { 1, 0, 0.5 }, { 1, 1, 0.5 }, { 0, 1, 0.5 } }, - { /* T8_ECLASS_TET */ - { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 1 }, { 1, 0, 1 }, { 0.5, 0, 0 }, - { 1, 0.5, 0.5 }, { 0.5, 0.5, 0.5 }, { 0.5, 0, 0.5 }, { 1, 0, 0.5 }, { 1, 0.5, 1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 } }, - { /* T8_ECLASS_PRISM */ - { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0.5, 0, 0 }, - { 1, 0.5, 0 }, { 0.5, 0.5, 0 }, { 0.5, 0, 1 }, { 1, 0.5, 1 }, { 0.5, 0.5, 1 }, { 0, 0, 0.5 }, { 1, 0, 0.5 }, - { 1, 1, 0.5 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 } }, - { /* T8_ECLASS_PYRAMID */ - { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, { 1, 1, 1 }, - { 0.5, 0, 0 }, { 1, 0.5, 0 }, { 0.5, 1, 0 }, { 0, 0.5, 0 }, { 0.5, 0.5, 0.5 }, - { 1, 0.5, 0.5 }, { 1, 1, 0.5 }, { 0.5, 1, 0.5 }, { -1, -1, -1 }, { -1, -1, -1 }, - { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 }, { -1, -1, -1 } } }; - -/* depending on whether we want to write curved or non-curved elements - * we need the right number of points, so we choose the right lookup table - */ -#if T8_WITH_VTK -static int -t8_get_number_of_vtk_nodes (const t8_element_shape_t eclass, const int curved_flag) -{ - /* use the lookup table of the eclasses. */ - if (curved_flag) { - return t8_curved_eclass_num_nodes[eclass]; - } - return t8_eclass_num_vertices[eclass]; -} -#endif - -#if T8_WITH_VTK -static void -t8_forest_vtk_get_element_nodes (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element, const int vertex, - const int curved_flag, double *out_coords) -{ - const t8_eclass_t tree_class = t8_forest_get_tree_class (forest, ltreeid); - const t8_eclass_scheme_c *scheme = t8_forest_get_eclass_scheme (forest, tree_class); - const t8_element_shape_t element_shape = scheme->t8_element_shape (element); - const double *ref_coords = t8_forest_vtk_point_to_element_ref_coords[element_shape][vertex]; - const int num_node = t8_get_number_of_vtk_nodes (element_shape, curved_flag); - t8_forest_element_from_ref_coords (forest, ltreeid, element, ref_coords, num_node, out_coords); -} - -/** - * Translate a single element from the forest into a vtkCell and fill the vtkArrays with - * the data related to the element (not element_data). - */ -static void -t8_forest_element_to_vtk_cell ( - t8_forest_t forest, const t8_element_t *element, t8_eclass_scheme_c *scheme, const t8_locidx_t itree, - const t8_gloidx_t offset, const int write_treeid, const int write_mpirank, const int write_level, - const int write_element_id, const int curved_flag, const int is_ghost, const int elem_id, long int *point_id, - int *cellTypes, vtkSmartPointer points, vtkSmartPointer cellArray, - vtkSmartPointer vtk_treeid, vtkSmartPointer vtk_mpirank, - vtkSmartPointer vtk_level, vtkSmartPointer vtk_element_id) -{ - vtkSmartPointer pvtkCell = NULL; - - const t8_element_shape_t element_shape = scheme->t8_element_shape (element); - const int num_node = t8_get_number_of_vtk_nodes (element_shape, curved_flag); - /* depending on the element type we choose the correct vtk cell to insert points to */ - if (curved_flag == 0) { - switch (element_shape) { - case T8_ECLASS_VERTEX: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_LINE: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_QUAD: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_TRIANGLE: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_HEX: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_TET: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_PRISM: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_PYRAMID: - pvtkCell = vtkSmartPointer::New (); - break; - default: - SC_ABORT_NOT_REACHED (); - } - } - else { /* curved_flag != 0 */ - switch (element_shape) { - case T8_ECLASS_VERTEX: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_LINE: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_QUAD: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_TRIANGLE: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_HEX: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_TET: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_PRISM: - pvtkCell = vtkSmartPointer::New (); - break; - case T8_ECLASS_PYRAMID: - pvtkCell = vtkSmartPointer::New (); - break; - default: - SC_ABORT_NOT_REACHED (); - } - } - double *coordinates = T8_ALLOC (double, 3 * num_node); - /* Compute coordinates for all vertices inside the domain. */ - t8_forest_vtk_get_element_nodes (forest, itree, element, 0, curved_flag, coordinates); - /* For each element we iterate over all points */ - for (int ivertex = 0; ivertex < num_node; ivertex++, (*point_id)++) { - const size_t offset_3d = 3 * ivertex; - /* Insert point in the points array */ - points->InsertNextPoint (coordinates[offset_3d], coordinates[offset_3d + 1], coordinates[offset_3d + 2]); - - pvtkCell->GetPointIds ()->SetId (ivertex, *point_id); - } - T8_FREE (coordinates); - /* We insert the next cell in the cell array */ - cellArray->InsertNextCell (pvtkCell); - /* - * Write current cell Type in the cell Types array at the elem_id index. - * Depending on the values of the binary inputs write_treeid, - * write_mpirank and write_element_id we also fill the corresponding - * arrays with the data we want(treeid,mpirank,element_id). - * To get the element id, we have to add the local id in the tree - * plus theo - */ - if (curved_flag == 0) { - cellTypes[elem_id - offset] = t8_eclass_vtk_type[element_shape]; - } - else { - cellTypes[elem_id - offset] = t8_curved_eclass_vtk_type[element_shape]; - } - if (write_treeid == 1) { - const t8_gloidx_t gtree_id = t8_forest_global_tree_id (forest, itree); - if (is_ghost) { - vtk_treeid->InsertNextValue (-1); - } - else { - vtk_treeid->InsertNextValue (gtree_id); - } - } - if (write_mpirank == 1) { - vtk_mpirank->InsertNextValue (forest->mpirank); - } - if (write_level == 1) { - vtk_level->InsertNextValue (scheme->t8_element_level (element)); - } - if (write_element_id == 1) { - vtk_element_id->InsertNextValue (elem_id); - } -} -#endif - -int -t8_forest_vtk_write_file_via_API (t8_forest_t forest, const char *fileprefix, const int write_treeid, - const int write_mpirank, const int write_level, const int write_element_id, - const int curved_flag, const int write_ghosts, const int num_data, - t8_vtk_data_field_t *data) -{ -#if T8_WITH_VTK - int freturn = 0; - T8_ASSERT (fileprefix != NULL); - /* - * Write file: First we construct the unstructured Grid - * that will store the points and elements. It requires - * information about the points(coordinates, stored in the points object) - * and the cells(cellTypes and which points belong to this cell) - */ - - vtkSmartPointer unstructuredGrid = vtkSmartPointer::New (); - t8_forest_to_vtkUnstructuredGrid (forest, unstructuredGrid, write_treeid, write_mpirank, write_level, - write_element_id, curved_flag, write_ghosts, num_data, data); - /* - * We define the filename used to write the pvtu and the vtu files. - * The pwriterObj is of class XMLPUnstructuredGridWriter, the P in - * XMLP is important: We want to write a vtu file for each process. - * This class enables us to do exactly that. - */ - char mpifilename[BUFSIZ]; - snprintf (mpifilename, BUFSIZ, "%s.pvtu", fileprefix); - - vtkSmartPointer pwriterObj = vtkSmartPointer::New (); - /* - * Get/Set whether the appended data section is base64 encoded. - * If encoded, reading and writing will be slower, but the file - * will be fully valid XML and text-only. - * If not encoded, the XML specification will be violated, - * but reading and writing will be fast. The default is to do the encoding. - * Documentation: https://vtk.org/doc/release/5.0/html/a02260.html#z3560_2 - */ - pwriterObj->EncodeAppendedDataOff (); - - /* We set the filename of the pvtu file. The filenames of the vtu files - * are given based on the name of the pvtu file and the process number. - */ - pwriterObj->SetFileName (mpifilename); - - /* - * Since we want to write multiple files, the processes - * have to communicate. Therefore, we define the communicator - * vtk_comm and set it as the communicator. - * We have to set a controller for the pwriterObj, - * therefore we define the controller vtk_mpi_ctrl. - */ -#if T8_ENABLE_MPI - vtkSmartPointer vtk_comm = vtkSmartPointer::New (); - vtkMPICommunicatorOpaqueComm vtk_opaque_comm (&forest->mpicomm); - vtk_comm->InitializeExternal (&vtk_opaque_comm); - - vtkSmartPointer vtk_mpi_ctrl = vtkSmartPointer::New (); - vtk_mpi_ctrl->SetCommunicator (vtk_comm); - - pwriterObj->SetController (vtk_mpi_ctrl); -#endif - /* - * We set the number of pieces as the number of mpi processes, - * since we want to write a file for each process. We also - * need to define a Start and EndPiece for the current - * process. Then we can set the inputData for the writer: - * We want to write the unstructured Grid, update the writer - * and then write. - * - * Note: We could write more than one file per process here, if desired. - */ - pwriterObj->SetNumberOfPieces (forest->mpisize); - pwriterObj->SetStartPiece (forest->mpirank); - pwriterObj->SetEndPiece (forest->mpirank); - - /* We set the input data and write the vtu files. */ - pwriterObj->SetInputData (unstructuredGrid); - pwriterObj->Update (); - if (pwriterObj->Write ()) { - /* Writing was successful */ - freturn = 1; - } - else { - t8_errorf ("Error when writing vtk file.\n"); - } - - /* Return whether writing was successful */ - return freturn; - -#else - t8_global_errorf ("Warning: t8code is not linked against vtk library. Vtk output will not be generated.\n"); - t8_global_productionf ("Consider calling 't8_forest_write_vtk' or 't8_forest_vtk_write_file' instead.\n"); - return 0; -#endif -} - -#if T8_WITH_VTK -void -t8_forest_to_vtkUnstructuredGrid (t8_forest_t forest, vtkSmartPointer unstructuredGrid, - const int write_treeid, const int write_mpirank, const int write_level, - const int write_element_id, const int write_ghosts, const int curved_flag, - const int num_data, t8_vtk_data_field_t *data) -{ - /*Check assertions: forest and fileprefix are not NULL and forest is committed */ - T8_ASSERT (forest != NULL); - T8_ASSERT (forest->rc.refcount > 0); - T8_ASSERT (forest->committed); - - long int point_id = 0; /* The id of the point in the points Object. */ - - const t8_gloidx_t offset = t8_forest_get_first_local_element_id (forest); - t8_gloidx_t elem_id = offset; - - vtkSmartPointer cellArray = vtkSmartPointer::New (); - - vtkSmartPointer points = vtkSmartPointer::New (); - - int ghosts = write_ghosts; - if (forest->ghosts == NULL || forest->ghosts->num_ghosts_elements == 0) { - /* Never write ghost elements if there aren't any */ - ghosts = 0; - } - T8_ASSERT (forest->ghosts != NULL || !ghosts); - /* - * The cellTypes Array stores the element types as integers(see vtk doc). - */ - t8_locidx_t num_elements = t8_forest_get_local_num_elements (forest); - if (ghosts) { - num_elements += t8_forest_get_num_ghosts (forest); - } - int *cellTypes = T8_ALLOC (int, num_elements); - - /* - * We need the vertex coords array to be of the - * correct dim. Since it is always the same - * in one mesh, we take the dim of one element. - * We add 1 if we look at a vertext(dim=0) because - * an array of size 0 is not allowed. - * Then we allocate memory, because we do not know - * beforehand how many entries the array needs. - */ - - /* - * We have to define the vtkTypeInt64Array that hold - * metadata if wanted. - */ - - vtkSmartPointer vtk_treeid = vtkSmartPointer::New (); - vtkSmartPointer vtk_mpirank = vtkSmartPointer::New (); - vtkSmartPointer vtk_level = vtkSmartPointer::New (); - vtkSmartPointer vtk_element_id = vtkSmartPointer::New (); - - /* - * We need the dataArray for writing double valued user defined data in the vtu files. - * We want to write num_data many timesteps/arrays. - * We need num_data many vtkDoubleArrays, so we need to allocate storage. - * Later we call the constructor with: dataArrays[idata]=vtkDoubleArray::New() - */ - vtkDoubleArray **dataArrays; - dataArrays = T8_ALLOC (vtkDoubleArray *, num_data); - - const t8_locidx_t num_local_trees = t8_forest_get_num_local_trees (forest); - - /* We iterate over all local trees*/ - for (t8_locidx_t itree = 0; itree < num_local_trees; itree++) { - /* - * We get the current tree, the scheme for this tree - * and the number of elements in this tree. We need the vertices of - * the tree to get the coordinates of the elements later. We need - * the number of elements in this tree to iterate over all of them. - */ - t8_eclass_scheme_c *scheme = t8_forest_get_eclass_scheme (forest, t8_forest_get_tree_class (forest, itree)); - const t8_locidx_t elems_in_tree = t8_forest_get_tree_num_elements (forest, itree); - /* We iterate over all elements in the tree */ - for (t8_locidx_t ielement = 0; ielement < elems_in_tree; ielement++) { - const t8_element_t *element = t8_forest_get_element_in_tree (forest, itree, ielement); - T8_ASSERT (element != NULL); - - t8_forest_element_to_vtk_cell (forest, element, scheme, itree, offset, write_treeid, write_mpirank, write_level, - write_element_id, curved_flag, 0, elem_id, &point_id, cellTypes, points, cellArray, - vtk_treeid, vtk_mpirank, vtk_level, vtk_element_id); - - elem_id++; - } /* end of loop over elements */ - } /* end of loop over local trees */ - if (ghosts) { - /* Get number of ghost-trees */ - const t8_locidx_t num_ghost_trees = t8_forest_ghost_num_trees (forest); - for (t8_locidx_t itree_ghost = 0; itree_ghost < num_ghost_trees; itree_ghost++) { - /* Get Tree scheme of the ghost tree */ - t8_eclass_scheme_c *scheme - = t8_forest_get_eclass_scheme (forest, t8_forest_ghost_get_tree_class (forest, itree_ghost)); - const t8_locidx_t num_ghosts = t8_forest_ghost_tree_num_elements (forest, itree_ghost); - for (t8_locidx_t ielem_ghost = 0; ielem_ghost < num_ghosts; ielem_ghost++) { - const t8_element_t *element = t8_forest_ghost_get_element (forest, itree_ghost, ielem_ghost); - t8_forest_element_to_vtk_cell (forest, element, scheme, itree_ghost + num_local_trees, offset, write_treeid, - write_mpirank, write_level, write_element_id, curved_flag, 1, elem_id, &point_id, - cellTypes, points, cellArray, vtk_treeid, vtk_mpirank, vtk_level, - vtk_element_id); - elem_id++; - } - } - } - - unstructuredGrid->SetPoints (points); - unstructuredGrid->SetCells (cellTypes, cellArray); - - if (write_treeid) { - vtk_treeid->SetName ("treeid"); - unstructuredGrid->GetCellData ()->AddArray (vtk_treeid); - } - if (write_mpirank) { - vtk_mpirank->SetName ("mpirank"); - unstructuredGrid->GetCellData ()->AddArray (vtk_mpirank); - } - if (write_level) { - vtk_level->SetName ("level"); - unstructuredGrid->GetCellData ()->AddArray (vtk_level); - } - if (write_element_id) { - vtk_element_id->SetName ("element_id"); - unstructuredGrid->GetCellData ()->AddArray (vtk_element_id); - } - - /* Write the user defined data fields. - * For that we iterate over the idata, set the name, the array - * and then give this data to the unstructured Grid Object. - * We differentiate between scalar and vector data. - */ - for (int idata = 0; idata < num_data; idata++) { - dataArrays[idata] = vtkDoubleArray::New (); - const int num_components = data[idata].type == T8_VTK_SCALAR ? 1 : 3; - dataArrays[idata]->SetName (data[idata].description); /* Set the name of the array */ - dataArrays[idata]->SetNumberOfTuples (num_elements); /* We want number of tuples=number of elements */ - dataArrays[idata]->SetNumberOfComponents (num_components); /* Each tuples has 3 values */ - dataArrays[idata]->SetVoidArray (data[idata].data, num_elements * num_components, 1); - unstructuredGrid->GetCellData ()->AddArray (dataArrays[idata]); - } - - /* We have to free the allocated memory for the cellTypes Array and the other arrays we allocated memory for. */ - for (int idata = 0; idata < num_data; idata++) { - dataArrays[idata]->Delete (); - } - - T8_FREE (cellTypes); - T8_FREE (dataArrays); -} -#endif - static t8_locidx_t t8_forest_num_points (t8_forest_t forest, const int count_ghosts) { @@ -692,11 +207,11 @@ t8_forest_vtk_cells_offset_kernel (t8_forest_t forest, const t8_locidx_t ltree_i if (modus == T8_VTK_KERNEL_INIT) { *data = T8_ALLOC_ZERO (long long, 1); - return 1; + return true; } else if (modus == T8_VTK_KERNEL_CLEANUP) { T8_FREE (*data); - return 1; + return true; } T8_ASSERT (modus == T8_VTK_KERNEL_EXECUTE); @@ -706,7 +221,7 @@ t8_forest_vtk_cells_offset_kernel (t8_forest_t forest, const t8_locidx_t ltree_i *offset += num_vertices; freturn = fprintf (vtufile, " %lld", *offset); if (freturn <= 0) { - return 0; + return false; } *columns += 1; @@ -1260,9 +775,9 @@ t8_forest_vtk_write_points (t8_forest_t forest, FILE *vtufile, const int write_g } int -t8_forest_vtk_write_file (t8_forest_t forest, const char *fileprefix, const int write_treeid, const int write_mpirank, - const int write_level, const int write_element_id, int write_ghosts, const int num_data, - t8_vtk_data_field_t *data) +t8_forest_vtk_write_ASCII (t8_forest_t forest, const char *fileprefix, const int write_treeid, const int write_mpirank, + const int write_level, const int write_element_id, int write_ghosts, const int num_data, + t8_vtk_data_field_t *data) { FILE *vtufile = NULL; t8_locidx_t num_elements, num_points; @@ -1374,4 +889,286 @@ t8_forest_vtk_write_file (t8_forest_t forest, const char *fileprefix, const int return 0; } -T8_EXTERN_C_END (); +/* Return the local number of vertices in a cmesh. + * \param [in] cmesh The cmesh to be considered. + * \param [in] count_ghosts If true, we also count the vertices of the ghost trees. + * \return The number of vertices associated to \a cmesh. + * \a cmesh must be committed before calling this function. + */ +static t8_gloidx_t +t8_cmesh_get_num_vertices (const t8_cmesh_t cmesh, const int count_ghosts) +{ + int iclass; + t8_eclass_t ghost_class; + t8_gloidx_t num_vertices = 0; + t8_locidx_t ighost; + T8_ASSERT (cmesh != NULL); + T8_ASSERT (cmesh->committed); + + for (iclass = T8_ECLASS_ZERO; iclass < T8_ECLASS_COUNT; iclass++) { + num_vertices += t8_eclass_num_vertices[iclass] * cmesh->num_local_trees_per_eclass[iclass]; + } + if (count_ghosts) { + /* Also count the vertices of the ghost trees */ + for (ighost = 0; ighost < t8_cmesh_get_num_ghosts (cmesh); ighost++) { + ghost_class = t8_cmesh_get_ghost_class (cmesh, ighost); + num_vertices += t8_eclass_num_vertices[ghost_class]; + } + } + + return num_vertices; +} + +static int +t8_cmesh_vtk_write_file_ext (const t8_cmesh_t cmesh, const char *fileprefix, const int write_ghosts) +{ + T8_ASSERT (cmesh != NULL); + T8_ASSERT (t8_cmesh_is_committed (cmesh)); + T8_ASSERT (fileprefix != NULL); + + if (cmesh->mpirank == 0) { + /* Write the pvtu header file. */ + int num_ranks_that_write = cmesh->set_partition ? cmesh->mpisize : 1; + if (t8_write_pvtu (fileprefix, num_ranks_that_write, 1, 1, 0, 0, 0, NULL)) { + SC_ABORTF ("Error when writing file %s.pvtu\n", fileprefix); + } + } + /* If the cmesh is replicated only rank 0 prints it, + * otherwise each process prints its part of the cmesh.*/ + if (cmesh->mpirank == 0 || cmesh->set_partition) { + char vtufilename[BUFSIZ]; + FILE *vtufile; + t8_locidx_t num_vertices, ivertex; + t8_locidx_t num_trees; + t8_ctree_t tree; + double x, y, z; + double *vertices, *vertex; + int k, sk; + long long offset, count_vertices; + t8_locidx_t ighost, num_ghosts = 0, num_loc_trees; +#ifdef T8_ENABLE_DEBUG + t8_cghost_t ghost; +#endif + t8_eclass_t eclass; + + num_vertices = t8_cmesh_get_num_vertices (cmesh, write_ghosts); + num_trees = t8_cmesh_get_num_local_trees (cmesh); + if (write_ghosts) { + num_trees += t8_cmesh_get_num_ghosts (cmesh); + } + + snprintf (vtufilename, BUFSIZ, "%s_%04d.vtu", fileprefix, cmesh->mpirank); + vtufile = fopen (vtufilename, "wb"); + if (vtufile == NULL) { + t8_global_errorf ("Could not open file %s for output.\n", vtufilename); + return 0; + } + fprintf (vtufile, "\n"); + fprintf (vtufile, "\n"); +#else + fprintf (vtufile, " byte_order=\"LittleEndian\">\n"); +#endif + fprintf (vtufile, " \n"); + fprintf (vtufile, " \n", (long long) num_vertices, + (long long) num_trees); + fprintf (vtufile, " \n"); + + /* write point position data */ + fprintf (vtufile, + " \n", + T8_VTK_FLOAT_NAME, T8_VTK_FORMAT_STRING); + + for (tree = t8_cmesh_get_first_tree (cmesh); tree != NULL; tree = t8_cmesh_get_next_tree (cmesh, tree)) { + /* TODO: Use new geometry here. Need cmesh_get_reference coords function. */ + vertices = t8_cmesh_get_tree_vertices (cmesh, tree->treeid); + for (ivertex = 0; ivertex < t8_eclass_num_vertices[tree->eclass]; ivertex++) { + vertex = vertices + 3 * t8_eclass_t8_to_vtk_corner_number[tree->eclass][ivertex]; + x = vertex[0]; + y = vertex[1]; + z = vertex[2]; +#ifdef T8_VTK_DOUBLES + fprintf (vtufile, " %24.16e %24.16e %24.16e\n", x, y, z); +#else + fprintf (vtufile, " %16.8e %16.8e %16.8e\n", x, y, z); +#endif + } + } /* end tree loop */ + if (write_ghosts) { + + /* Write the vertices of the ghost trees */ + num_ghosts = t8_cmesh_get_num_ghosts (cmesh); + num_loc_trees = t8_cmesh_get_num_local_trees (cmesh); + for (ighost = 0; ighost < num_ghosts; ighost++) { + /* Get the eclass of this ghost */ + eclass = t8_cmesh_get_ghost_class (cmesh, ighost); + /* Get a pointer to this ghosts vertices */ + vertices = (double *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), 0, ighost + num_loc_trees); + T8_ASSERT (vertices != NULL); + /* TODO: This code is duplicated above */ + for (ivertex = 0; ivertex < t8_eclass_num_vertices[eclass]; ivertex++) { + vertex = vertices + 3 * t8_eclass_vtk_to_t8_corner_number[eclass][ivertex]; + x = vertex[0]; + y = vertex[1]; + z = vertex[2]; +#ifdef T8_VTK_DOUBLES + fprintf (vtufile, " %24.16e %24.16e %24.16e\n", x, y, z); +#else + fprintf (vtufile, " %16.8e %16.8e %16.8e\n", x, y, z); +#endif + } + } /* end ghost loop */ + } + fprintf (vtufile, " \n"); + fprintf (vtufile, " \n"); + fprintf (vtufile, " \n"); + + /* write connectivity data */ + fprintf (vtufile, + " \n", + T8_VTK_LOCIDX, T8_VTK_FORMAT_STRING); + for (tree = t8_cmesh_get_first_tree (cmesh), count_vertices = 0; tree != NULL; + tree = t8_cmesh_get_next_tree (cmesh, tree)) { + fprintf (vtufile, " "); + for (k = 0; k < t8_eclass_num_vertices[tree->eclass]; ++k, count_vertices++) { + fprintf (vtufile, " %lld", count_vertices); + } + fprintf (vtufile, "\n"); + } + if (write_ghosts) { + /* Write the ghost connectivity */ + for (ighost = 0; ighost < num_ghosts; ighost++) { + eclass = t8_cmesh_get_ghost_class (cmesh, ighost); + fprintf (vtufile, " "); + for (k = 0; k < t8_eclass_num_vertices[eclass]; ++k, count_vertices++) { + fprintf (vtufile, " %lld", count_vertices); + } + fprintf (vtufile, "\n"); + } + } + fprintf (vtufile, " \n"); + + /* write offset data */ + fprintf (vtufile, + " \n", + T8_VTK_LOCIDX, T8_VTK_FORMAT_STRING); + fprintf (vtufile, " "); + for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1, offset = 0; tree != NULL; + tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) { + offset += t8_eclass_num_vertices[tree->eclass]; + fprintf (vtufile, " %lld", offset); + if (!(sk % 8)) + fprintf (vtufile, "\n "); + } + if (write_ghosts) { + /* ghost offset data */ + for (ighost = 0; ighost < num_ghosts; ighost++, ++sk) { + eclass = t8_cmesh_get_ghost_class (cmesh, ighost); + offset += t8_eclass_num_vertices[eclass]; + fprintf (vtufile, " %lld", offset); + if (!(sk % 8)) + fprintf (vtufile, "\n "); + } + } + fprintf (vtufile, "\n"); + fprintf (vtufile, " \n"); + /* write type data */ + fprintf (vtufile, + " \n", + T8_VTK_FORMAT_STRING); + fprintf (vtufile, " "); + for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1; tree != NULL; + tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) { + fprintf (vtufile, " %d", t8_eclass_vtk_type[tree->eclass]); + if (!(sk % 20) && tree->treeid != (cmesh->num_local_trees - 1)) + fprintf (vtufile, "\n "); + } + if (write_ghosts) { + /* ghost offset types */ + for (ighost = 0; ighost < num_ghosts; ighost++, ++sk) { + eclass = t8_cmesh_get_ghost_class (cmesh, ighost); + fprintf (vtufile, " %d", t8_eclass_vtk_type[eclass]); + if (!(sk % 20) && ighost != (num_ghosts - 1)) + fprintf (vtufile, "\n "); + } + } + fprintf (vtufile, "\n"); + fprintf (vtufile, " \n"); + fprintf (vtufile, " \n"); + /* write treeif data */ + fprintf (vtufile, " \n"); + fprintf (vtufile, + " \n", + T8_VTK_GLOIDX, T8_VTK_FORMAT_STRING); + fprintf (vtufile, " "); + for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1, offset = 0; tree != NULL; + tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) { + /* Since tree_id is actually 64 Bit but we store it as 32, we have to check + * that we do not get into conversion errors */ + /* TODO: We switched to 32 Bit because Paraview could not handle 64 well enough. + */ + T8_ASSERT (tree->treeid + cmesh->first_tree == (t8_gloidx_t) ((long) tree->treeid + cmesh->first_tree)); + fprintf (vtufile, " %ld", (long) tree->treeid + cmesh->first_tree); + if (!(sk % 8)) + fprintf (vtufile, "\n "); + } + if (write_ghosts) { + /* ghost offset types */ + for (ighost = 0; ighost < num_ghosts; ighost++, ++sk) { +#ifdef T8_ENABLE_DEBUG + ghost = t8_cmesh_trees_get_ghost (cmesh->trees, ighost); + /* Check for conversion errors */ + T8_ASSERT (ghost->treeid == (t8_gloidx_t) ((long) ghost->treeid)); +#endif + /* Write -1 as tree_id so that we can distinguish ghosts from normal trees + * in the vtk file */ + fprintf (vtufile, " %ld", (long) -1); + if (!(sk % 8)) + fprintf (vtufile, "\n "); + } + } + fprintf (vtufile, "\n"); + fprintf (vtufile, " \n"); + /* write mpirank data */ + fprintf (vtufile, + " \n", + "Int32", T8_VTK_FORMAT_STRING); + fprintf (vtufile, " "); + for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1, offset = 0; tree != NULL; + tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) { + fprintf (vtufile, " %i", cmesh->mpirank); + if (!(sk % 8)) + fprintf (vtufile, "\n "); + } + if (write_ghosts) { + /* write our rank for each ghost */ + for (ighost = 0; ighost < num_ghosts; ighost++, ++sk) { + fprintf (vtufile, " %i", cmesh->mpirank); + if (!(sk % 8)) + fprintf (vtufile, "\n "); + } + } + fprintf (vtufile, "\n"); + fprintf (vtufile, " \n"); + fprintf (vtufile, " \n"); + /* write type data */ + fprintf (vtufile, " \n"); + fprintf (vtufile, " \n"); + fprintf (vtufile, "\n"); + fclose (vtufile); + } + return 1; +} + +int +t8_cmesh_vtk_write_ASCII (const t8_cmesh_t cmesh, const char *fileprefix) +{ + return t8_cmesh_vtk_write_file_ext (cmesh, fileprefix, 1); +} diff --git a/src/t8_vtk/t8_vtk_write_ASCII.hxx b/src/t8_vtk/t8_vtk_write_ASCII.hxx new file mode 100644 index 0000000000..aa04e0cd1a --- /dev/null +++ b/src/t8_vtk/t8_vtk_write_ASCII.hxx @@ -0,0 +1,57 @@ +/* + 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. +*/ + +#ifndef T8_VTK_WRITE_ASCII_HXX +#define T8_VTK_WRITE_ASCII_HXX + +#include "t8_forest/t8_forest_types.h" +#include "t8_vtk.h" + +/** Write the forest in .pvtu file format. Writes one .vtu file per + * process and a meta .pvtu file. + * This function writes ASCII files and can be used when + * t8code is not configure with "--with-vtk" and + * \ref t8_forest_vtk_write_file_via_API is not available. + * \param [in] forest The forest. + * \param [in] fileprefix The prefix of the output files. + * \param [in] write_treeid If true, the global tree id is written for each element. + * \param [in] write_mpirank If true, the mpirank is written for each element. + * \param [in] write_level If true, the refinement level is written for each element. + * \param [in] write_element_id If true, the global element id is written for each element. + * \param [in] write_ghosts If true, each process additionally writes its ghost elements. + * For ghost element the treeid is -1. + * \param [in] num_data Number of user defined double valued data fields to write. + * \param [in] data Array of t8_vtk_data_field_t of length \a num_data + * providing the used defined per element data. + * If scalar and vector fields are used, all scalar fields + * must come first in the array. + * \return True if successful, false if not (process local). + */ +int +t8_forest_vtk_write_ASCII (t8_forest_t forest, const char *fileprefix, const int write_treeid, const int write_mpirank, + const int write_level, const int write_element_id, int write_ghosts, const int num_data, + t8_vtk_data_field_t *data); + +int +t8_cmesh_vtk_write_ASCII (t8_cmesh_t cmesh, const char *fileprefix); + +#endif /* T8_VTK_WRITE_ASCII_HXX */ diff --git a/src/t8_vtk/t8_vtk_writer.cxx b/src/t8_vtk/t8_vtk_writer.cxx new file mode 100644 index 0000000000..67f0172982 --- /dev/null +++ b/src/t8_vtk/t8_vtk_writer.cxx @@ -0,0 +1,160 @@ +/* + 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. +*/ + +#include + +#if T8_WITH_VTK +#include +#endif + +#if T8_WITH_VTK +/** + * \brief template specialization for forests. + * + */ +template <> +void +vtk_writer::t8_grid_tree_to_vtk_cells ( + const t8_forest_t forest, vtkSmartPointer unstructuredGrid, + vtkSmartPointer vtk_treeid, vtkSmartPointer vtk_mpirank, + vtkSmartPointer vtk_level, vtkSmartPointer vtk_element_id, + vtkSmartPointer cellArray, vtkSmartPointer points, int *cellTypes, + const t8_locidx_t num_local_trees, t8_gloidx_t *elem_id, long int *point_id, const t8_gloidx_t offset, + const bool ghosts, const t8_locidx_t itree) +{ + /* For both ghosts and pure-local trees iterate over all elements and translate them into a vtk cell. */ + if (ghosts) { + const t8_locidx_t num_ghosts = t8_forest_ghost_tree_num_elements (forest, itree); + for (t8_locidx_t ielem_ghost = 0; ielem_ghost < num_ghosts; ielem_ghost++) { + const t8_element_t *element = t8_forest_ghost_get_element (forest, itree, ielem_ghost); + this->t8_grid_element_to_vtk_cell (forest, element, itree + num_local_trees, offset, true, *elem_id, point_id, + cellTypes, points, cellArray, vtk_treeid, vtk_mpirank, vtk_level, + vtk_element_id); + (*elem_id)++; + } + } + else { + const t8_locidx_t elems_in_tree = t8_forest_get_tree_num_elements (forest, itree); + /* We iterate over all elements in the tree */ + for (t8_locidx_t ielement = 0; ielement < elems_in_tree; ielement++) { + const t8_element_t *element = t8_forest_get_element_in_tree (forest, itree, ielement); + T8_ASSERT (element != NULL); + this->t8_grid_element_to_vtk_cell (forest, element, itree, offset, true, *elem_id, point_id, cellTypes, points, + cellArray, vtk_treeid, vtk_mpirank, vtk_level, vtk_element_id); + (*elem_id)++; + + } /* end of loop over elements */ + } + return; +} + +/** + * \brief template specialization for cmeshes. + * + */ +template <> +void +vtk_writer::t8_grid_tree_to_vtk_cells ( + const t8_cmesh_t cmesh, vtkSmartPointer unstructuredGrid, + vtkSmartPointer vtk_treeid, vtkSmartPointer vtk_mpirank, + vtkSmartPointer vtk_level, vtkSmartPointer vtk_element_id, + vtkSmartPointer cellArray, vtkSmartPointer points, int *cellTypes, + const t8_locidx_t num_local_trees, t8_gloidx_t *elem_id, long int *point_id, const t8_gloidx_t offset, + const bool ghosts, const t8_locidx_t itree) +{ + /* A cmesh does not have any further elements, we can call the translator directly. */ + this->t8_grid_element_to_vtk_cell (cmesh, NULL, itree, offset, ghosts, *elem_id, point_id, cellTypes, points, + cellArray, vtk_treeid, vtk_mpirank, vtk_level, vtk_element_id); + (*elem_id)++; + return; +} +#endif /* T8_WITH_VTK */ + +template <> +bool +vtk_writer::write_ASCII (const t8_forest_t forest) +{ + return t8_forest_vtk_write_ASCII (forest, this->fileprefix.c_str (), this->write_treeid, this->write_mpirank, + this->write_level, this->write_element_id, this->write_ghosts, this->num_data, + this->data); +} + +template <> +bool +vtk_writer::write_ASCII (const t8_cmesh_t forest) +{ + return t8_cmesh_vtk_write_ASCII (forest, this->fileprefix.c_str ()); +} + +/* Implementation of the c-interface */ +T8_EXTERN_C_BEGIN (); + +int +t8_forest_vtk_write_file_via_API (const t8_forest_t forest, const char *fileprefix, const int write_treeid, + const int write_mpirank, const int write_level, const int write_element_id, + const int curved_flag, const int write_ghosts, const int num_data, + t8_vtk_data_field_t *data) +{ + vtk_writer writer (write_treeid, write_mpirank, write_level, write_element_id, write_ghosts, curved_flag, + std::string (fileprefix), num_data, data, t8_forest_get_mpicomm (forest)); + return writer.write_with_API (forest); +} + +int +t8_forest_vtk_write_file (const t8_forest_t forest, const char *fileprefix, const int write_treeid, + const int write_mpirank, const int write_level, const int write_element_id, int write_ghosts, + const int num_data, t8_vtk_data_field_t *data) +{ + vtk_writer writer (write_treeid, write_mpirank, write_level, write_element_id, write_ghosts, false, + std::string (fileprefix), num_data, data, t8_forest_get_mpicomm (forest)); + return writer.write_ASCII (forest); +} + +int +t8_cmesh_vtk_write_file_via_API (const t8_cmesh_t cmesh, const char *fileprefix, sc_MPI_Comm comm) +{ + vtk_writer writer (std::string (fileprefix), comm); + return writer.write_with_API (cmesh); +} + +int +t8_cmesh_vtk_write_file (const t8_cmesh_t cmesh, const char *fileprefix) +{ + /* No mpi Communicator is needed for ASCII output*/ + vtk_writer writer (std::string (fileprefix), sc_MPI_COMM_NULL); + return writer.write_ASCII (cmesh); +} + +#if T8_WITH_VTK +void +t8_forest_to_vtkUnstructuredGrid (const t8_forest_t forest, vtkSmartPointer unstructuredGrid, + const int write_treeid, const int write_mpirank, const int write_level, + const int write_element_id, const int write_ghosts, const int curved_flag, + const int num_data, t8_vtk_data_field_t *data) +{ + vtk_writer writer (write_treeid, write_mpirank, write_level, write_element_id, write_ghosts, curved_flag, + std::string (""), num_data, data, t8_forest_get_mpicomm (forest)); + writer.grid_to_vtkUnstructuredGrid (forest, unstructuredGrid); +} +#endif + +T8_EXTERN_C_END (); diff --git a/src/t8_forest/t8_forest_vtk.h b/src/t8_vtk/t8_vtk_writer.h similarity index 78% rename from src/t8_forest/t8_forest_vtk.h rename to src/t8_vtk/t8_vtk_writer.h index 2b85b8c2a0..1e65dc2f3f 100644 --- a/src/t8_forest/t8_forest_vtk.h +++ b/src/t8_vtk/t8_vtk_writer.h @@ -3,7 +3,7 @@ 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) 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 @@ -20,24 +20,18 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/** file t8_forest_vtk.h - */ - -/* TODO: Document this file */ - -#ifndef T8_FOREST_VTK_H -#define T8_FOREST_VTK_H +#ifndef T8_VTK_WRITER_C_INTERFACE_H +#define T8_VTK_WRITER_C_INTERFACE_H +#include #include -#include -#include +#include #if T8_WITH_VTK #include #endif T8_EXTERN_C_BEGIN (); -/* function declarations */ #if T8_WITH_VTK /** @@ -117,6 +111,42 @@ t8_forest_vtk_write_file (t8_forest_t forest, const char *fileprefix, const int const int write_level, const int write_element_id, int write_ghosts, const int num_data, t8_vtk_data_field_t *data); -T8_EXTERN_C_END (); +/** + * Write the cmesh in .pvtu file format. Writes one .vtu file per + * process and a meta .pvtu file. + * This function uses the vtk library. t8code must be configured with + * "--with-vtk" in order to use it. + * + * \param[in] cmesh The cmesh + * \param[in] fileprefix The prefix of the output files + * \param[in] comm The communicator to use + * \return int + * \note If t8code was not configured with vtk, use \ref t8_cmesh_vtk_write_file + */ +int +t8_cmesh_vtk_write_file_via_API (t8_cmesh_t cmesh, const char *fileprefix, sc_MPI_Comm comm); + +/** + * Write the cmesh in .pvtu file format. Writes one .vtu file per + * process and a meta .pvtu file. + * This function writes ASCII files and can be used when + * t8code is not configure with "--with-vtk" and + * \ref t8_cmesh_vtk_write_file_via_API is not available. + * + * \param[in] cmesh The cmesh + * \param[in] fileprefix The prefix of the output files + * \return int + */ +int +t8_cmesh_vtk_write_file (t8_cmesh_t cmesh, const char *fileprefix); -#endif /* !T8_FOREST_VTK_H */ +#if T8_WITH_VTK +void +t8_forest_to_vtkUnstructuredGrid (t8_forest_t forest, vtkSmartPointer unstructuredGrid, + const int write_treeid, const int write_mpirank, const int write_level, + const int write_element_id, const int write_ghosts, const int curved_flag, + const int num_data, t8_vtk_data_field_t *data); +#endif + +T8_EXTERN_C_END (); +#endif /* T8_VTK_WRITER_C_INTERFACE_H */ diff --git a/src/t8_vtk/t8_vtk_writer.hxx b/src/t8_vtk/t8_vtk_writer.hxx index fcd41d664d..8b992effc5 100644 --- a/src/t8_vtk/t8_vtk_writer.hxx +++ b/src/t8_vtk/t8_vtk_writer.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_VTK_WRITER_HXX @@ -30,6 +30,7 @@ along with t8code; if not, write to the Free Software Foundation, Inc., #include #include "t8_forest/t8_forest_types.h" #include "t8_vtk/t8_vtk_writer_helper.hxx" +#include "t8_vtk/t8_vtk_write_ASCII.hxx" #include #include @@ -62,8 +63,8 @@ along with t8code; if not, write to the Free Software Foundation, Inc., #include #include #include -#endif -#endif +#endif /* T8_ENABLE_MPI */ +#endif /* T8_WITH_VTK */ /** * A class that controls the writing of vtk files for cmeshes or forests. @@ -92,8 +93,28 @@ 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) + { + } + + /** + * Construct a new vtk writer object. All parameters are set to false. + * + * \param[in] fileprefix + * \param[in] comm + */ + vtk_writer (std::string fileprefix, sc_MPI_Comm comm): fileprefix (fileprefix), comm (comm) + { + } + +#if T8_WITH_VTK + void + grid_to_vtkUnstructuredGrid (const grid_t grid, vtkSmartPointer unstructuredGrid) + { + this->t8_grid_to_vtkUnstructuredGrid (grid, unstructuredGrid); + } +#endif /* T8_WITH_VTK */ /** * A vtk-writer function that uses the vtk API. @@ -103,11 +124,21 @@ class vtk_writer { * \return false if writing was not successful. */ bool - write (const grid_t grid) + write_with_API (const grid_t grid) { return write_vtk (grid); } + /** + * A vtk-writer function that uses the vtk API + * + * \param[in] grid The forest or cmesh that is translated + * \return true + * \return false + */ + bool + write_ASCII (const grid_t grid); + private: #if T8_WITH_VTK /** @@ -440,7 +471,7 @@ class vtk_writer { vtk_mpi_ctrl->SetCommunicator (vtk_comm); pwriterObj->SetController (vtk_mpi_ctrl); -#endif +#endif /* T8_ENABLE_MPI */ /* * We set the number of pieces as the number of mpi processes, * since we want to write a file for each process. We also @@ -494,67 +525,4 @@ class vtk_writer { sc_MPI_Comm comm; }; -#if T8_WITH_VTK -/** - * \brief template specialization for forests. - * - */ -template <> -void -vtk_writer::t8_grid_tree_to_vtk_cells ( - const t8_forest_t forest, vtkSmartPointer unstructuredGrid, - vtkSmartPointer vtk_treeid, vtkSmartPointer vtk_mpirank, - vtkSmartPointer vtk_level, vtkSmartPointer vtk_element_id, - vtkSmartPointer cellArray, vtkSmartPointer points, int *cellTypes, - const t8_locidx_t num_local_trees, t8_gloidx_t *elem_id, long int *point_id, const t8_gloidx_t offset, - const bool ghosts, const t8_locidx_t itree) -{ - /* For both ghosts and pure-local trees iterate over all elements and translate them into a vtk cell. */ - if (ghosts) { - const t8_locidx_t num_ghosts = t8_forest_ghost_tree_num_elements (forest, itree); - for (t8_locidx_t ielem_ghost = 0; ielem_ghost < num_ghosts; ielem_ghost++) { - const t8_element_t *element = t8_forest_ghost_get_element (forest, itree, ielem_ghost); - this->t8_grid_element_to_vtk_cell (forest, element, itree + num_local_trees, offset, true, *elem_id, point_id, - cellTypes, points, cellArray, vtk_treeid, vtk_mpirank, vtk_level, - vtk_element_id); - (*elem_id)++; - } - } - else { - const t8_locidx_t elems_in_tree = t8_forest_get_tree_num_elements (forest, itree); - /* We iterate over all elements in the tree */ - for (t8_locidx_t ielement = 0; ielement < elems_in_tree; ielement++) { - const t8_element_t *element = t8_forest_get_element_in_tree (forest, itree, ielement); - T8_ASSERT (element != NULL); - this->t8_grid_element_to_vtk_cell (forest, element, itree, offset, true, *elem_id, point_id, cellTypes, points, - cellArray, vtk_treeid, vtk_mpirank, vtk_level, vtk_element_id); - (*elem_id)++; - - } /* end of loop over elements */ - } - return; -} - -/** - * \brief template specialization for cmeshes. - * - */ -template <> -void -vtk_writer::t8_grid_tree_to_vtk_cells ( - const t8_cmesh_t cmesh, vtkSmartPointer unstructuredGrid, - vtkSmartPointer vtk_treeid, vtkSmartPointer vtk_mpirank, - vtkSmartPointer vtk_level, vtkSmartPointer vtk_element_id, - vtkSmartPointer cellArray, vtkSmartPointer points, int *cellTypes, - const t8_locidx_t num_local_trees, t8_gloidx_t *elem_id, long int *point_id, const t8_gloidx_t offset, - const bool ghosts, const t8_locidx_t itree) -{ - /* A cmesh does not have any further elements, we can call the translatore directly. */ - this->t8_grid_element_to_vtk_cell (cmesh, NULL, itree, offset, ghosts, *elem_id, point_id, cellTypes, points, - cellArray, vtk_treeid, vtk_mpirank, vtk_level, vtk_element_id); - (*elem_id)++; - return; -} -#endif /* T8_WITH_VTK */ - #endif /* T8_VTK_WRITER_HXX */ diff --git a/src/t8_vtk/t8_vtk_writer_helper.cxx b/src/t8_vtk/t8_vtk_writer_helper.cxx new file mode 100644 index 0000000000..976c403c88 --- /dev/null +++ b/src/t8_vtk/t8_vtk_writer_helper.cxx @@ -0,0 +1,208 @@ +/* + 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. +*/ + +#include +#include +#include +#include + +int +t8_get_number_of_vtk_nodes (const t8_element_shape_t eclass, const int curved_flag) +{ + /* Use the lookup table of the eclasses. */ + if (curved_flag) { + return t8_curved_eclass_num_nodes[eclass]; + } + return t8_eclass_num_vertices[eclass]; +} + +void +t8_forest_vtk_get_element_nodes (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element, const int vertex, + const int curved_flag, double *out_coords) +{ + const t8_eclass_t tree_class = t8_forest_get_tree_class (forest, ltreeid); + const t8_eclass_scheme_c *scheme = t8_forest_get_eclass_scheme (forest, tree_class); + const t8_element_shape_t element_shape = scheme->t8_element_shape (element); + const double *ref_coords = t8_forest_vtk_point_to_element_ref_coords[element_shape][vertex]; + const int num_node = t8_get_number_of_vtk_nodes (element_shape, curved_flag); + t8_forest_element_from_ref_coords (forest, ltreeid, element, ref_coords, num_node, out_coords); +} + +template <> +t8_locidx_t +grid_local_num_elements (const t8_forest_t grid) +{ + return t8_forest_get_local_num_elements (grid); +} + +template <> +t8_locidx_t +grid_local_num_elements (const t8_cmesh_t grid) +{ + return t8_cmesh_get_num_local_trees (grid); +} + +template <> +t8_locidx_t +grid_local_num_trees (const t8_forest_t grid) +{ + return t8_forest_get_num_local_trees (grid); +} + +template <> +t8_locidx_t +grid_local_num_trees (const t8_cmesh_t grid) +{ + return t8_cmesh_get_num_local_trees (grid); +} + +template <> +t8_locidx_t +grid_local_num_ghost_trees (const t8_forest_t grid) +{ + return t8_forest_get_num_ghost_trees (grid); +} + +template <> +t8_locidx_t +grid_local_num_ghost_trees (const t8_cmesh_t grid) +{ + return t8_cmesh_get_num_ghosts (grid); +} + +template <> +t8_gloidx_t +grid_first_local_id (const t8_forest_t grid) +{ + return t8_forest_get_first_local_element_id (grid); +} + +template <> +t8_gloidx_t +grid_first_local_id (const t8_cmesh_t grid) +{ + return t8_cmesh_get_first_treeid (grid); +} + +template <> +t8_gloidx_t +tree_local_to_global_id (const t8_forest_t grid, t8_locidx_t ltree) +{ + return t8_forest_global_tree_id (grid, ltree); +} + +template <> +t8_gloidx_t +tree_local_to_global_id (const t8_cmesh_t grid, t8_locidx_t ltree) +{ + return t8_cmesh_get_global_id (grid, ltree); +} + +template <> +bool +grid_do_ghosts (const t8_forest_t grid, const int write_ghosts) +{ + bool ghosts = write_ghosts; + if (grid->ghosts == NULL || grid->ghosts->num_ghosts_elements == 0) { + /* Never write ghost elements if there aren't any */ + ghosts = false; + } + T8_ASSERT (grid->ghosts != NULL || !ghosts); + return ghosts; +} + +template <> +bool +grid_do_ghosts (const t8_cmesh_t grid, const int write_ghosts) +{ + bool ghosts = write_ghosts; + if (t8_cmesh_get_num_ghosts (grid) == 0) { + /* Never write ghost elements if there aren't any */ + ghosts = false; + } + return ghosts; +} + +template <> +t8_locidx_t +num_cells_to_write (const t8_forest_t grid, const int write_ghosts) +{ + return grid_local_num_elements (grid) + (write_ghosts ? t8_forest_get_num_ghost_trees (grid) : 0); +} + +template <> +t8_locidx_t +num_cells_to_write (const t8_cmesh_t grid, const int write_ghosts) +{ + return grid_local_num_elements (grid) + (write_ghosts ? t8_cmesh_get_num_ghosts (grid) : 0); +} + +template <> +t8_element_shape_t +grid_element_shape (const t8_forest_t grid, const t8_locidx_t itree, const t8_element_t *element) +{ + const t8_eclass_t eclass = t8_forest_get_eclass (grid, itree); + t8_eclass_scheme *scheme = t8_forest_get_eclass_scheme (grid, eclass); + return scheme->t8_element_shape (element); +} + +template <> +t8_element_shape_t +grid_element_shape (const t8_cmesh_t grid, const t8_locidx_t itree, const t8_element_t *element) +{ + return t8_cmesh_get_tree_class (grid, itree); +} + +template <> +void +grid_element_to_coords (const t8_forest_t grid, const t8_locidx_t itree, const t8_element_t *element, + const int curved_flag, double *coordinates, const int num_node, + const t8_element_shape_t shape) +{ + t8_forest_vtk_get_element_nodes (grid, itree, element, 0, curved_flag, coordinates); +} + +template <> +void +grid_element_to_coords (const t8_cmesh_t grid, const t8_locidx_t itree, const t8_element_t *element, + const int curved_flag, double *coordinates, const int num_node, + const t8_element_shape_t shape) +{ + const double *ref_coords = t8_forest_vtk_point_to_element_ref_coords[shape][curved_flag]; + const t8_gloidx_t gtree_id = t8_cmesh_get_global_id (grid, itree); + t8_geometry_evaluate (grid, gtree_id, ref_coords, num_node, coordinates); +} + +template <> +int +grid_element_level (const t8_forest_t grid, const t8_locidx_t itree, const t8_element_t *element) +{ + const t8_eclass_t eclass = t8_forest_get_eclass (grid, itree); + t8_eclass_scheme *scheme = t8_forest_get_eclass_scheme (grid, eclass); + return scheme->t8_element_level (element); +} +template <> +int +grid_element_level (const t8_cmesh_t grid, const t8_locidx_t itree, const t8_element_t *element) +{ + return 0; +} diff --git a/src/t8_vtk/t8_vtk_writer_helper.hxx b/src/t8_vtk/t8_vtk_writer_helper.hxx index 3df1694e03..513d1b64bb 100644 --- a/src/t8_vtk/t8_vtk_writer_helper.hxx +++ b/src/t8_vtk/t8_vtk_writer_helper.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_VTK_WRITER_HELPER @@ -25,13 +25,16 @@ along with t8code; if not, write to the Free Software Foundation, Inc., #include #include +#include #define T8_FOREST_VTK_QUADRATIC_ELEMENT_MAX_CORNERS 20 /** 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 @@ -81,15 +84,8 @@ const double t8_forest_vtk_point_to_element_ref_coords[T8_ECLASS_COUNT][T8_FORES * \param[in] curved_flag * \return the number of nodes of this element */ -static int -t8_get_number_of_vtk_nodes (const t8_element_shape_t eclass, const int curved_flag) -{ - /* Use the lookup table of the eclasses. */ - if (curved_flag) { - return t8_curved_eclass_num_nodes[eclass]; - } - return t8_eclass_num_vertices[eclass]; -} +int +t8_get_number_of_vtk_nodes (const t8_element_shape_t eclass, const int curved_flag); /** * Get the coordinates of an element to represent a vtk-cell. @@ -101,17 +97,9 @@ t8_get_number_of_vtk_nodes (const t8_element_shape_t eclass, const int curved_fl * \param[in] curved_flag Flag to tell if we use curved or linear cells. * \param[in, out] out_coords An array to fill with the coordinates of the vertex. */ -static void +void t8_forest_vtk_get_element_nodes (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element, const int vertex, - const int curved_flag, double *out_coords) -{ - const t8_eclass_t tree_class = t8_forest_get_tree_class (forest, ltreeid); - const t8_eclass_scheme_c *scheme = t8_forest_get_eclass_scheme (forest, tree_class); - const t8_element_shape_t element_shape = scheme->t8_element_shape (element); - const double *ref_coords = t8_forest_vtk_point_to_element_ref_coords[element_shape][vertex]; - const int num_node = t8_get_number_of_vtk_nodes (element_shape, curved_flag); - t8_forest_element_from_ref_coords (forest, ltreeid, element, ref_coords, num_node, out_coords); -} + const int curved_flag, double *out_coords); /** * Templated getter functions to use one call to get the local number of elements (trees) for a forest(cmesh). @@ -124,20 +112,6 @@ template t8_locidx_t grid_local_num_elements (const grid_t grid); -template <> -t8_locidx_t -grid_local_num_elements (const t8_forest_t grid) -{ - return t8_forest_get_local_num_elements (grid); -} - -template <> -t8_locidx_t -grid_local_num_elements (const t8_cmesh_t grid) -{ - return t8_cmesh_get_num_local_trees (grid); -} - /** * Templated getter functions to use one call to get the local number of trees for a forest(cmesh). * @@ -149,20 +123,6 @@ template t8_locidx_t grid_local_num_trees (const grid_t grid); -template <> -t8_locidx_t -grid_local_num_trees (const t8_forest_t grid) -{ - return t8_forest_get_num_local_trees (grid); -} - -template <> -t8_locidx_t -grid_local_num_trees (const t8_cmesh_t grid) -{ - return t8_cmesh_get_num_local_trees (grid); -} - /** * Templated getter functions to use one call to get the local number of ghost trees for a forest(cmesh). * @@ -174,20 +134,6 @@ template t8_locidx_t grid_local_num_ghost_trees (const grid_t grid); -template <> -t8_locidx_t -grid_local_num_ghost_trees (const t8_forest_t grid) -{ - return t8_forest_get_num_ghost_trees (grid); -} - -template <> -t8_locidx_t -grid_local_num_ghost_trees (const t8_cmesh_t grid) -{ - return t8_cmesh_get_num_ghosts (grid); -} - /** * Templated getter functions to use one call to get the id of the first local element (tree) for a forest(cmesh). * @@ -199,20 +145,6 @@ template t8_gloidx_t grid_first_local_id (const grid_t grid); -template <> -t8_gloidx_t -grid_first_local_id (const t8_forest_t grid) -{ - return t8_forest_get_first_local_element_id (grid); -} - -template <> -t8_gloidx_t -grid_first_local_id (const t8_cmesh_t grid) -{ - return t8_cmesh_get_first_treeid (grid); -} - /** * Templated getter functions to use one call to get the global tree id of a local tree id. * @@ -225,20 +157,6 @@ template t8_gloidx_t tree_local_to_global_id (const grid_t grid, t8_locidx_t itree); -template <> -t8_gloidx_t -tree_local_to_global_id (const t8_forest_t grid, t8_locidx_t ltree) -{ - return t8_forest_global_tree_id (grid, ltree); -} - -template <> -t8_gloidx_t -tree_local_to_global_id (const t8_cmesh_t grid, t8_locidx_t ltree) -{ - return t8_cmesh_get_global_id (grid, ltree); -} - /** * Templated getter functions to check if this proc has to write any ghosts or not. * @@ -252,31 +170,6 @@ template bool grid_do_ghosts (const grid_t grid, const int write_ghosts); -template <> -bool -grid_do_ghosts (const t8_forest_t grid, const int write_ghosts) -{ - bool ghosts = write_ghosts; - if (grid->ghosts == NULL || grid->ghosts->num_ghosts_elements == 0) { - /* Never write ghost elements if there aren't any */ - ghosts = false; - } - T8_ASSERT (grid->ghosts != NULL || !ghosts); - return ghosts; -} - -template <> -bool -grid_do_ghosts (const t8_cmesh_t grid, const int write_ghosts) -{ - bool ghosts = write_ghosts; - if (t8_cmesh_get_num_ghosts (grid) == 0) { - /* Never write ghost elements if there aren't any */ - ghosts = false; - } - return ghosts; -} - /** * Compute the number of cells to write on this process. * @@ -289,20 +182,6 @@ template t8_locidx_t num_cells_to_write (const grid_t grid, const int write_ghosts); -template <> -t8_locidx_t -num_cells_to_write (const t8_forest_t grid, const int write_ghosts) -{ - return grid_local_num_elements (grid) + (write_ghosts ? t8_forest_get_num_ghost_trees (grid) : 0); -} - -template <> -t8_locidx_t -num_cells_to_write (const t8_cmesh_t grid, const int write_ghosts) -{ - return grid_local_num_elements (grid) + (write_ghosts ? t8_cmesh_get_num_ghosts (grid) : 0); -} - /** * Templated function to get the shape of an element for forests or cmeshes. If grid is a cmesh the input for * \a element is ignored. @@ -317,22 +196,6 @@ template t8_element_shape_t grid_element_shape (const grid_t grid, const t8_locidx_t itree, const t8_element_t *element); -template <> -t8_element_shape_t -grid_element_shape (const t8_forest_t grid, const t8_locidx_t itree, const t8_element_t *element) -{ - const t8_eclass_t eclass = t8_forest_get_eclass (grid, itree); - t8_eclass_scheme *scheme = t8_forest_get_eclass_scheme (grid, eclass); - return scheme->t8_element_shape (element); -} - -template <> -t8_element_shape_t -grid_element_shape (const t8_cmesh_t grid, const t8_locidx_t itree, const t8_element_t *element) -{ - return t8_cmesh_get_tree_class (grid, itree); -} - /** * Compute the coordinates of the corners of an element in the grid. If the grid is a forest the input for element is ignored. * @@ -350,26 +213,6 @@ void grid_element_to_coords (const grid_t grid, const t8_locidx_t itree, const t8_element_t *element, const int curved_flag, double *coordinates, const int num_node, const t8_element_shape_t shape); -template <> -void -grid_element_to_coords (const t8_forest_t grid, const t8_locidx_t itree, const t8_element_t *element, - const int curved_flag, double *coordinates, const int num_node, - const t8_element_shape_t shape) -{ - t8_forest_vtk_get_element_nodes (grid, itree, element, 0, curved_flag, coordinates); -} - -template <> -void -grid_element_to_coords (const t8_cmesh_t grid, const t8_locidx_t itree, const t8_element_t *element, - const int curved_flag, double *coordinates, const int num_node, - const t8_element_shape_t shape) -{ - const double *ref_coords = t8_forest_vtk_point_to_element_ref_coords[shape][curved_flag]; - const t8_gloidx_t gtree_id = t8_cmesh_get_global_id (grid, itree); - t8_geometry_evaluate (grid, gtree_id, ref_coords, num_node, coordinates); -} - /** * Get the level of an element/tree. If \a grid is a cmesh we always return 0. * @@ -383,19 +226,4 @@ template int grid_element_level (const grid_t grid, const t8_locidx_t itree, const t8_element_t *element); -template <> -int -grid_element_level (const t8_forest_t grid, const t8_locidx_t itree, const t8_element_t *element) -{ - const t8_eclass_t eclass = t8_forest_get_eclass (grid, itree); - t8_eclass_scheme *scheme = t8_forest_get_eclass_scheme (grid, eclass); - return scheme->t8_element_level (element); -} -template <> -int -grid_element_level (const t8_cmesh_t grid, const t8_locidx_t itree, const t8_element_t *element) -{ - return 0; -} - #endif /* T8_VTK_WRITER_HELPER */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3a77b03211..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 ) + + # 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,80 +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_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/Makefile.am b/test/Makefile.am index 0dc6b221d1..6ee6f4d17a 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -45,6 +45,7 @@ t8code_googletest_programs = \ test/t8_cmesh/t8_gtest_hypercube \ test/t8_schemes/t8_gtest_element_count_leaves \ test/t8_schemes/t8_gtest_element_ref_coords \ + test/t8_geometry/t8_gtest_geometry_triangular_interpolation \ test/t8_geometry/t8_gtest_geometry_handling \ test/t8_schemes/t8_gtest_descendant \ test/t8_schemes/t8_gtest_find_parent \ @@ -177,6 +178,10 @@ test_t8_schemes_t8_gtest_element_ref_coords_SOURCES = \ test/t8_gtest_main.cxx \ test/t8_schemes/t8_gtest_element_ref_coords.cxx +test_t8_geometry_t8_gtest_geometry_triangular_interpolation_SOURCES = \ + test/t8_gtest_main.cxx \ + test/t8_geometry/t8_gtest_geometry_triangular_interpolation.cxx + test_t8_geometry_t8_gtest_geometry_handling_SOURCES = \ test/t8_gtest_main.cxx \ test/t8_geometry/t8_gtest_geometry_handling.cxx @@ -441,6 +446,10 @@ test_t8_schemes_t8_gtest_element_ref_coords_LDADD = $(t8_gtest_target_ld_add) test_t8_schemes_t8_gtest_element_ref_coords_LDFLAGS = $(t8_gtest_target_ld_flags) test_t8_schemes_t8_gtest_element_ref_coords_CPPFLAGS = $(t8_gtest_target_cpp_flags) +test_t8_geometry_t8_gtest_geometry_triangular_interpolation_LDADD = $(t8_gtest_target_ld_add) +test_t8_geometry_t8_gtest_geometry_triangular_interpolation_LDFLAGS = $(t8_gtest_target_ld_flags) +test_t8_geometry_t8_gtest_geometry_triangular_interpolation_CPPFLAGS = $(t8_gtest_target_cpp_flags) + test_t8_geometry_t8_gtest_geometry_handling_LDADD = $(t8_gtest_target_ld_add) test_t8_geometry_t8_gtest_geometry_handling_LDFLAGS = $(t8_gtest_target_ld_flags) test_t8_geometry_t8_gtest_geometry_handling_CPPFLAGS = $(t8_gtest_target_cpp_flags) @@ -642,6 +651,7 @@ test_t8_cmesh_t8_gtest_hypercube_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags) test_t8_cmesh_t8_gtest_cmesh_set_join_by_vertices_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags) test_t8_schemes_t8_gtest_element_count_leaves_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags) test_t8_schemes_t8_gtest_element_ref_coords_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags) +test_t8_geometry_t8_gtest_geometry_triangular_interpolation_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags) test_t8_geometry_t8_gtest_geometry_handling_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags) test_t8_schemes_t8_gtest_descendant_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags) test_t8_schemes_t8_gtest_find_parent_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags) 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_IO/t8_gtest_vtk_reader.cxx b/test/t8_IO/t8_gtest_vtk_reader.cxx index 51c992e9e1..3df4b8dfdc 100644 --- a/test/t8_IO/t8_gtest_vtk_reader.cxx +++ b/test/t8_IO/t8_gtest_vtk_reader.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ #include diff --git a/test/t8_IO/t8_gtest_vtk_writer.cxx b/test/t8_IO/t8_gtest_vtk_writer.cxx index 802206aed3..81fb56630f 100644 --- a/test/t8_IO/t8_gtest_vtk_writer.cxx +++ b/test/t8_IO/t8_gtest_vtk_writer.cxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #include @@ -26,6 +26,8 @@ along with t8code; if not, write to the Free Software Foundation, Inc., #include #include +#include + /** * Create a hybrid forest or a cmesh * @@ -75,6 +77,42 @@ destroy_grid (t8_forest_t *forest) t8_forest_unref (forest); } +template +static int +use_c_interface (const grid_t grid, const char *fileprefix, const int write_treeid, const int write_mpirank, + const int write_level, const int write_element_id, const int curved_flag, const int write_ghosts, + const int num_data, t8_vtk_data_field_t *data, sc_MPI_Comm comm); + +template <> +int +use_c_interface (const t8_forest_t grid, const char *fileprefix, const int write_treeid, + const int write_mpirank, const int write_level, const int write_element_id, + const int curved_flag, const int write_ghosts, const int num_data, + t8_vtk_data_field_t *data, sc_MPI_Comm comm) +{ +#if T8_WITH_VTK + return t8_forest_vtk_write_file_via_API (grid, fileprefix, write_treeid, write_mpirank, write_level, write_element_id, + curved_flag, write_ghosts, num_data, data); +#else + return t8_forest_vtk_write_file (grid, fileprefix, write_treeid, write_mpirank, write_level, write_element_id, + write_ghosts, num_data, data); +#endif +} + +template <> +int +use_c_interface (const t8_cmesh_t grid, const char *fileprefix, const int write_treeid, + const int write_mpirank, const int write_level, const int write_element_id, + const int curved_flag, const int write_ghosts, const int num_data, + t8_vtk_data_field_t *data, sc_MPI_Comm comm) +{ +#if T8_WITH_VTK + return t8_cmesh_vtk_write_file_via_API (grid, fileprefix, comm); +#else + return t8_cmesh_vtk_write_file (grid, fileprefix); +#endif +} + /** * Templated class to test the vtk writer for forests and cmeshes. * @@ -91,6 +129,12 @@ class vtk_writer_test: public testing::Test { sc_MPI_COMM_WORLD); } + int + grid_c_interface () + { + return use_c_interface (grid, "test_vtk_c_interface", 1, 1, 1, 1, 1, 1, 0, NULL, sc_MPI_COMM_WORLD); + } + void TearDown () override { @@ -109,16 +153,19 @@ TYPED_TEST_SUITE_P (vtk_writer_test); */ TYPED_TEST_P (vtk_writer_test, write_vtk) { - int success = this->writer->write (this->grid); - #if T8_WITH_VTK - EXPECT_TRUE (success); + EXPECT_TRUE (this->writer->write_with_API (this->grid)); #else - EXPECT_FALSE (success); + EXPECT_TRUE (this->writer->write_ASCII (this->grid)); #endif } -REGISTER_TYPED_TEST_SUITE_P (vtk_writer_test, write_vtk); +TYPED_TEST_P (vtk_writer_test, c_interface) +{ + EXPECT_TRUE (this->grid_c_interface ()); +} + +REGISTER_TYPED_TEST_SUITE_P (vtk_writer_test, write_vtk, c_interface); using GridTypes = ::testing::Types; diff --git a/test/t8_cmesh/t8_gtest_bcast.cxx b/test/t8_cmesh/t8_gtest_bcast.cxx index 4d9e05bc1b..4fbe66083e 100644 --- a/test/t8_cmesh/t8_gtest_bcast.cxx +++ b/test/t8_cmesh/t8_gtest_bcast.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 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_cmesh_tree_vertices_negative_volume.cxx b/test/t8_cmesh/t8_gtest_cmesh_tree_vertices_negative_volume.cxx index af0e714bfd..810f1847a0 100644 --- a/test/t8_cmesh/t8_gtest_cmesh_tree_vertices_negative_volume.cxx +++ b/test/t8_cmesh/t8_gtest_cmesh_tree_vertices_negative_volume.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2023 the developers + Copyright (C) 2023 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 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. + 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. + 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. */ /** \file t8_gtest_cmesh_tree_vertices_negative_volume.cxx 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_example_sets.hxx b/test/t8_cmesh_generator/t8_cmesh_example_sets.hxx index 769151c55e..0bdf5addaa 100644 --- a/test/t8_cmesh_generator/t8_cmesh_example_sets.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_example_sets.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_GTEST_CMESH_COMM_CREATOR_HXX diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_bigmesh_param.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_bigmesh_param.hxx index 848b12090b..9af128eee5 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_bigmesh_param.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_bigmesh_param.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_CMESH_NEW_BIGMESH_PARAM_HXX diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_comm.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_comm.hxx index d0da2f6160..3ad941b589 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_comm.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_comm.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_CMESH_NEW_COMM diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_disjoint_bricks_param.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_disjoint_bricks_param.hxx index 3e3c85b254..0d4658dfeb 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_disjoint_bricks_param.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_disjoint_bricks_param.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx" diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_empty.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_empty.hxx index 4f0974a429..1d0eb1e796 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_empty.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_empty.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_CMESH_NEW_EMPTY_HXX diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_from_class_param.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_from_class_param.hxx index 640200feae..cf24526e83 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_from_class_param.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_from_class_param.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx" diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_pad.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_pad.hxx index 7806f1d526..19b57fcfe6 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_pad.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_pad.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_CMESH_NEW_HYPERCUBE_PAD 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 b2e0ff85fd..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 @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef 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_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_periodic.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_periodic.hxx index 0e1b0f4bc6..854db24ad8 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_periodic.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_periodic.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_CMESH_NEW_PERIODIC_HXX diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_prism_cake_param.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_prism_cake_param.hxx index c9521aeeb1..a63909f7ac 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_prism_cake_param.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_prism_cake_param.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx" diff --git a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx index 0c86bba505..53c42de2a5 100644 --- a/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx +++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ /** diff --git a/test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx b/test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx index cec3c617da..1a4538e97d 100644 --- a/test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx +++ b/test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_GTEST_CMESH_CREATOR_BASE_HXX diff --git a/test/t8_cmesh_generator/t8_gtest_cmesh_generator_test.cxx b/test/t8_cmesh_generator/t8_gtest_cmesh_generator_test.cxx index 0130f7ad11..5056787115 100644 --- a/test/t8_cmesh_generator/t8_gtest_cmesh_generator_test.cxx +++ b/test/t8_cmesh_generator/t8_gtest_cmesh_generator_test.cxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #include diff --git a/test/t8_cmesh_generator/t8_gtest_cmesh_sum_of_sets.hxx b/test/t8_cmesh_generator/t8_gtest_cmesh_sum_of_sets.hxx index 49cafa2635..ad0bd9e2db 100644 --- a/test/t8_cmesh_generator/t8_gtest_cmesh_sum_of_sets.hxx +++ b/test/t8_cmesh_generator/t8_gtest_cmesh_sum_of_sets.hxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ #ifndef T8_GTEST_cmesh_sum_of_sets_HXX diff --git a/test/t8_forest/t8_gtest_balance.cxx b/test/t8_forest/t8_gtest_balance.cxx index 2fc7857f97..3d4e3062ba 100644 --- a/test/t8_forest/t8_gtest_balance.cxx +++ b/test/t8_forest/t8_gtest_balance.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ /** \file t8_gtest_balance.cxx diff --git a/test/t8_forest/t8_gtest_element_volume.cxx b/test/t8_forest/t8_gtest_element_volume.cxx index f0c20099d3..a44c990fe1 100644 --- a/test/t8_forest/t8_gtest_element_volume.cxx +++ b/test/t8_forest/t8_gtest_element_volume.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ #include @@ -33,7 +33,6 @@ along with t8code; if not, write to the Free Software Foundation, Inc., /** * 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_forest/t8_gtest_forest_face_normal.cxx b/test/t8_forest/t8_gtest_forest_face_normal.cxx index 83ed348087..659aa53ea9 100644 --- a/test/t8_forest/t8_gtest_forest_face_normal.cxx +++ b/test/t8_forest/t8_gtest_forest_face_normal.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2023 the developers + Copyright (C) 2023 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 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. + 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. + 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. */ #include diff --git a/test/t8_forest/t8_gtest_search.cxx b/test/t8_forest/t8_gtest_search.cxx index 175917e3a8..a4a9bb2712 100644 --- a/test/t8_forest/t8_gtest_search.cxx +++ b/test/t8_forest/t8_gtest_search.cxx @@ -62,11 +62,8 @@ class forest_search: public testing::TestWithParam> { */ static int t8_test_search_all_fn (t8_forest_t forest, const t8_locidx_t ltreeid, const t8_element_t *element, const int is_leaf, - const t8_element_array_t *leaf_elements, const t8_locidx_t tree_leaf_index, void *queries, - sc_array_t *query_indices, int *query_matches, const size_t num_active_queries) + const t8_element_array_t *leaf_elements, const t8_locidx_t tree_leaf_index) { - EXPECT_TRUE (queries == NULL) << "Search callback must not be called with query argument."; - sc_array_t *matched_leaves = (sc_array_t *) t8_forest_get_user_data (forest); if (is_leaf) { t8_locidx_t tree_offset; @@ -88,15 +85,16 @@ t8_test_search_all_fn (t8_forest_t forest, const t8_locidx_t ltreeid, const t8_e return 1; } -static int +static void t8_test_search_query_all_fn (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element, const int is_leaf, - const t8_element_array_t *leaf_elements, const t8_locidx_t tree_leaf_index, void *queries, - sc_array_t *query_indices, int *query_matches, const size_t num_active_queries) + const t8_element_array_t *leaf_elements, const t8_locidx_t tree_leaf_index, + sc_array_t *queries, sc_array_t *query_indices, int *query_matches, + const size_t num_active_queries) { EXPECT_TRUE (queries != NULL) << "query callback must be called with queries argument. "; EXPECT_EQ (num_active_queries, (long unsigned int) 1) << "Wrong number of active queries passed to query callback."; for (size_t iquery = 0; iquery < num_active_queries; iquery++) { - void *query = sc_array_index_int ((sc_array_t *) queries, iquery); + void *query = sc_array_index_int (queries, iquery); /* The query callback is always called with a query */ EXPECT_TRUE (query != NULL) << "query " << iquery << " is NULL."; /* The query is an int with value 42 (see below) */ @@ -115,7 +113,6 @@ t8_test_search_query_all_fn (t8_forest_t forest, t8_locidx_t ltreeid, const t8_e } query_matches[iquery] = 1; } - return 1; } TEST_P (forest_search, test_search_one_query_matches_all) 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 d420e61048..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 @@ -30,7 +30,8 @@ #include #include #include -#include +#include + #include #include #include @@ -48,7 +49,7 @@ #include #include #include -#include + #include #endif @@ -216,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); } @@ -231,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); @@ -423,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); } @@ -438,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); @@ -670,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); @@ -790,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); @@ -857,7 +858,7 @@ class class_2d_element_curved_cad_surface: public testing::TestWithParam (cmesh, 2, shape); + t8_cmesh_register_geometry (cmesh, shape); } void @@ -964,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); } @@ -979,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 121a599bc9..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 @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ /** \file t8_gtest_geometry_lagrange.cxx @@ -35,8 +35,8 @@ along with t8code; if not, write to the Free Software Foundation, Inc., #include #include #include -#include -#include +#include +#include #include #include #include @@ -249,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 ae9998990f..55028a7160 100644 --- a/test/t8_geometry/t8_gtest_geometry_handling.cxx +++ b/test/t8_geometry/t8_gtest_geometry_handling.cxx @@ -54,23 +54,21 @@ 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 ()); + 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 ()); /* Check that we can find the geometries by name. */ for (auto geom : geometries) { @@ -81,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. */ @@ -95,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. */ @@ -118,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); @@ -136,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. */ @@ -147,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); @@ -161,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_geometry_triangular_interpolation.cxx b/test/t8_geometry/t8_gtest_geometry_triangular_interpolation.cxx new file mode 100644 index 0000000000..d549c8ff0a --- /dev/null +++ b/test/t8_geometry/t8_gtest_geometry_triangular_interpolation.cxx @@ -0,0 +1,136 @@ +/* + 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. +*/ + +#include +#include +#include +#include +#include + +/* In this file we test the functionality of t8_geom_triangular_interpolation. + * The function maps reference coordinates inside the reference triangle or tetrahedron + * to the coordinate space of a triagle or tetrahedron given by its corner coordinates. + * We currently check that the reference coordinates of the corners are mapped correctly + * to the corners of the interpolated triangle/tet. */ + +/* TODO: + * - Check corner_value_dim > 1 + * - Check different coefficient coordinates (for example midpoint) + * - Check different corner values + * - The 2d and 3d example contain a lot of nearly duplicate code. + * Can we simplify? + */ + +/* Check that the corner interpolation coordinates are + * mapped to the corners of a triangle. */ +TEST (triangular_interpolation, corners_map_to_corners_2d) +{ + const double coeff_A[2] = { 0, 0 }; + const double coeff_B[2] = { 0, 1 }; + const double coeff_C[2] = { 1, 1 }; + + const double corner_values_2d[] = { + 1, 2, // corner A + 3, 4, // corner B + 5, 6 // corner C + }; + + const double *cornerA = corner_values_2d; + const double *cornerB = corner_values_2d + 2; + const double *cornerC = corner_values_2d + 4; + + const double dimension = 2; + + double result[2]; + + // Check corner A + // 2D + t8_geom_triangular_interpolation (coeff_A, corner_values_2d, 2, dimension, result); + EXPECT_NEAR (cornerA[0], result[0], T8_PRECISION_EPS); + EXPECT_NEAR (cornerA[1], result[1], T8_PRECISION_EPS); + + // Check corner B + // 2D + t8_geom_triangular_interpolation (coeff_B, corner_values_2d, 2, dimension, result); + EXPECT_NEAR (cornerB[0], result[0], T8_PRECISION_EPS); + EXPECT_NEAR (cornerB[1], result[1], T8_PRECISION_EPS); + + // Check corner C + // 2D + t8_geom_triangular_interpolation (coeff_C, corner_values_2d, 2, dimension, result); + EXPECT_NEAR (cornerC[0], result[0], T8_PRECISION_EPS); + EXPECT_NEAR (cornerC[1], result[1], T8_PRECISION_EPS); +} + +/* Check that the corner interpolation coordinates are + * mapped to the corners of a tetrahedron. */ +TEST (triangular_interpolation, corners_map_to_corners_3d) +{ + const double coeff_A[3] = { 0, 0, 0 }; + const double coeff_B[3] = { 0, 1, 0 }; + const double coeff_C[3] = { 1, 1, 0 }; + const double coeff_D[3] = { 1, 1, 1 }; + + const double corner_values_3d[] = { + 1, 2, 3, // corner A + 4, 5, 6, // corner B + 7, 8, 9, // corner C + 10, 11, 12, // corner D + }; + + const double *cornerA = corner_values_3d; + const double *cornerB = corner_values_3d + 3; + const double *cornerC = corner_values_3d + 6; + const double *cornerD = corner_values_3d + 9; + + const double dimension = 3; + + double result[3]; + + // Check corner A + // 3D + t8_geom_triangular_interpolation (coeff_A, corner_values_3d, 3, dimension, result); + EXPECT_NEAR (cornerA[0], result[0], T8_PRECISION_EPS); + EXPECT_NEAR (cornerA[1], result[1], T8_PRECISION_EPS); + EXPECT_NEAR (cornerA[2], result[2], T8_PRECISION_EPS); + + // Check corner B + // 3D + t8_geom_triangular_interpolation (coeff_B, corner_values_3d, 3, dimension, result); + EXPECT_NEAR (cornerB[0], result[0], T8_PRECISION_EPS); + EXPECT_NEAR (cornerB[1], result[1], T8_PRECISION_EPS); + EXPECT_NEAR (cornerB[2], result[2], T8_PRECISION_EPS); + + // Check corner C + // 3D + t8_geom_triangular_interpolation (coeff_C, corner_values_3d, 3, dimension, result); + EXPECT_NEAR (cornerC[0], result[0], T8_PRECISION_EPS); + EXPECT_NEAR (cornerC[1], result[1], T8_PRECISION_EPS); + EXPECT_NEAR (cornerC[2], result[2], T8_PRECISION_EPS); + + // Check corner D + // 3D + t8_geom_triangular_interpolation (coeff_D, corner_values_3d, 3, dimension, result); + EXPECT_NEAR (cornerD[0], result[0], T8_PRECISION_EPS); + EXPECT_NEAR (cornerD[1], result[1], T8_PRECISION_EPS); + EXPECT_NEAR (cornerD[2], result[2], T8_PRECISION_EPS); +} diff --git a/test/t8_geometry/t8_gtest_point_inside.cxx b/test/t8_geometry/t8_gtest_point_inside.cxx index c312c10a64..c12f634ac2 100644 --- a/test/t8_geometry/t8_gtest_point_inside.cxx +++ b/test/t8_geometry/t8_gtest_point_inside.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 @@ -34,7 +33,6 @@ #include #include #include -#include /* In this test we define a triangle in the x-y plane * and a point that lies in a triangle that is parallel @@ -58,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); @@ -99,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/test/t8_gtest_basics.cxx b/test/t8_gtest_basics.cxx index d8633dc3a9..5732d11461 100644 --- a/test/t8_gtest_basics.cxx +++ b/test/t8_gtest_basics.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_gtest_custom_assertion.hxx b/test/t8_gtest_custom_assertion.hxx index 2341393781..e5cb271576 100644 --- a/test/t8_gtest_custom_assertion.hxx +++ b/test/t8_gtest_custom_assertion.hxx @@ -1,23 +1,23 @@ /* -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. + 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) 2023 the developers + Copyright (C) 2023 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 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. + 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. + 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. */ /** \file t8_gtest_custom_assertion.cxx diff --git a/test/t8_gtest_eclass.cxx b/test/t8_gtest_eclass.cxx index deda7e12c8..4abe116e66 100644 --- a/test/t8_gtest_eclass.cxx +++ b/test/t8_gtest_eclass.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_gtest_macros.hxx b/test/t8_gtest_macros.hxx index 983f7a8e70..b3cdb559e2 100644 --- a/test/t8_gtest_macros.hxx +++ b/test/t8_gtest_macros.hxx @@ -1,23 +1,23 @@ /* -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. + 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) 2023 the developers + Copyright (C) 2023 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 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. + 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. + 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. */ /** \file t8_gtest_macros.hxx diff --git a/test/t8_gtest_refcount.cxx b/test/t8_gtest_refcount.cxx index c58721272b..09ef36559d 100644 --- a/test/t8_gtest_refcount.cxx +++ b/test/t8_gtest_refcount.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_gtest_vec.cxx b/test/t8_gtest_vec.cxx index 395f82f838..efe41a258f 100644 --- a/test/t8_gtest_vec.cxx +++ b/test/t8_gtest_vec.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_gtest_version.cxx b/test/t8_gtest_version.cxx index 56a1a56dfb..12dd6446f4 100644 --- a/test/t8_gtest_version.cxx +++ b/test/t8_gtest_version.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_schemes/t8_gtest_ancestor.cxx b/test/t8_schemes/t8_gtest_ancestor.cxx index b067e85be8..05ca3df634 100644 --- a/test/t8_schemes/t8_gtest_ancestor.cxx +++ b/test/t8_schemes/t8_gtest_ancestor.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ /** \file t8_gtest_nca.cxx diff --git a/test/t8_schemes/t8_gtest_default.cxx b/test/t8_schemes/t8_gtest_default.cxx index ea361ac571..aab7410d43 100644 --- a/test/t8_schemes/t8_gtest_default.cxx +++ b/test/t8_schemes/t8_gtest_default.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2023 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_schemes/t8_gtest_descendant.cxx b/test/t8_schemes/t8_gtest_descendant.cxx index 625454d58d..2461ec138a 100644 --- a/test/t8_schemes/t8_gtest_descendant.cxx +++ b/test/t8_schemes/t8_gtest_descendant.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_schemes/t8_gtest_element_ref_coords.cxx b/test/t8_schemes/t8_gtest_element_ref_coords.cxx index 325a946ab7..fa7e6ed0b9 100644 --- a/test/t8_schemes/t8_gtest_element_ref_coords.cxx +++ b/test/t8_schemes/t8_gtest_element_ref_coords.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ /** \file t8_gtest_element_ref_coords.cxx diff --git a/test/t8_schemes/t8_gtest_face_descendant.cxx b/test/t8_schemes/t8_gtest_face_descendant.cxx index 376f9d32aa..6d12e21b5b 100644 --- a/test/t8_schemes/t8_gtest_face_descendant.cxx +++ b/test/t8_schemes/t8_gtest_face_descendant.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_schemes/t8_gtest_init_linear_id.cxx b/test/t8_schemes/t8_gtest_init_linear_id.cxx index 253c850c56..7e2e6c419b 100644 --- a/test/t8_schemes/t8_gtest_init_linear_id.cxx +++ b/test/t8_schemes/t8_gtest_init_linear_id.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ #include diff --git a/test/t8_schemes/t8_gtest_nca.cxx b/test/t8_schemes/t8_gtest_nca.cxx index 5498e63f38..e78a07ece0 100644 --- a/test/t8_schemes/t8_gtest_nca.cxx +++ b/test/t8_schemes/t8_gtest_nca.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ /** \file t8_gtest_nca.cxx diff --git a/test/t8_schemes/t8_gtest_pyra_connectivity.cxx b/test/t8_schemes/t8_gtest_pyra_connectivity.cxx index 399f15d9ec..4bc0ed6c06 100644 --- a/test/t8_schemes/t8_gtest_pyra_connectivity.cxx +++ b/test/t8_schemes/t8_gtest_pyra_connectivity.cxx @@ -1,23 +1,23 @@ /* -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. + 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) 2015 the developers + 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 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. + 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. + 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. */ /** t8_test_pyra_connectivity.cxx diff --git a/test/t8_schemes/t8_gtest_root.cxx b/test/t8_schemes/t8_gtest_root.cxx index 5c92f313f5..63d546c6b4 100644 --- a/test/t8_schemes/t8_gtest_root.cxx +++ b/test/t8_schemes/t8_gtest_root.cxx @@ -1,23 +1,23 @@ /* -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. + 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 + 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 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. + 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. + 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. */ /** \file t8_gtest_root.cxx diff --git a/test/t8_schemes/t8_gtest_scheme_consistency.cxx b/test/t8_schemes/t8_gtest_scheme_consistency.cxx index f42f2373f3..4882e6429d 100644 --- a/test/t8_schemes/t8_gtest_scheme_consistency.cxx +++ b/test/t8_schemes/t8_gtest_scheme_consistency.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 diff --git a/test/t8_schemes/t8_gtest_successor.cxx b/test/t8_schemes/t8_gtest_successor.cxx index 31e4e07d8d..2b7a465a48 100644 --- a/test/t8_schemes/t8_gtest_successor.cxx +++ b/test/t8_schemes/t8_gtest_successor.cxx @@ -1,10 +1,9 @@ /* 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. + connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2010 The University of Texas System - Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac + 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 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 c48fe36acd..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. @@ -37,7 +37,7 @@ #include /* General t8code header, always include this. */ #include /* cmesh definition and basic interface. */ -#include /* cmesh-writer interface. */ +#include /* cmesh-writer interface. */ #include /* A collection of exemplary cmeshes */ /* Builds cmesh of 6 tetrahedra that build up a unit cube. 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 d6606f0a3c..122636fc49 100644 --- a/tutorials/general/t8_tutorial_build_cmesh.cxx +++ b/tutorials/general/t8_tutorial_build_cmesh.cxx @@ -41,7 +41,7 @@ #include /* cmesh definition and basic interface. */ #include /* forest definition and basic interface. */ #include /* default refinement scheme. */ -#include /* write file in vtu file */ +#include /* write file in vtu file */ #include /* linear geometry of the cmesh */ T8_EXTERN_C_BEGIN (); @@ -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 aea51588b0..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. @@ -148,10 +148,8 @@ typedef struct static int t8_tutorial_search_callback (t8_forest_t forest, const t8_locidx_t ltreeid, const t8_element_t *element, const int is_leaf, const t8_element_array_t *leaf_elements, - const t8_locidx_t tree_leaf_index, void *query, sc_array_t *query_indices, - int *query_matches, const size_t num_active_queries) + const t8_locidx_t tree_leaf_index) { - T8_ASSERT (query == NULL); /* Get a pointer to our user data and increase the counter of searched elements. */ t8_tutorial_search_user_data_t *user_data = (t8_tutorial_search_user_data_t *) t8_forest_get_user_data (forest); @@ -171,10 +169,10 @@ t8_tutorial_search_callback (t8_forest_t forest, const t8_locidx_t ltreeid, cons * a counter for this element by one. * These counters are provided in an sc_array as user data of the input forest. */ -static int +static void t8_tutorial_search_query_callback (t8_forest_t forest, const t8_locidx_t ltreeid, const t8_element_t *element, const int is_leaf, const t8_element_array_t *leaf_elements, - const t8_locidx_t tree_leaf_index, void *query, sc_array_t *query_indices, + const t8_locidx_t tree_leaf_index, sc_array_t *queries, sc_array_t *query_indices, int *query_matches, const size_t num_active_queries) { /* Build an array of all particle-coords, necessary for t8_forest_element_point_batch_inside */ @@ -184,7 +182,7 @@ t8_tutorial_search_query_callback (t8_forest_t forest, const t8_locidx_t ltreeid const size_t particle_id = *(size_t *) sc_array_index_int (query_indices, particle_iter); /* Cast the query into a particle*/ t8_tutorial_search_particle_t *particle - = (t8_tutorial_search_particle_t *) sc_array_index ((sc_array_t *) query, particle_id); + = (t8_tutorial_search_particle_t *) sc_array_index ((sc_array_t *) queries, particle_id); /* extract the coordinates of the particle struct */ coords[3 * particle_iter] = particle->coordinates[0]; coords[3 * particle_iter + 1] = particle->coordinates[1]; @@ -200,7 +198,7 @@ t8_tutorial_search_query_callback (t8_forest_t forest, const t8_locidx_t ltreeid sc_array *particles_per_element = user_data->particles_per_element; /* Ensure that the data is actually set. */ T8_ASSERT (particles_per_element != NULL); - T8_ASSERT (query != NULL); + T8_ASSERT (queries != NULL); /* Test whether the particles are inside this element. */ t8_forest_element_points_inside (forest, ltreeid, element, coords, num_active_queries, query_matches, tolerance); @@ -218,13 +216,12 @@ t8_tutorial_search_query_callback (t8_forest_t forest, const t8_locidx_t ltreeid /* Get the correct particle_id */ size_t particle_id = *(size_t *) sc_array_index_int (query_indices, matches_id); t8_tutorial_search_particle_t *particle - = (t8_tutorial_search_particle_t *) sc_array_index ((sc_array_t *) query, particle_id); + = (t8_tutorial_search_particle_t *) sc_array_index ((sc_array_t *) queries, particle_id); particle->is_inside_partition = 1; *(double *) t8_sc_array_index_locidx (particles_per_element, element_index) += 1; } } } - return 0; } /* Write the forest to vtu files and also write the particles_per_element