diff --git a/.github/workflows/add_release_documentation.yml b/.github/workflows/add_release_documentation.yml
index 54113f8eab..5ac4235eb2 100644
--- a/.github/workflows/add_release_documentation.yml
+++ b/.github/workflows/add_release_documentation.yml
@@ -119,19 +119,27 @@ jobs:
if: ${{ env.MINOR_RELEASE == 'true' }}
run: |
cd t8code-website/content
+ # Generate new folder for the newest documentation and copy documentation
mkdir -p doc/$GITHUB_REF_NAME
cp -r ../../t8code/build_debug/doc/html/* doc/$GITHUB_REF_NAME/
+ # Add a link to the newest documentation in the documentation webpage
cd pages
today=`date +'%Y-%m-%d %H:%M'`
sed -i s/"^Date:.*"/"Date: $today"/g 4_Documentation.md
- csplit -z 4_Documentation.md /"t8code dev"/+1
+ # Split documentation webpage after t8code latest and append newest documentation
+ csplit -z 4_Documentation.md /"t8code latest"/+1
mv xx00 4_Documentation.md
echo " - [t8code $GITHUB_REF_NAME](../doc/$GITHUB_REF_NAME/index.html)" >> 4_Documentation.md
cat xx01 >> 4_Documentation.md
rm xx01
+ # Refresh redirect to t8code latest
+ cd ../doc
+ echo '' > latest.html
+ # Refresh redirections for complete latest documentation
+ ./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@v5
+ uses: peter-evans/create-pull-request@v6
with:
path: t8code-website
title: Add documentation for t8code ${{ github.ref_name }}
diff --git a/.github/workflows/tests_t8code_linkage_parallel_debug.yml b/.github/workflows/tests_t8code_linkage_parallel_debug.yml
index fae6d3602b..cef908feae 100644
--- a/.github/workflows/tests_t8code_linkage_parallel_debug.yml
+++ b/.github/workflows/tests_t8code_linkage_parallel_debug.yml
@@ -205,25 +205,25 @@ jobs:
- name: check OpenCASCADE
run: echo "Checking OpenCASCADE with MPI in debugging mode"
- name: configure MPI OpenCASCADE debug
- run: mkdir build_occ && cd build_occ && ../configure $CONFIG_DEBUG --with-occ CFLAGS="$CFLAGS_var -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -I/usr/include/opencascade"
+ run: mkdir build_cad && cd build_cad && ../configure $CONFIG_DEBUG --with-occ CFLAGS="$CFLAGS_var -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -I/usr/include/opencascade"
- name: OnFailUploadLog
if: failure()
uses: actions/upload-artifact@v4
with:
- name: config_occ_debug_MPI.log
- path: build_occ/config.log
+ name: config_cad_debug_MPI.log
+ path: build_cad/config.log
- name: make
- run: cd build_occ && make $MAKEFLAGS CFLAGS="$CFLAGS_var -Werror -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -Werror -I/usr/include/opencascade"
+ run: cd build_cad && make $MAKEFLAGS CFLAGS="$CFLAGS_var -Werror -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -Werror -I/usr/include/opencascade"
- name: make install
- run: cd build_occ && make install $MAKEFLAGS
+ run: cd build_cad && make install $MAKEFLAGS
- name: make check
- run: cd build_occ && make check $MAKEFLAGS CFLAGS="$CFLAGS_var -Werror -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -Werror -I/usr/include/opencascade"
+ run: cd build_cad && make check $MAKEFLAGS CFLAGS="$CFLAGS_var -Werror -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -Werror -I/usr/include/opencascade"
- name: OnFailUploadLog
if: failure()
uses: actions/upload-artifact@v4
with:
- name: test-suite_occ.log
- path: build_occ/test-suite.log
+ name: test-suite_cad.log
+ path: build_cad/test-suite.log
# configure and test with MPI and VTK (debug mode)
- name: check VTK
run: echo "Checking VTK with MPI in debugging mode"
diff --git a/.github/workflows/tests_t8code_linkage_parallel_release.yml b/.github/workflows/tests_t8code_linkage_parallel_release.yml
index 90ec479fdf..fc16d7486a 100644
--- a/.github/workflows/tests_t8code_linkage_parallel_release.yml
+++ b/.github/workflows/tests_t8code_linkage_parallel_release.yml
@@ -205,25 +205,25 @@ jobs:
- name: check OpenCASCADE
run: echo "Checking OpenCASCADE with MPI in release mode"
- name: configure MPI OpenCASCADE release
- run: mkdir build_occ && cd build_occ && ../configure $CONFIG_RELEASE --with-occ CFLAGS="$CFLAGS_var -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -I/usr/include/opencascade"
+ run: mkdir build_cad && cd build_cad && ../configure $CONFIG_RELEASE --with-cad CFLAGS="$CFLAGS_var -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -I/usr/include/opencascade"
- name: OnFailUploadLog
if: failure()
uses: actions/upload-artifact@v4
with:
- name: config_occ_release_MPI.log
- path: build_occ/config.log
+ name: config_cad_release_MPI.log
+ path: build_cad/config.log
- name: make
- run: cd build_occ && make $MAKEFLAGS CFLAGS="$CFLAGS_var -Werror -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -Werror -I/usr/include/opencascade"
+ run: cd build_cad && make $MAKEFLAGS CFLAGS="$CFLAGS_var -Werror -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -Werror -I/usr/include/opencascade"
- name: make install
- run: cd build_occ && make install $MAKEFLAGS
+ run: cd build_cad && make install $MAKEFLAGS
- name: make check
- run: cd build_occ && make check $MAKEFLAGS CFLAGS="$CFLAGS_var -Werror -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -Werror -I/usr/include/opencascade"
+ run: cd build_cad && make check $MAKEFLAGS CFLAGS="$CFLAGS_var -Werror -I/usr/include/opencascade" CXXFLAGS="$CXXFLAGS_var -Werror -I/usr/include/opencascade"
- name: OnFailUploadLog
if: failure()
uses: actions/upload-artifact@v4
with:
- name: test-suite_occ.log
- path: build_occ/test-suite.log
+ name: test-suite_cad.log
+ path: build_cad/test-suite.log
# configure and test with MPI and VTK (release mode)
- name: check VTK
run: echo "Checking VTK with MPI in release mode"
diff --git a/.gitignore b/.gitignore
index e536e16531..ecc0d1ed99 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
sc/
p4est/
build-aux/
+build/
.deps/
.libs/
@@ -87,7 +88,7 @@ test/t8_geometry/t8_test_geometry
test/t8_geometry/t8_test_point_inside
test/t8_gtest_main
test/t8_schemes/t8_test_descendant
-test/t8_schemes/t8_test_element_count_leafs
+test/t8_schemes/t8_test_element_count_leaves
test/t8_schemes/t8_test_find_parent
test/t8_schemes/t8_test_init_linear_id
test/t8_schemes/t8_test_pyra_face_descendant
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000..5e07b82cb8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,68 @@
+cmake_minimum_required( VERSION 3.16 )
+project( T8CODE DESCRIPTION "Parallel algorithms and data structures for tree-based AMR with arbitrary element shapes." LANGUAGES C CXX )
+include( CTest )
+
+
+option( T8CODE_BUILD_AS_SHARED_LIBRARY "Whether t8code should be built as a shared or a static library" ON )
+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_ENABLE_MPI "Enable t8code's features which rely on MPI" ON )
+option( T8CODE_ENABLE_VTK "Enable t8code's features which rely on VTK" OFF )
+
+
+if( NOT CMAKE_BUILD_TYPE )
+ set( CMAKE_BUILD_TYPE "Release" )
+endif()
+
+set( CMAKE_C_STANDARD 11 )
+set( CMAKE_C_STANDARD_REQUIRED ON )
+set( CMAKE_C_EXTENSIONS OFF )
+list( APPEND CMAKE_C_FLAGS "-Wall" )
+
+set( CMAKE_CXX_STANDARD 17 )
+set( CMAKE_CXX_STANDARD_REQUIRED ON )
+set( CMAKE_CXX_EXTENSIONS OFF )
+list( APPEND CMAKE_CXX_FLAGS "-Wall" )
+
+
+if( T8CODE_ENABLE_MPI )
+ find_package( MPI COMPONENTS C REQUIRED )
+ if( NOT MPIEXEC_EXECUTABLE )
+ message( FATAL_ERROR "MPIEXEC was not found" )
+ endif()
+ set( SC_ENABLE_MPI ON )
+ set( mpi ON ) # This is very dirty, we should consider fixing this in the p4est repo
+endif()
+
+if( T8CODE_ENABLE_VTK )
+ find_package( VTK REQUIRED )
+endif()
+
+# Override default for this libsc option
+set( BUILD_SHARED_LIBS ON CACHE BOOL "Build libsc as a shared library" )
+
+# Prevent `libsc` and `p4est` from overwriting the default install prefix.
+set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
+
+# Rpath options necessary for shared library install to work correctly in user projects.
+set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/lib)
+set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH true)
+
+add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/sc )
+add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/p4est )
+add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/src )
+
+if ( T8CODE_BUILD_TESTS )
+ add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/test )
+endif()
+
+if ( T8CODE_BUILD_TUTORIALS )
+ add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/tutorials )
+endif()
+
+if ( T8CODE_BUILD_EXAMPLES )
+ add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/example )
+endif()
\ No newline at end of file
diff --git a/benchmarks/t8_time_set_join_by_vertices.cxx b/benchmarks/t8_time_set_join_by_vertices.cxx
index 96f5a49c5c..09b09f2087 100644
--- a/benchmarks/t8_time_set_join_by_vertices.cxx
+++ b/benchmarks/t8_time_set_join_by_vertices.cxx
@@ -161,7 +161,7 @@ main (int argc, char **argv)
const int dim = 3;
const int main_proc = 0;
const int partition = 0;
- const int use_occ_geometry = 0;
+ const int use_cad_geometry = 0;
t8_cmesh_t cmesh;
@@ -173,7 +173,7 @@ main (int argc, char **argv)
sc_flops_start (&fi);
sc_flops_snap (&fi, &snapshot);
- cmesh = t8_cmesh_from_msh_file (meshfile, partition, sc_MPI_COMM_WORLD, dim, main_proc, use_occ_geometry);
+ cmesh = t8_cmesh_from_msh_file (meshfile, partition, sc_MPI_COMM_WORLD, dim, main_proc, use_cad_geometry);
/* Measure passed time. */
sc_flops_shot (&fi, &snapshot);
diff --git a/benchmarks/time_forest_partition.cxx b/benchmarks/time_forest_partition.cxx
index b1362311bc..3b62cf19d9 100644
--- a/benchmarks/time_forest_partition.cxx
+++ b/benchmarks/time_forest_partition.cxx
@@ -30,7 +30,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -254,7 +254,7 @@ t8_time_forest_cmesh_mshfile (t8_cmesh_t cmesh, const char *vtu_prefix, sc_MPI_C
snprintf (forest_vtu, BUFSIZ, "%s_forest_partition_%03d", vtu_prefix, time_step);
snprintf (cmesh_vtu, BUFSIZ, "%s_cmesh_partition_%03d", vtu_prefix, time_step);
t8_forest_write_vtk (forest_partition, forest_vtu);
- t8_cmesh_vtk_write_file (t8_forest_get_cmesh (forest_partition), cmesh_vtu, 1.0);
+ t8_cmesh_vtk_write_file (t8_forest_get_cmesh (forest_partition), cmesh_vtu);
t8_debugf ("Wrote partitioned forest and cmesh\n");
}
if (cmesh_is_partitioned) {
@@ -288,7 +288,7 @@ t8_time_forest_cmesh_mshfile (t8_cmesh_t cmesh, const char *vtu_prefix, sc_MPI_C
* file and mesh_dim must be specified. */
t8_cmesh_t
t8_time_forest_create_cmesh (const char *msh_file, int mesh_dim, const char *cmesh_file, int num_files,
- sc_MPI_Comm comm, int init_level, int stride, int use_occ)
+ sc_MPI_Comm comm, int init_level, int stride, int use_cad)
{
t8_cmesh_t cmesh;
t8_cmesh_t cmesh_partition;
@@ -297,7 +297,7 @@ t8_time_forest_create_cmesh (const char *msh_file, int mesh_dim, const char *cme
T8_ASSERT (msh_file == NULL || cmesh_file == NULL);
if (msh_file != NULL) {
- if (use_occ) {
+ if (use_cad) {
partition = 0;
t8_global_productionf ("The cmesh is not partitioned due to the usage of the curved mesh option. \n"
"Timing will not be comparable to non-curved meshes. \n");
@@ -306,7 +306,7 @@ t8_time_forest_create_cmesh (const char *msh_file, int mesh_dim, const char *cme
partition = 1;
}
/* Create a cmesh from the given mesh files */
- cmesh = t8_cmesh_from_msh_file ((char *) msh_file, partition, comm, mesh_dim, 0, use_occ);
+ cmesh = t8_cmesh_from_msh_file ((char *) msh_file, partition, comm, mesh_dim, 0, use_cad);
}
else {
T8_ASSERT (cmesh_file != NULL);
@@ -337,9 +337,9 @@ main (int argc, char *argv[])
int mpiret, mpisize;
int first_argc;
int level, level_diff;
- int help = 0, no_vtk, do_ghost, do_balance, use_occ;
+ int help = 0, no_vtk, do_ghost, do_balance, use_cad;
int dim, num_files;
- int test_tet, test_linear_cylinder, test_occ_cylinder;
+ int test_tet, test_linear_cylinder, test_cad_cylinder;
int stride;
int cmesh_level;
double T, delta_t, cfl;
@@ -384,16 +384,16 @@ main (int argc, char *argv[])
"Use a cmesh that tests all tet face-to-face connections."
" If this option is used -o is enabled automatically. Not allowed with -f and -c.");
sc_options_add_switch (opt, 'L', "test-linear-cylinder", &test_linear_cylinder,
- "Use a linear cmesh to compare linear and occ geometry performance."
+ "Use a linear cmesh to compare linear and cad geometry performance."
" If this option is used -o is enabled automatically. Not allowed with -f and -c.");
- sc_options_add_switch (opt, 'O', "test-occ-cylinder", &test_occ_cylinder,
- "Use a occ cmesh to compare linear and occ geometry performance."
+ sc_options_add_switch (opt, 'O', "test-cad-cylinder", &test_cad_cylinder,
+ "Use a cad cmesh to compare linear and cad geometry performance."
" If this option is used -o is enabled automatically. Not allowed with -f and -c.");
sc_options_add_int (opt, 'l', "level", &level, 0, "The initial uniform refinement level of the forest.");
sc_options_add_int (opt, 'r', "rlevel", &level_diff, 1,
"The number of levels that the forest is refined from the initial level.");
sc_options_add_int (opt, '\0', "cmesh-level", &cmesh_level, -1,
- "Starting level of the linear or occ cmesh, default is 0. Only viable with -L or -O.");
+ "Starting level of the linear or cad cmesh, default is 0. Only viable with -L or -O.");
sc_options_add_double (opt, 'x', "xmin", x_min_max, 0, "The minimum x coordinate in the mesh.");
sc_options_add_double (opt, 'X', "xmax", x_min_max + 1, 1, "The maximum x coordinate in the mesh.");
sc_options_add_double (opt, 'T', "time", &T, 1,
@@ -406,20 +406,20 @@ main (int argc, char *argv[])
"Overwrites any other delta_t setting.");
sc_options_add_switch (opt, 'g', "ghost", &do_ghost, "Create ghost elements.");
sc_options_add_switch (opt, 'b', "balance", &do_balance, "Establish a 2:1 balance in the forest.");
- sc_options_add_switch (opt, 'z', "use_occ", &use_occ,
+ sc_options_add_switch (opt, 'z', "use_cad", &use_cad,
"If used, meshes will be curved to original geometries (msh- and brep-files necessary).");
/* parse command line options */
first_argc = sc_options_parse (t8_get_package_id (), SC_LP_DEFAULT, opt, argc, 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_occ_cylinder == 0
+ || (cmeshfileprefix == NULL && mshfileprefix == NULL && test_tet == 0 && test_cad_cylinder == 0
&& test_linear_cylinder == 0)
|| stride <= 0 || (num_files - 1) * stride >= mpisize || cfl < 0 || T <= 0
- || test_tet + test_linear_cylinder + test_occ_cylinder > 1
- || (cmesh_level >= 0 && (!test_linear_cylinder && !test_occ_cylinder))
- || ((mshfileprefix != NULL || cmeshfileprefix != NULL) && (test_linear_cylinder || test_occ_cylinder || test_tet))
- || (mshfileprefix == NULL && use_occ)) {
+ || test_tet + test_linear_cylinder + test_cad_cylinder > 1
+ || (cmesh_level >= 0 && (!test_linear_cylinder && !test_cad_cylinder))
+ || ((mshfileprefix != NULL || cmeshfileprefix != NULL) && (test_linear_cylinder || test_cad_cylinder || test_tet))
+ || (mshfileprefix == NULL && use_cad)) {
sc_options_print_usage (t8_get_package_id (), SC_LP_ERROR, opt, NULL);
return 1;
}
@@ -438,25 +438,25 @@ main (int argc, char *argv[])
}
t8_global_productionf ("Using delta_t = %f\n", delta_t);
if (mshfileprefix != NULL) {
- cmesh = t8_time_forest_create_cmesh (mshfileprefix, dim, NULL, -1, sc_MPI_COMM_WORLD, level, stride, use_occ);
+ cmesh = t8_time_forest_create_cmesh (mshfileprefix, dim, NULL, -1, sc_MPI_COMM_WORLD, level, stride, use_cad);
vtu_prefix = mshfileprefix;
}
else if (test_tet) {
cmesh = t8_cmesh_new_tet_orientation_test (sc_MPI_COMM_WORLD);
vtu_prefix = "test_tet";
}
- else if (test_linear_cylinder || test_occ_cylinder) {
+ else if (test_linear_cylinder || test_cad_cylinder) {
if (cmesh_level < 0) {
cmesh_level = 0;
}
cmesh = t8_cmesh_new_hollow_cylinder (sc_MPI_COMM_WORLD, 4 * sc_intpow (2, cmesh_level),
- sc_intpow (2, cmesh_level), sc_intpow (2, cmesh_level), test_occ_cylinder);
- test_linear_cylinder ? vtu_prefix = "test_linear_cylinder" : vtu_prefix = "test_occ_cylinder";
+ 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 {
T8_ASSERT (cmeshfileprefix != NULL);
cmesh
- = t8_time_forest_create_cmesh (NULL, -1, cmeshfileprefix, num_files, sc_MPI_COMM_WORLD, level, stride, use_occ);
+ = t8_time_forest_create_cmesh (NULL, -1, cmeshfileprefix, num_files, sc_MPI_COMM_WORLD, level, stride, use_cad);
vtu_prefix = cmeshfileprefix;
}
t8_time_forest_cmesh_mshfile (cmesh, vtu_prefix, sc_MPI_COMM_WORLD, level, level + level_diff, no_vtk, x_min_max, T,
diff --git a/benchmarks/time_partition.cxx b/benchmarks/time_partition.cxx
index a071353fbe..df5c8704bf 100644
--- a/benchmarks/time_partition.cxx
+++ b/benchmarks/time_partition.cxx
@@ -132,7 +132,7 @@ t8_time_cmesh_partition_brick (int x, int y, int z, sc_MPI_Comm comm, int no_vtk
mpiret = sc_MPI_Comm_rank (comm, &mpirank);
SC_CHECK_MPI (mpiret);
- t8_cmesh_vtk_write_file (cmesh_partition, "cmesh_box_partition", 1.0);
+ t8_cmesh_vtk_write_file (cmesh_partition, "cmesh_box_partition");
}
/* memory clean-up */
t8_cmesh_destroy (&cmesh_partition);
diff --git a/doc/author_dutka.txt b/doc/author_dutka.txt
new file mode 100644
index 0000000000..f2401f4078
--- /dev/null
+++ b/doc/author_dutka.txt
@@ -0,0 +1 @@
+I place my contributions to t8code under the FreeBSD license. Alexandre Dutka
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
new file mode 100644
index 0000000000..a44b444a33
--- /dev/null
+++ b/example/CMakeLists.txt
@@ -0,0 +1,52 @@
+# Conditionally adding new sources to the main T8 target as in the original BS looked wrong...
+add_library( t8example )
+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 )
+install( TARGETS t8example DESTINATION ${CMAKE_INSTALL_PREFIX}/lib )
+
+function( add_t8_example )
+ set( options "" )
+ set( oneValueArgs "NAME" )
+ set( multiValueArgs "SOURCES" )
+ cmake_parse_arguments( ADD_T8_EXAMPLE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ 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}/.. )
+
+ install( TARGETS ${ADD_T8_EXAMPLE_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/example )
+endfunction()
+
+add_t8_example( NAME t8_advection SOURCES advect/t8_advection.cxx )
+
+add_t8_example( NAME t8_cmesh_partition SOURCES cmesh/t8_cmesh_partition.cxx )
+add_t8_example( NAME t8_cmesh_set_join_by_vertices SOURCES cmesh/t8_cmesh_set_join_by_vertices.cxx )
+add_t8_example( NAME t8_cmesh_geometry_examples SOURCES cmesh/t8_cmesh_geometry_examples.cxx )
+add_t8_example( NAME t8_cmesh_create_partitioned SOURCES cmesh/t8_cmesh_create_partitioned.cxx )
+add_t8_example( NAME t8_cmesh_hypercube_pad SOURCES cmesh/t8_cmesh_hypercube_pad.cxx )
+
+add_t8_example( NAME t8_face_neighbor SOURCES forest/t8_face_neighbor.cxx )
+add_t8_example( NAME t8_test_ghost SOURCES forest/t8_test_ghost.cxx )
+add_t8_example( NAME t8_test_face_iterate SOURCES forest/t8_test_face_iterate.cxx )
+add_t8_example( NAME t8_test_ghost_large_level_diff SOURCES forest/t8_test_ghost_large_level_diff.cxx )
+
+add_t8_example( NAME t8_example_geometries SOURCES geometry/t8_example_geometries.cxx )
+
+add_t8_example( NAME t8_cmesh_load_save SOURCES IO/cmesh/t8_cmesh_load_save.cxx )
+add_t8_example( NAME t8_read_msh_file SOURCES IO/cmesh/gmsh/t8_read_msh_file.cxx )
+add_t8_example( NAME t8_load_and_refine_square_w_hole SOURCES IO/cmesh/gmsh/t8_load_and_refine_square_w_hole.cxx )
+add_t8_example( NAME t8_write_cmesh_netcdf SOURCES IO/cmesh/netcdf/t8_write_cmesh_netcdf.cxx )
+add_t8_example( NAME t8_read_tetgen SOURCES IO/cmesh/tetgen/t8_read_tetgen_file.cxx )
+add_t8_example( NAME t8_time_tetgen SOURCES IO/cmesh/tetgen/t8_time_tetgen_file.cxx )
+add_t8_example( NAME t8_forest_tetgen SOURCES IO/cmesh/tetgen/t8_forest_from_tetgen.cxx )
+add_t8_example( NAME t8_read_triangle SOURCES IO/cmesh/triangle/t8_read_triangle_file.cxx )
+add_t8_example( NAME t8_cmesh_read_from_vtk SOURCES IO/cmesh/vtk/t8_cmesh_read_from_vtk.cxx )
+add_t8_example( NAME t8_netcdf_compilation_status SOURCES IO/forest/netcdf/t8_netcdf_status.c )
+add_t8_example( NAME t8_write_forest_netcdf SOURCES IO/forest/netcdf/t8_write_forest_netcdf.cxx )
+
+add_t8_example( NAME t8_example_spheres SOURCES remove/t8_example_spheres.cxx )
+add_t8_example( NAME t8_example_gauss_blob SOURCES remove/t8_example_gauss_blob.cxx )
+add_t8_example( NAME t8_example_empty_trees SOURCES remove/t8_example_empty_trees.cxx )
+
+add_t8_example( NAME t8_version SOURCES version/t8_version.cxx )
\ No newline at end of file
diff --git a/example/IO/cmesh/gmsh/t8_load_and_refine_square_w_hole.cxx b/example/IO/cmesh/gmsh/t8_load_and_refine_square_w_hole.cxx
index 107c14bfdf..ffe4caa3f4 100644
--- a/example/IO/cmesh/gmsh/t8_load_and_refine_square_w_hole.cxx
+++ b/example/IO/cmesh/gmsh/t8_load_and_refine_square_w_hole.cxx
@@ -27,7 +27,6 @@
#include
#include
-#include
#include
#include
#include
diff --git a/example/IO/cmesh/gmsh/t8_read_msh_file.cxx b/example/IO/cmesh/gmsh/t8_read_msh_file.cxx
index fc5b7d5566..0678e9e3ed 100644
--- a/example/IO/cmesh/gmsh/t8_read_msh_file.cxx
+++ b/example/IO/cmesh/gmsh/t8_read_msh_file.cxx
@@ -40,7 +40,7 @@ t8_read_msh_file_vtk (t8_cmesh_t cmesh, const char *prefix)
SC_CHECK_MPI (mpiret);
snprintf (fileprefix, BUFSIZ, "%s_t8_msh", prefix);
- if (!t8_cmesh_vtk_write_file (cmesh, fileprefix, 1.)) {
+ if (!t8_cmesh_vtk_write_file (cmesh, fileprefix)) {
t8_debugf ("Wrote to file %s\n", fileprefix);
}
else {
diff --git a/example/IO/cmesh/t8_cmesh_load_save.cxx b/example/IO/cmesh/t8_cmesh_load_save.cxx
index 0a949b9e6d..9a5e9ab0db 100644
--- a/example/IO/cmesh/t8_cmesh_load_save.cxx
+++ b/example/IO/cmesh/t8_cmesh_load_save.cxx
@@ -40,14 +40,14 @@ t8_cmesh_load_distribute (const char *fileprefix, int num_files, int no_vtk)
else {
t8_debugf ("Successfully loaded cmesh from %s files\n", fileprefix);
if (!no_vtk) {
- t8_cmesh_vtk_write_file (cmesh, "cmesh_dist_loaded", 1.0);
+ t8_cmesh_vtk_write_file (cmesh, "cmesh_dist_loaded");
}
t8_cmesh_init (&cmesh_partition);
t8_cmesh_set_derive (cmesh_partition, cmesh);
t8_cmesh_set_partition_uniform (cmesh_partition, 0, t8_scheme_new_default_cxx ());
t8_cmesh_commit (cmesh_partition, sc_MPI_COMM_WORLD);
if (!no_vtk) {
- t8_cmesh_vtk_write_file (cmesh_partition, "cmesh_dist_loaded_partition", 1.0);
+ t8_cmesh_vtk_write_file (cmesh_partition, "cmesh_dist_loaded_partition");
}
t8_cmesh_destroy (&cmesh_partition);
}
diff --git a/example/IO/cmesh/tetgen/t8_forest_from_tetgen.cxx b/example/IO/cmesh/tetgen/t8_forest_from_tetgen.cxx
index 2658b72242..d56a7ed4cf 100644
--- a/example/IO/cmesh/tetgen/t8_forest_from_tetgen.cxx
+++ b/example/IO/cmesh/tetgen/t8_forest_from_tetgen.cxx
@@ -45,7 +45,7 @@ t8_cmesh_from_tetgen (const char *prefix, int do_partition)
t8_debugf ("Successfully constructed cmesh from %s files.\n", prefix);
t8_debugf ("cmesh has:\n\t%lli tetrahedra\n", (long long) t8_cmesh_get_num_trees (cmesh));
snprintf (fileprefix, BUFSIZ, "%s_t8_tetgen_%04d", prefix, mpirank);
- if (!t8_cmesh_vtk_write_file (cmesh, fileprefix, 1.)) {
+ if (!t8_cmesh_vtk_write_file (cmesh, fileprefix)) {
t8_debugf ("Wrote to file %s\n", fileprefix);
}
else {
diff --git a/example/IO/cmesh/tetgen/t8_read_tetgen_file.cxx b/example/IO/cmesh/tetgen/t8_read_tetgen_file.cxx
index 2ae0d27cd2..824722f64a 100644
--- a/example/IO/cmesh/tetgen/t8_read_tetgen_file.cxx
+++ b/example/IO/cmesh/tetgen/t8_read_tetgen_file.cxx
@@ -42,7 +42,7 @@ t8_read_tetgen_file_build_cmesh (const char *prefix, int do_dup, int do_partitio
t8_debugf ("Successfully constructed cmesh from %s files.\n", prefix);
t8_debugf ("cmesh has:\n\t%lli tetrahedra\n", (long long) t8_cmesh_get_num_trees (cmesh));
snprintf (fileprefix, BUFSIZ, "%s_t8_tetgen", prefix);
- if (!t8_cmesh_vtk_write_file (cmesh, fileprefix, 1.)) {
+ if (!t8_cmesh_vtk_write_file (cmesh, fileprefix)) {
t8_debugf ("Wrote to file %s\n", fileprefix);
}
else {
@@ -60,7 +60,7 @@ t8_read_tetgen_file_build_cmesh (const char *prefix, int do_dup, int do_partitio
t8_debugf ("Successfully partitioned %s.\n", "cmesh");
t8_debugf ("cmesh has:\n\t%li local tetrahedra\n", (long) t8_cmesh_get_num_local_trees (cmesh_partitioned));
snprintf (fileprefix, BUFSIZ, "%s_t8_tetgen_partitioned", prefix);
- if (!t8_cmesh_vtk_write_file (cmesh_partitioned, fileprefix, 1.)) {
+ if (!t8_cmesh_vtk_write_file (cmesh_partitioned, fileprefix)) {
t8_debugf ("Wrote to file %s\n", fileprefix);
}
else {
diff --git a/example/IO/cmesh/tetgen/t8_time_tetgen_file.cxx b/example/IO/cmesh/tetgen/t8_time_tetgen_file.cxx
index eeb6204b03..4540e706e5 100644
--- a/example/IO/cmesh/tetgen/t8_time_tetgen_file.cxx
+++ b/example/IO/cmesh/tetgen/t8_time_tetgen_file.cxx
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/example/IO/cmesh/triangle/t8_read_triangle_file.cxx b/example/IO/cmesh/triangle/t8_read_triangle_file.cxx
index d413bf99ce..b5ba185158 100644
--- a/example/IO/cmesh/triangle/t8_read_triangle_file.cxx
+++ b/example/IO/cmesh/triangle/t8_read_triangle_file.cxx
@@ -48,7 +48,7 @@ t8_read_triangle_file_build_cmesh (const char *prefix, int do_dup, int do_partit
t8_cmesh_set_partition_uniform (cmesh_part, 1, t8_scheme_new_default_cxx ());
t8_cmesh_commit (cmesh_part, sc_MPI_COMM_WORLD);
snprintf (fileprefix, BUFSIZ, "%s_t8_triangle_partition", prefix);
- if (!t8_cmesh_vtk_write_file (cmesh_part, fileprefix, 1.0)) {
+ if (!t8_cmesh_vtk_write_file (cmesh_part, fileprefix)) {
t8_debugf ("Wrote to file %s\n", fileprefix);
}
t8_cmesh_destroy (&cmesh_part);
@@ -56,7 +56,7 @@ t8_read_triangle_file_build_cmesh (const char *prefix, int do_dup, int do_partit
t8_debugf ("Successfully constructed cmesh from %s files.\n", prefix);
t8_debugf ("cmesh has:\n\t%lli triangles\n", (long long) t8_cmesh_get_num_trees (cmesh));
snprintf (fileprefix, BUFSIZ, "%s_t8_triangle", prefix);
- if (!t8_cmesh_vtk_write_file (cmesh, fileprefix, 1.)) {
+ if (!t8_cmesh_vtk_write_file (cmesh, fileprefix)) {
t8_debugf ("Wrote to file %s\n", fileprefix);
}
else {
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 a328edad3a..392a7829b5 100644
--- a/example/IO/cmesh/vtk/t8_cmesh_read_from_vtk.cxx
+++ b/example/IO/cmesh/vtk/t8_cmesh_read_from_vtk.cxx
@@ -49,7 +49,7 @@ t8_forest_construct_from_vtk (const char *prefix, sc_MPI_Comm comm, const int va
}
char out_file[BUFSIZ];
snprintf (out_file, BUFSIZ - 9, "%s_cmesh_in", out_prefix);
- t8_cmesh_vtk_write_file (cmesh_in, out_file, 1.0);
+ t8_cmesh_vtk_write_file (cmesh_in, out_file);
t8_cmesh_t cmesh;
if (partition) {
@@ -58,7 +58,7 @@ t8_forest_construct_from_vtk (const char *prefix, sc_MPI_Comm comm, const int va
t8_cmesh_set_partition_uniform (cmesh, 0, t8_scheme_new_default_cxx ());
t8_cmesh_commit (cmesh, comm);
snprintf (out_file, BUFSIZ - 16, "%s_cmesh_partition", out_prefix);
- t8_cmesh_vtk_write_file (cmesh, out_file, 1.0);
+ t8_cmesh_vtk_write_file (cmesh, out_file);
}
else {
cmesh = cmesh_in;
diff --git a/example/advect/t8_advection.cxx b/example/advect/t8_advection.cxx
index c6259df6b8..1855ba3386 100644
--- a/example/advect/t8_advection.cxx
+++ b/example/advect/t8_advection.cxx
@@ -834,16 +834,16 @@ t8_advect_problem_partition (t8_advect_problem_t *problem, int measure_time)
}
static t8_cmesh_t
-t8_advect_create_cmesh (sc_MPI_Comm comm, int cube_type, const char *mshfile, int level, int dim, int use_occ_geometry)
+t8_advect_create_cmesh (sc_MPI_Comm comm, int cube_type, const char *mshfile, int level, int dim, int use_cad_geometry)
{
if (mshfile != NULL) {
/* Load from .msh file and partition */
t8_cmesh_t cmesh, cmesh_partition;
T8_ASSERT (mshfile != NULL);
- cmesh = t8_cmesh_from_msh_file (mshfile, 0, comm, dim, 0, use_occ_geometry);
- /* The partitioning of the occ geometry is not yet available */
- if (use_occ_geometry) {
+ cmesh = t8_cmesh_from_msh_file (mshfile, 0, comm, dim, 0, use_cad_geometry);
+ /* The partitioning of the cad geometry is not yet available */
+ if (use_cad_geometry) {
t8_productionf ("cmesh was not partitioned. Partitioning is not yet "
"available with the curved geometry\n");
return cmesh;
@@ -1489,7 +1489,7 @@ main (int argc, char *argv[])
int level, reflevel, dim, cube_type, dummy_op;
int parsed, helpme, no_vtk, vtk_freq, adapt_freq;
int volume_refine;
- int flow_arg, use_occ_geometry;
+ int flow_arg, use_cad_geometry;
double T, cfl, band_width;
t8_levelset_sphere_data_t ls_data;
/* brief help message */
@@ -1546,8 +1546,8 @@ main (int argc, char *argv[])
"and be in ASCII format version 2. -d must be specified.");
sc_options_add_int (opt, 'd', "dim", &dim, -1, "In combination with -f: The dimension of the mesh. 1 <= d <= 3.");
- sc_options_add_switch (opt, 'O', "occ", &use_occ_geometry,
- "In combination with -f: Use the occ geometry, only viable if a "
+ sc_options_add_switch (opt, 'O', "cad", &use_cad_geometry,
+ "In combination with -f: Use the cad geometry, only viable if a "
".brep file of the same name is present.");
sc_options_add_double (opt, 'T', "end-time", &T, 1, "The duration of the simulation. Default: 1");
@@ -1628,10 +1628,10 @@ main (int argc, char *argv[])
ls_data.M[1] = ls_data.M[2] = 0;
}
- cmesh = t8_advect_create_cmesh (sc_MPI_COMM_WORLD, cube_type, mshfile, level, dim, use_occ_geometry);
+ cmesh = t8_advect_create_cmesh (sc_MPI_COMM_WORLD, cube_type, mshfile, level, dim, use_cad_geometry);
u = t8_advect_choose_flow (flow_arg);
if (!no_vtk) {
- t8_cmesh_vtk_write_file (cmesh, "advection_cmesh", 1.0);
+ t8_cmesh_vtk_write_file (cmesh, "advection_cmesh");
}
/* Computation */
t8_advect_solve (cmesh, u, t8_levelset_sphere, &ls_data, level, level + reflevel, T, cfl, sc_MPI_COMM_WORLD,
diff --git a/example/cmesh/t8_cmesh_geometry_examples.cxx b/example/cmesh/t8_cmesh_geometry_examples.cxx
index d2064bcabc..c11b092b81 100644
--- a/example/cmesh/t8_cmesh_geometry_examples.cxx
+++ b/example/cmesh/t8_cmesh_geometry_examples.cxx
@@ -114,7 +114,7 @@ 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, 1.0);
+ t8_cmesh_vtk_write_file (cmesh, prefix_cmesh);
t8_global_productionf ("Wrote %s.\n", prefix_cmesh);
t8_write_forest_to_vtu (forest, prefix_forest);
@@ -124,17 +124,37 @@ main (int argc, char **argv)
}
{
- const char *prefix_cmesh = "t8_triangulated_spherical_surface_cmesh";
- const char *prefix_forest = "t8_triangulated_spherical_surface_forest";
+ const char *prefix_cmesh = "t8_triangulated_spherical_surface_octahedron_cmesh";
+ const char *prefix_forest = "t8_triangulated_spherical_surface_octahedron_forest";
const int uniform_level = 5;
- const double radius = 1.0;
+ const double radius = 42.0;
+
+ t8_cmesh_t cmesh = t8_cmesh_new_triangulated_spherical_surface_octahedron (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_write_forest_to_vtu (forest, prefix_forest);
+ t8_global_productionf ("Wrote %s.\n\n", prefix_forest);
+
+ t8_forest_unref (&forest);
+ }
- t8_cmesh_t cmesh = t8_cmesh_new_triangulated_spherical_surface (radius, comm);
+ {
+ const char *prefix_cmesh = "t8_triangulated_spherical_surface_icosahedron_cmesh";
+ const char *prefix_forest = "t8_triangulated_spherical_surface_icosahedron_forest";
+
+ const int uniform_level = 5;
+ const double radius = 42.0;
+
+ t8_cmesh_t cmesh = t8_cmesh_new_triangulated_spherical_surface_icosahedron (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, 1.0);
+ t8_cmesh_vtk_write_file (cmesh, prefix_cmesh);
t8_global_productionf ("Wrote %s.\n", prefix_cmesh);
t8_write_forest_to_vtu (forest, prefix_forest);
@@ -148,13 +168,13 @@ main (int argc, char **argv)
const char *prefix_forest = "t8_quadrangulated_spherical_surface_forest";
const int uniform_level = 5;
- const double radius = 1.0;
+ const double radius = 42.0;
t8_cmesh_t cmesh = t8_cmesh_new_quadrangulated_spherical_surface (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, 1.0);
+ t8_cmesh_vtk_write_file (cmesh, prefix_cmesh);
t8_global_productionf ("Wrote %s.\n", prefix_cmesh);
t8_write_forest_to_vtu (forest, prefix_forest);
@@ -168,8 +188,10 @@ main (int argc, char **argv)
const char *prefix_forest = "t8_cubed_spherical_shell_forest";
const int uniform_level = 1;
- constexpr double inner_radius = std::sqrt (3);
- const double shell_thickness = 0.2;
+
+ const double inner_radius = 42.0;
+ const double shell_thickness = 5.0;
+
const int num_levels = 3;
const int num_layers = 2;
@@ -177,7 +199,55 @@ 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, 1.0);
+ t8_cmesh_vtk_write_file (cmesh, prefix_cmesh);
+ t8_global_productionf ("Wrote %s.\n", prefix_cmesh);
+
+ t8_write_forest_to_vtu (forest, prefix_forest);
+ t8_global_productionf ("Wrote %s.\n\n", prefix_forest);
+
+ t8_forest_unref (&forest);
+ }
+
+ {
+ 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 double inner_radius = 42.0;
+ const double shell_thickness = 5.0;
+ const int num_levels = 2;
+ const int num_layers = 1;
+
+ t8_cmesh_t cmesh
+ = t8_cmesh_new_prismed_spherical_shell_octahedron (inner_radius, shell_thickness, num_levels, num_layers, 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_write_forest_to_vtu (forest, prefix_forest);
+ t8_global_productionf ("Wrote %s.\n\n", prefix_forest);
+
+ t8_forest_unref (&forest);
+ }
+
+ {
+ 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 double inner_radius = 42.0;
+ const double shell_thickness = 5.0;
+ const int num_levels = 2;
+ const int num_layers = 1;
+
+ t8_cmesh_t cmesh
+ = t8_cmesh_new_prismed_spherical_shell_icosahedron (inner_radius, shell_thickness, num_levels, num_layers, 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_write_forest_to_vtu (forest, prefix_forest);
diff --git a/example/cmesh/t8_cmesh_hypercube_pad.cxx b/example/cmesh/t8_cmesh_hypercube_pad.cxx
index 3e8239a653..9615ae2969 100644
--- a/example/cmesh/t8_cmesh_hypercube_pad.cxx
+++ b/example/cmesh/t8_cmesh_hypercube_pad.cxx
@@ -55,7 +55,7 @@ main (int argc, char **argv)
t8_global_productionf (" [step1] Local number of trees:\t%i\n", local_num_trees);
t8_global_productionf (" [step1] Global number of trees:\t%li\n", global_num_trees);
- t8_cmesh_vtk_write_file (cmesh, prefix, 1.0);
+ t8_cmesh_vtk_write_file (cmesh, prefix);
t8_cmesh_destroy (&cmesh);
diff --git a/example/cmesh/t8_cmesh_partition.cxx b/example/cmesh/t8_cmesh_partition.cxx
index 069f4e3836..67bdef72c1 100644
--- a/example/cmesh/t8_cmesh_partition.cxx
+++ b/example/cmesh/t8_cmesh_partition.cxx
@@ -49,7 +49,7 @@ t8_random_partition (int level)
cmesh = t8_cmesh_new_from_p8est (conn, sc_MPI_COMM_WORLD, 1);
p8est_connectivity_destroy (conn);
snprintf (file, BUFSIZ, "t8_brick_random");
- t8_cmesh_vtk_write_file (cmesh, file, 1.);
+ t8_cmesh_vtk_write_file (cmesh, file);
t8_cmesh_init (&cmesh_part);
@@ -70,14 +70,14 @@ t8_random_partition (int level)
t8_cmesh_commit (cmesh_part2, sc_MPI_COMM_WORLD);
snprintf (file, BUFSIZ, "t8_brick_partition_random2");
- t8_cmesh_vtk_write_file (cmesh_part2, file, 1.0);
+ t8_cmesh_vtk_write_file (cmesh_part2, file);
}
else {
cmesh_part2 = cmesh_part;
t8_cmesh_ref (cmesh_part);
}
snprintf (file, BUFSIZ, "t8_brick_partition_random");
- t8_cmesh_vtk_write_file (cmesh_part, file, 1.0);
+ t8_cmesh_vtk_write_file (cmesh_part, file);
t8_cmesh_destroy (&cmesh);
t8_cmesh_unref (&cmesh_part);
t8_cmesh_destroy (&cmesh_part2);
@@ -106,7 +106,7 @@ t8_partition (int level, int partition_from)
cmesh = t8_cmesh_new_from_p4est (conn, sc_MPI_COMM_WORLD, partition_from);
p4est_connectivity_destroy (conn);
snprintf (file, BUFSIZ, "t8_brick");
- t8_cmesh_vtk_write_file (cmesh, file, 1.);
+ t8_cmesh_vtk_write_file (cmesh, file);
t8_cmesh_init (&cmesh_part);
/* We still need access to cmesh later */
@@ -123,14 +123,14 @@ t8_partition (int level, int partition_from)
t8_cmesh_offset_concentrate (1, sc_MPI_COMM_WORLD, t8_cmesh_get_num_trees (cmesh)));
t8_cmesh_commit (cmesh_part2, sc_MPI_COMM_WORLD);
snprintf (file, BUFSIZ, "t8_brick_partition2");
- t8_cmesh_vtk_write_file (cmesh_part2, file, 1.0);
+ t8_cmesh_vtk_write_file (cmesh_part2, file);
}
else {
cmesh_part2 = cmesh_part;
t8_cmesh_ref (cmesh_part);
}
snprintf (file, BUFSIZ, "t8_brick_partition");
- t8_cmesh_vtk_write_file (cmesh_part, file, 1.0);
+ t8_cmesh_vtk_write_file (cmesh_part, file);
t8_cmesh_destroy (&cmesh);
t8_cmesh_unref (&cmesh_part);
t8_cmesh_destroy (&cmesh_part2);
diff --git a/example/cmesh/t8_cmesh_set_join_by_vertices.cxx b/example/cmesh/t8_cmesh_set_join_by_vertices.cxx
index 7673dcd02d..82a7708078 100644
--- a/example/cmesh/t8_cmesh_set_join_by_vertices.cxx
+++ b/example/cmesh/t8_cmesh_set_join_by_vertices.cxx
@@ -197,10 +197,10 @@ main (int argc, char **argv)
const int dim = 3;
const int main_proc = 0;
const int partition = 0;
- const int use_occ_geometry = 0;
+ const int use_cad_geometry = 0;
t8_cmesh_t cmesh
- = t8_cmesh_from_msh_file (meshfile, partition, sc_MPI_COMM_WORLD, dim, main_proc, use_occ_geometry);
+ = t8_cmesh_from_msh_file (meshfile, partition, sc_MPI_COMM_WORLD, dim, main_proc, use_cad_geometry);
test_with_cmesh (cmesh);
diff --git a/example/forest/t8_test_face_iterate.cxx b/example/forest/t8_test_face_iterate.cxx
index 20a66b21d0..07262f5444 100644
--- a/example/forest/t8_test_face_iterate.cxx
+++ b/example/forest/t8_test_face_iterate.cxx
@@ -92,7 +92,7 @@ t8_test_fiterate (t8_forest_t forest)
= t8_forest_get_element_in_tree (forest, itree, t8_forest_get_tree_num_elements (forest, itree) - 1);
ts->t8_element_new (1, &nca);
ts->t8_element_nca (first_el, last_el, nca);
- leaf_elements = t8_forest_tree_get_leafs (forest, itree);
+ leaf_elements = t8_forest_tree_get_leaves (forest, itree);
for (iface = 0; iface < ts->t8_element_num_faces (nca); iface++) {
udata.count = 0;
@@ -110,7 +110,7 @@ t8_test_fiterate_refine_and_partition (t8_cmesh_t cmesh, int level, sc_MPI_Comm
t8_cmesh_t cmesh_partition;
if (!no_vtk) {
- t8_cmesh_vtk_write_file (cmesh, "test_fiterate_cmesh0", 1.0);
+ t8_cmesh_vtk_write_file (cmesh, "test_fiterate_cmesh0");
}
if (partition_cmesh) {
/* partition the initial cmesh according to a uniform forest */
@@ -124,7 +124,7 @@ t8_test_fiterate_refine_and_partition (t8_cmesh_t cmesh, int level, sc_MPI_Comm
cmesh_partition = cmesh;
}
if (!no_vtk) {
- t8_cmesh_vtk_write_file (cmesh_partition, "test_fiterate_cmesh1", 1.0);
+ t8_cmesh_vtk_write_file (cmesh_partition, "test_fiterate_cmesh1");
}
forest = t8_forest_new_uniform (cmesh_partition, t8_scheme_new_default_cxx (), level, 0, comm);
diff --git a/example/forest/t8_test_ghost.cxx b/example/forest/t8_test_ghost.cxx
index bcfb64babb..ef07d0dc84 100644
--- a/example/forest/t8_test_ghost.cxx
+++ b/example/forest/t8_test_ghost.cxx
@@ -119,7 +119,7 @@ t8_test_ghost_refine_and_partition (t8_cmesh_t cmesh, const int level, sc_MPI_Co
t8_forest_adapt_t adapt_fn;
if (!no_vtk) {
- t8_cmesh_vtk_write_file (cmesh, "test_ghost_cmesh0", 1.0);
+ t8_cmesh_vtk_write_file (cmesh, "test_ghost_cmesh0");
}
if (partition_cmesh) {
/* partition the initial cmesh according to a uniform forest */
@@ -133,7 +133,7 @@ t8_test_ghost_refine_and_partition (t8_cmesh_t cmesh, const int level, sc_MPI_Co
cmesh_partition = cmesh;
}
if (!no_vtk) {
- t8_cmesh_vtk_write_file (cmesh_partition, "test_ghost_cmesh1", 1.0);
+ t8_cmesh_vtk_write_file (cmesh_partition, "test_ghost_cmesh1");
}
forest = t8_forest_new_uniform (cmesh_partition, t8_scheme_new_default_cxx (), level, 1, comm);
diff --git a/example/forest/t8_test_ghost_large_level_diff.cxx b/example/forest/t8_test_ghost_large_level_diff.cxx
index 2368a14d00..787dcb565c 100644
--- a/example/forest/t8_test_ghost_large_level_diff.cxx
+++ b/example/forest/t8_test_ghost_large_level_diff.cxx
@@ -145,7 +145,7 @@ t8_ghost_large_level_diff (const char *prefix, int dim, int level, int refine, i
t8_cmesh_set_partition_uniform (cmesh_partition, level, t8_scheme_new_default_cxx ());
t8_cmesh_commit (cmesh_partition, comm);
if (!no_vtk) {
- t8_cmesh_vtk_write_file (cmesh_partition, "partitioned_cmesh", 1.0);
+ t8_cmesh_vtk_write_file (cmesh_partition, "partitioned_cmesh");
}
/* New */
diff --git a/example/geometry/t8_example_geometries.cxx b/example/geometry/t8_example_geometries.cxx
index 1922b350ea..a8ab9f7f8d 100644
--- a/example/geometry/t8_example_geometries.cxx
+++ b/example/geometry/t8_example_geometries.cxx
@@ -26,9 +26,10 @@
#include
#include
#include
-#include
+#include
#include
-#include
+#include
+#include
#include
#include
@@ -63,10 +64,11 @@ typedef enum {
T8_GEOM_CIRCLE,
T8_GEOM_3D,
T8_GEOM_MOVING,
- T8_GEOM_OCC_TRIANGLE,
- T8_GEOM_OCC_CURVE_CUBE,
- T8_GEOM_OCC_SURFACE_CUBES,
- T8_GEOM_OCC_SURFACE_CYLINDER,
+ T8_GEOM_ANALYTIC_QUAD_TO_SPHERE,
+ T8_GEOM_CAD_TRIANGLE,
+ T8_GEOM_CAD_CURVE_CUBE,
+ T8_GEOM_CAD_SURFACE_CUBES,
+ T8_GEOM_CAD_SURFACE_CYLINDER,
T8_GEOM_COUNT
} t8_example_geom_type;
@@ -510,6 +512,23 @@ t8_geom_adapt_boundary (t8_forest_t forest, t8_forest_t forest_from, t8_locidx_t
return 0;
}
+void
+quad_to_sphere_callback (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
+ double *out_coords, const void *tree_data, const void *user_data)
+{
+ for (size_t i_coord = 0; i_coord < num_coords; i_coord++) {
+ const size_t offset = 3 * i_coord;
+
+ const double radius = 1.0;
+ const double latitude = 2 * M_PI * ref_coords[offset + 0];
+ const double longitude = ref_coords[offset + 1] * M_PI;
+
+ out_coords[offset + 0] = radius * sin (longitude) * cos (latitude);
+ out_coords[offset + 1] = radius * sin (longitude) * sin (latitude);
+ out_coords[offset + 2] = radius * cos (longitude);
+ }
+}
+
static void
t8_analytic_geom (int level, t8_example_geom_type geom_type)
{
@@ -595,12 +614,21 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD);
snprintf (vtuname, BUFSIZ, "forest_moving_lvl_%i", level);
break;
- case T8_GEOM_OCC_TRIANGLE: {
+ case T8_GEOM_ANALYTIC_QUAD_TO_SPHERE:
+ t8_global_productionf ("Wrapping a quad around a sphere.\n");
+
+ geometry = new t8_geometry_analytic (3, "geom_quad_to_sphere", quad_to_sphere_callback, NULL, NULL, NULL);
+ t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_QUAD);
+ t8_cmesh_set_join (cmesh, 0, 0, 1, 0, 0);
+
+ snprintf (vtuname, BUFSIZ, "forest_quad_to_sphere");
+ break;
+ case T8_GEOM_CAD_TRIANGLE: {
#if T8_WITH_OCC
- t8_global_productionf ("Creating uniform level %i forests with an occ triangle geometry.\n", level);
+ t8_global_productionf ("Creating uniform level %i forests with an cad triangle geometry.\n", level);
/* Constructing a triangle with one curved edge (f2) */
- Handle_Geom_BSplineCurve occ_curve;
+ Handle_Geom_BSplineCurve cad_curve;
TColgp_Array1OfPnt point_array (1, 3);
TopoDS_Shape shape;
@@ -610,17 +638,17 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
point_array (3) = gp_Pnt (1.0, 2.0, 0.0);
/* Generate bsplines from arrays. */
- occ_curve = GeomAPI_PointsToBSpline (point_array).Curve ();
+ cad_curve = GeomAPI_PointsToBSpline (point_array).Curve ();
/* Fill shape with bsplines so that we can create a geometry with this shape. */
- shape = BRepBuilderAPI_MakeEdge (occ_curve).Edge ();
+ shape = BRepBuilderAPI_MakeEdge (cad_curve).Edge ();
- /* Create an occ geometry. */
- t8_geometry_occ *geometry_occ = new t8_geometry_occ (3, shape, "occ curve dim=3");
+ /* Create an cad geometry. */
+ t8_geometry_cad *geometry_cad = new t8_geometry_cad (3, shape, "cad curve dim=3");
/* The arrays indicate which face/edge carries a geometry.
* 0 means no geometry and any other number indicates the position of the geometry
- * in the global geometry array. Here edge 1 carries the created occ_curve. */
+ * in the global geometry array. Here edge 1 carries the created cad_curve. */
int faces[1] = { 0 };
int edges[6] = { 0, 1, 0, 0, 0, 0 };
/* Create tree 0 */
@@ -633,28 +661,28 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
/* Give the tree information about its curves and the parameters of the vertices.
* Each parameter set is given to the tree via its attribute key + the edge or face index it corresponds with. */
- t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces, 1 * sizeof (int),
+ t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces, 1 * sizeof (int),
0);
- t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY, edges, 6 * sizeof (int),
+ t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges, 6 * sizeof (int),
0);
- t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + 1,
+ t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + 1,
parameters_edge, 2 * sizeof (double), 0);
- geometry = geometry_occ;
- snprintf (vtuname, BUFSIZ, "forest_occ_triangle_lvl_%i", level);
+ geometry = geometry_cad;
+ snprintf (vtuname, BUFSIZ, "forest_cad_triangle_lvl_%i", level);
break;
#else /* !T8_WITH_OCC */
SC_ABORTF ("OCC not linked");
#endif /* T8_WITH_OCC */
}
- case T8_GEOM_OCC_CURVE_CUBE: {
+ case T8_GEOM_CAD_CURVE_CUBE: {
#if T8_WITH_OCC
- t8_global_productionf ("Creating uniform level %i forests with occ curve geometries.\n", level);
+ t8_global_productionf ("Creating uniform level %i forests with cad curve geometries.\n", level);
- /* Create two occ bsplines which oscillate along the x-axis.
+ /* Create two cad bsplines which oscillate along the x-axis.
* For this we need to define two arrays from which we create the bsplines. */
- Handle_Geom_Curve occ_curve0;
- Handle_Geom_Curve occ_curve1;
+ Handle_Geom_Curve cad_curve0;
+ Handle_Geom_Curve cad_curve1;
TColgp_Array1OfPnt point_array0 (1, 5);
TColgp_Array1OfPnt point_array1 (1, 5);
TopoDS_Shape shape;
@@ -673,19 +701,19 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
point_array1 (5) = gp_Pnt (1, 1, 1);
/* Generate bsplines from arrays. */
- occ_curve0 = GeomAPI_PointsToBSpline (point_array0).Curve ();
- occ_curve1 = GeomAPI_PointsToBSpline (point_array1).Curve ();
+ cad_curve0 = GeomAPI_PointsToBSpline (point_array0).Curve ();
+ cad_curve1 = GeomAPI_PointsToBSpline (point_array1).Curve ();
/* Fill shape with bsplines so that we can create a geometry with this shape. */
- shape = BRepBuilderAPI_MakeEdge (occ_curve0).Edge ();
- shape = BRepAlgoAPI_Fuse (shape, BRepBuilderAPI_MakeEdge (occ_curve1).Edge ());
+ shape = BRepBuilderAPI_MakeEdge (cad_curve0).Edge ();
+ shape = BRepAlgoAPI_Fuse (shape, BRepBuilderAPI_MakeEdge (cad_curve1).Edge ());
- /* Create an occ geometry. */
- t8_geometry_occ *geometry_occ = new t8_geometry_occ (3, shape, "occ curve dim=3");
+ /* Create an cad geometry. */
+ t8_geometry_cad *geometry_cad = new t8_geometry_cad (3, shape, "cad curve dim=3");
/* The arrays indicate which face/edge carries a geometry.
* 0 means no geometry and any other number indicates the position of the geometry
- * in the global geometry array. Here edge 0 carries occ_curve0 and edge 3 carries occ_curve1.
+ * in the global geometry array. Here edge 0 carries cad_curve0 and edge 3 carries cad_curve1.
* We add them in the next step. */
int faces[6] = { 0, 0, 0, 0, 0, 0 };
int edges[24] = { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -701,28 +729,28 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
/* Give the tree information about its curves and the parameters of the vertices.
* Each parameter set is given to the tree via its attribute key + the edge or face index it corresponds with. */
- t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces, 6 * sizeof (int),
+ 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_OCC_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int),
+ t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int),
0);
- t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + 0, parameters,
+ t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + 0, parameters,
2 * sizeof (double), 0);
- t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + 3, parameters,
+ t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + 3, parameters,
2 * sizeof (double), 0);
- geometry = geometry_occ;
- snprintf (vtuname, BUFSIZ, "forest_occ_curve_cube_lvl_%i", level);
+ geometry = geometry_cad;
+ snprintf (vtuname, BUFSIZ, "forest_cad_curve_cube_lvl_%i", level);
break;
-#else /* !T8_WITH_OCC */
+#else /* !T8_WITH_cad */
SC_ABORTF ("OCC not linked");
-#endif /* T8_WITH_OCC */
+#endif /* T8_WITH_cad */
}
- case T8_GEOM_OCC_SURFACE_CUBES: {
+ case T8_GEOM_CAD_SURFACE_CUBES: {
#if T8_WITH_OCC
- t8_global_productionf ("Creating uniform level %i forests with a occ surface geometry.\n", level);
+ t8_global_productionf ("Creating uniform level %i forests with a cad surface geometry.\n", level);
- /* Create a occ bspline surface with 2D array of knots */
- Handle_Geom_Surface occ_surface;
+ /* Create a cad bspline surface with 2D array of knots */
+ Handle_Geom_Surface cad_surface;
TColgp_Array2OfPnt point_array (1, 5, 1, 3);
TopoDS_Shape shape;
@@ -772,8 +800,8 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
/* Generate bspline surface from array and fill shape with it
* so that we can create a geometry with this shape. */
- occ_surface = GeomAPI_PointsToBSplineSurface (point_array).Surface ();
- shape = BRepBuilderAPI_MakeFace (occ_surface, 1e-6).Face ();
+ cad_surface = GeomAPI_PointsToBSplineSurface (point_array).Surface ();
+ shape = BRepBuilderAPI_MakeFace (cad_surface, 1e-6).Face ();
/* The arrays indicate which face/edge carries a geometry.
* 0 means no geometry and any other number indicates the position of the geometry
@@ -782,8 +810,8 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
int faces[6] = { 0, 0, 0, 0, 0, 1 };
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 occ geometry. */
- t8_geometry_occ *geometry_occ = new t8_geometry_occ (3, shape, "occ surface dim=3");
+ /* Create cad geometry. */
+ t8_geometry_cad *geometry_cad = new t8_geometry_cad (3, shape, "cad surface dim=3");
/* Create tree 0 */
t8_cmesh_set_tree_class (cmesh, 0, T8_ECLASS_HEX);
@@ -802,11 +830,11 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
/* Give tree 0 information about its surface and the parameters of the vertices.
* Each parameter set is given to the tree via its attribute key + the edge or face index it corresponds with.
*/
- t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces, 6 * sizeof (int),
+ 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_OCC_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int),
+ t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int),
0);
- t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + 5, parameters0,
+ t8_cmesh_set_attribute (cmesh, 0, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + 5, parameters0,
8 * sizeof (double), 0);
/* Create tree 1 */
@@ -826,28 +854,28 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
/* Give tree 1 information about its surface and the parameters of the vertices.
* Each parameter set is given to the tree via its attribute key + the edge or face index it corresponds with.
* We can use the same edges and faces array, because we link the surface to the same face on tree 1. */
- t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces, 6 * sizeof (int),
+ t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces, 6 * sizeof (int),
0);
- t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int),
+ t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int),
0);
- t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + 5, parameters1,
+ t8_cmesh_set_attribute (cmesh, 1, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + 5, parameters1,
8 * sizeof (double), 0);
/* Join tree 0 and tree 1 together */
t8_cmesh_set_join (cmesh, 0, 1, 1, 0, 0);
- geometry = geometry_occ;
- snprintf (vtuname, BUFSIZ, "forest_occ_surface_cubes_lvl_%i", level);
+ geometry = geometry_cad;
+ snprintf (vtuname, BUFSIZ, "forest_cad_surface_cubes_lvl_%i", level);
break;
#else /* !T8_WITH_OCC */
SC_ABORTF ("OCC not linked");
#endif /* T8_WITH_OCC */
}
- case T8_GEOM_OCC_SURFACE_CYLINDER: {
+ case T8_GEOM_CAD_SURFACE_CYLINDER: {
#if T8_WITH_OCC
- t8_global_productionf ("Creating uniform level %i forests with an occ cylinder geometry.\n", level);
+ t8_global_productionf ("Creating uniform level %i forests with an cad cylinder geometry.\n", level);
- /* Create occ cylinder surfaces. We use an outer radius of 0.5 to get a diameter of 1. */
+ /* Create cad cylinder surfaces. We use an outer radius of 0.5 to get a diameter of 1. */
double radius_inner = 0.25;
double radius_outer = 0.5;
@@ -880,8 +908,8 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
int faces[6] = { 1, 2, 0, 0, 0, 0 };
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 occ geometry. */
- t8_geometry_occ *geometry_occ = new t8_geometry_occ (3, shape, "occ surface dim=3");
+ /* Create cad geometry. */
+ t8_geometry_cad *geometry_cad = new t8_geometry_cad (3, shape, "cad surface dim=3");
/* Create corresponding trees and parameters.
* Here we create num trees by a coordinate transformation from cylinder to cartesian coordinates. */
@@ -932,24 +960,24 @@ t8_analytic_geom (int level, t8_example_geom_type geom_type)
/* Give the trees information about their surfaces and the parameters of the vertices.
* Each parameter set is given to the tree via its attribute key + face index it corresponds with.
* We can use the same edges and faces array, because we link the surface to the same faces on every tree.*/
- t8_cmesh_set_attribute (cmesh, i, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces, 6 * sizeof (int),
+ t8_cmesh_set_attribute (cmesh, i, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces, 6 * sizeof (int),
1);
- t8_cmesh_set_attribute (cmesh, i, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int),
+ t8_cmesh_set_attribute (cmesh, i, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges, 24 * sizeof (int),
1);
- t8_cmesh_set_attribute (cmesh, i, t8_get_package_id (), T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + 0,
+ t8_cmesh_set_attribute (cmesh, i, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + 0,
parameters + i * 8, 8 * sizeof (double), 0);
- t8_cmesh_set_attribute (cmesh, i, t8_get_package_id (), T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + 1,
+ t8_cmesh_set_attribute (cmesh, i, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + 1,
parameters + i * 8, 8 * sizeof (double), 0);
}
- geometry = geometry_occ;
+ geometry = geometry_cad;
T8_FREE (vertices);
T8_FREE (parameters);
snprintf (vtuname, BUFSIZ, "forest_geometry_cylinder_lvl_%i", level);
break;
-#else /* !T8_WITH_OCC */
+#else /* !T8_WITH_cad */
SC_ABORTF ("OCC not linked");
-#endif /* T8_WITH_OCC */
+#endif /* T8_WITH_cad */
}
default:
SC_ABORT_NOT_REACHED ();
@@ -1066,10 +1094,11 @@ main (int argc, char **argv)
"\t\t The mesh will not be uniform. Instead it is refined at the domain boundary.\n"
"\t\t5 - A cube that is distorted in z-direction with one 3D cube tree.\n"
"\t\t6 - A moving mesh consisting of a single 2D quad tree.\n"
- "\t\t7 - A curved triangle with an occ curve.\n"
- "\t\t8 - A cube with two occ curves as edges.\n"
- "\t\t9 - Two cubes with one occ surface as face.\n"
- "\t\t10 - A hollow cylinder with a occ surface on the in- and outside.\n");
+ "\t\t7 - A quad morphed into a sphere.\n"
+ "\t\t8 - A curved triangle with an cad curve.\n"
+ "\t\t9 - A cube with two cad curves as edges.\n"
+ "\t\t10 - Two cubes with one cad surface as face.\n"
+ "\t\t11 - A hollow cylinder with a cad surface on the in- and outside.\n");
parsed = sc_options_parse (t8_get_package_id (), SC_LP_ERROR, opt, argc, argv);
if (helpme) {
diff --git a/example/remove/t8_example_empty_trees.cxx b/example/remove/t8_example_empty_trees.cxx
index ca03fe0b5f..9aac0dce47 100644
--- a/example/remove/t8_example_empty_trees.cxx
+++ b/example/remove/t8_example_empty_trees.cxx
@@ -50,10 +50,10 @@ t8_strip_of_quads (t8_gloidx_t num_trees, t8_gloidx_t empty_tree, const char **v
{
const double boundary_coords[12] = { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0 };
- const t8_geometry_c *geometry = t8_geometry_linear_axis_aligned_new (2);
+ const int use_axis_alined = 1;
t8_cmesh_t cmesh
- = t8_cmesh_new_hypercube_pad (T8_ECLASS_QUAD, sc_MPI_COMM_WORLD, boundary_coords, num_trees, 1, 0, geometry);
+ = t8_cmesh_new_hypercube_pad (T8_ECLASS_QUAD, sc_MPI_COMM_WORLD, boundary_coords, num_trees, 1, 0, use_axis_alined);
t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), 0, 0, sc_MPI_COMM_WORLD);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000000..86961ac219
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,203 @@
+if ( ${T8CODE_BUILD_AS_SHARED_LIBRARY} )
+ add_library( T8 SHARED )
+ set_target_properties( T8 PROPERTIES POSITION_INDEPENDENT_CODE ON )
+else()
+ add_library( T8 STATIC )
+endif()
+
+set_target_properties( T8 PROPERTIES OUTPUT_NAME t8 )
+
+target_compile_definitions( T8 PUBLIC T8_CMAKE_BUILD )
+target_compile_definitions( T8 PUBLIC T8_CC="${CMAKE_C_COMPILER}" )
+target_compile_definitions( T8 PUBLIC T8_CFLAGS="${CMAKE_C_FLAGS}" )
+target_compile_definitions( T8 PUBLIC T8_CPP="${CMAKE_CXX_COMPILER}" )
+target_compile_definitions( T8 PUBLIC T8_CPPFLAGS="${CMAKE_CXX_FLAGS}" )
+target_compile_definitions( T8 PUBLIC T8_LDFLAGS="${CMAKE_SHARED_LINKER_FLAGS}" )
+target_compile_definitions( T8 PUBLIC T8_LIBS="Not available with CMake builds" )
+
+
+find_package( Git REQUIRED )
+execute_process( COMMAND ${GIT_EXECUTABLE} describe --tags
+ COMMAND cut -c 2-
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+ OUTPUT_VARIABLE T8CODE_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+execute_process( COMMAND echo ${T8CODE_VERSION}
+ COMMAND cut -d. -f1
+ OUTPUT_VARIABLE T8CODE_VERSION_MAJOR
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+execute_process( COMMAND echo ${T8CODE_VERSION}
+ COMMAND cut -d. -f2
+ OUTPUT_VARIABLE T8CODE_VERSION_MINOR
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+execute_process( COMMAND echo ${T8CODE_VERSION}
+ COMMAND cut -d. -f3
+ OUTPUT_VARIABLE T8CODE_VERSION_POINT
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+
+target_compile_definitions( T8 PUBLIC T8_PACKAGE_STRING="t8 ${T8CODE_VERSION}" )
+target_compile_definitions( T8 PUBLIC T8_VERSION="${T8CODE_VERSION}" )
+target_compile_definitions( T8 PUBLIC T8_VERSION_MAJOR=${T8CODE_VERSION_MAJOR} )
+target_compile_definitions( T8 PUBLIC T8_VERSION_MINOR=${T8CODE_VERSION_MINOR} )
+target_compile_definitions( T8 PUBLIC T8_VERSION_POINT=${T8CODE_VERSION_POINT} )
+
+
+target_include_directories( T8 PUBLIC ${CMAKE_CURRENT_LIST_DIR} )
+target_link_libraries( T8 PUBLIC P4EST::P4EST SC::SC )
+
+if ( CMAKE_BUILD_TYPE STREQUAL "Debug" )
+ target_compile_definitions( T8 PUBLIC T8_ENABLE_DEBUG )
+endif()
+
+if ( T8CODE_ENABLE_MPI )
+ target_compile_definitions( T8 PUBLIC T8_ENABLE_MPI )
+ target_compile_definitions( T8 PUBLIC T8_ENABLE_MPIIO )
+ target_link_libraries( T8 PUBLIC MPI::MPI_C )
+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_link_libraries( T8 PUBLIC ${VTK_LIBRARIES} )
+endif()
+
+target_sources( T8 PRIVATE
+ t8.c
+ t8_eclass.c
+ t8_mesh.c
+ t8_element.c
+ t8_element_cxx.cxx
+ t8_element_c_interface.cxx
+ t8_refcount.c
+ t8_cmesh/t8_cmesh.c
+ t8_cmesh/t8_cmesh_cad.cxx
+ t8_cmesh/t8_cmesh_cxx.cxx
+ t8_cmesh/t8_cmesh_triangle.c
+ 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.c
+ t8_cmesh/t8_cmesh_netcdf.c
+ t8_cmesh/t8_cmesh_trees.c
+ t8_cmesh/t8_cmesh_commit.c
+ t8_cmesh/t8_cmesh_partition.c
+ t8_cmesh/t8_cmesh_copy.c
+ t8_data/t8_shmem.c
+ t8_cmesh/t8_cmesh_geometry.cxx
+ t8_cmesh/t8_cmesh_examples.c
+ t8_cmesh/t8_cmesh_helpers.c
+ t8_data/t8_containers.cxx
+ t8_cmesh/t8_cmesh_offset.c
+ t8_cmesh/t8_cmesh_readmshfile.cxx
+ t8_forest/t8_forest.c
+ t8_forest/t8_forest_adapt.cxx
+ t8_geometry/t8_geometry.cxx
+ t8_geometry/t8_geometry_helpers.c
+ t8_geometry/t8_geometry_base.cxx
+ t8_geometry/t8_geometry_with_vertices.cxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_analytic.cxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_linear.cxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.cxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_zero.cxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_examples.cxx
+ t8_forest/t8_forest_partition.cxx
+ t8_forest/t8_forest_cxx.cxx
+ t8_forest/t8_forest_private.c
+ t8_forest/t8_forest_vtk.cxx
+ t8_forest/t8_forest_ghost.cxx
+ t8_forest/t8_forest_iterate.cxx
+ t8_version.c
+ t8_vtk.c
+ t8_forest/t8_forest_balance.cxx
+ t8_forest/t8_forest_netcdf.cxx
+ t8_element_shape.c
+ t8_netcdf.c
+ t8_cmesh/t8_cmesh_testcases.c
+ t8_vtk/t8_vtk_polydata.cxx
+ t8_vtk/t8_vtk_unstructured.cxx
+ t8_vtk/t8_vtk_parallel.cxx
+ t8_vtk/t8_vtk_reader.cxx
+ t8_schemes/t8_default/t8_default_cxx.cxx
+ t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx
+ t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.cxx
+ t8_schemes/t8_default/t8_default_hex/t8_dhex_bits.c
+ t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.cxx
+ t8_schemes/t8_default/t8_default_line/t8_dline_bits.c
+ t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.cxx
+ t8_schemes/t8_default/t8_default_prism/t8_dprism_bits.c
+ t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.cxx
+ t8_schemes/t8_default/t8_default_quad/t8_dquad_bits.c
+ t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.cxx
+ t8_schemes/t8_default/t8_default_tet/t8_dtet_bits.c
+ t8_schemes/t8_default/t8_default_tet/t8_dtet_connectivity.c
+ t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.cxx
+ t8_schemes/t8_default/t8_default_tri/t8_dtri_bits.c
+ t8_schemes/t8_default/t8_default_tri/t8_dtri_connectivity.c
+ t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.cxx
+ t8_schemes/t8_default/t8_default_vertex/t8_dvertex_bits.c
+ t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.cxx
+ t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_bits.c
+ t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.c
+)
+
+set( T8_PUBLIC_HEADERS
+ t8.h
+ t8_eclass.h
+ t8_mesh.h
+ t8_element_cxx.hxx
+ t8_element.h
+ t8_element_c_interface.h
+ t8_refcount.h
+ t8_cmesh.h t8_cmesh_triangle.h
+ t8_cmesh_tetgen.h t8_cmesh_readmshfile.h
+ t8_cmesh_vtk_writer.h
+ t8_cmesh_vtk_reader.hxx
+ t8_vec.h
+ t8_version.h
+ t8_vtk.h
+ t8_cmesh_netcdf.h
+ t8_forest_netcdf.h
+ t8_element_shape.h
+ t8_netcdf.h
+ t8_cmesh/t8_cmesh_testcases.h
+ t8_cmesh/t8_cmesh_save.h
+ t8_cmesh/t8_cmesh_examples.h
+ t8_cmesh/t8_cmesh_geometry.h
+ t8_cmesh/t8_cmesh_helpers.h
+ t8_cmesh/t8_cmesh_cad.hxx
+ t8_data/t8_shmem.h
+ t8_data/t8_containers.h
+ t8_forest/t8_forest.h
+ t8_forest/t8_forest_general.h
+ t8_forest/t8_forest_geometrical.h
+ t8_forest/t8_forest_profiling.h
+ t8_forest/t8_forest_io.h
+ t8_forest/t8_forest_adapt.h
+ t8_forest/t8_forest_vtk.h
+ t8_forest/t8_forest_to_vtkUnstructured.hxx
+ t8_forest/t8_forest_iterate.h
+ t8_forest/t8_forest_partition.h
+ t8_geometry/t8_geometry.h
+ t8_geometry/t8_geometry_base.hxx
+ t8_geometry/t8_geometry_base.h
+ t8_geometry/t8_geometry_with_vertices.hxx
+ t8_geometry/t8_geometry_with_vertices.h
+ t8_geometry/t8_geometry_helpers.h
+ t8_geometry/t8_geometry_implementations/t8_geometry_linear.h
+ t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.h
+ t8_geometry/t8_geometry_implementations/t8_geometry_analytic.hxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_examples.h
+ t8_geometry/t8_geometry_implementations/t8_geometry_cad.h
+ t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.hxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_examples.hxx
+ t8_geometry/t8_geometry_implementations/t8_geometry_zero.hxx
+ t8_vtk/t8_vtk_reader.hxx
+ t8_vtk/t8_vtk_types.h
+)
+
+install( FILES ${T8_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include )
+install( TARGETS T8 DESTINATION ${CMAKE_INSTALL_PREFIX}/lib )
diff --git a/src/Makefile.am b/src/Makefile.am
index 42ca28aa9b..b684c8e34d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,7 +41,7 @@ libt8_installed_headers_cmesh = \
src/t8_cmesh/t8_cmesh_examples.h \
src/t8_cmesh/t8_cmesh_geometry.h \
src/t8_cmesh/t8_cmesh_helpers.h \
- src/t8_cmesh/t8_cmesh_occ.hxx
+ src/t8_cmesh/t8_cmesh_cad.hxx
libt8_installed_headers_data = \
src/t8_data/t8_shmem.h src/t8_data/t8_containers.h
libt8_installed_headers_forest = \
@@ -65,9 +65,10 @@ libt8_installed_headers_geometry_impl = \
src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.h \
src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.h \
src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.hxx \
+ src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.h \
src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.h \
- src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.h \
- src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.hxx \
+ src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.h \
+ src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx \
src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx \
src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.hxx \
src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.hxx \
@@ -104,7 +105,7 @@ libt8_compiled_sources = \
src/t8_element.c src/t8_element_cxx.cxx \
src/t8_element_c_interface.cxx \
src/t8_refcount.c src/t8_cmesh/t8_cmesh.c \
- src/t8_cmesh/t8_cmesh_occ.cxx \
+ src/t8_cmesh/t8_cmesh_cad.cxx \
src/t8_cmesh/t8_cmesh_cxx.cxx src/t8_cmesh/t8_cmesh_triangle.c \
src/t8_cmesh/t8_cmesh_vtk_writer.c src/t8_cmesh/t8_cmesh_stash.c \
src/t8_cmesh/t8_cmesh_vtk_reader.cxx \
@@ -124,7 +125,7 @@ libt8_compiled_sources = \
src/t8_geometry/t8_geometry_base.cxx \
src/t8_geometry/t8_geometry_with_vertices.cxx \
src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.cxx \
- src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.cxx \
+ src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx \
src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.cxx \
src/t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.cxx \
src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.cxx \
@@ -156,9 +157,13 @@ src_libt8_la_CPPFLAGS = $(AM_CPPFLAGS) $(T8_CPPFLAGS)
## This is the official API versioning scheme of libtool. Please see:
## Read https://www.gnu.org/software/libtool/manual/libtool.html#Versioning
src_libt8_la_LDFLAGS = -version-info 2:0:0
-src_libt8_la_LIBADD = @T8_P4EST_LDADD@ @T8_SC_LDADD@
+src_libt8_la_LIBADD = @T8_P4EST_LIBADD@ @T8_SC_LIBADD@
+EXTRA_src_libt8_la_DEPENDENCIES = @T8_SC_EDEPS@
+
+AM_LDFLAGS =
+AM_LDFLAGS += @T8_SC_RPATH@
LDADD += src/libt8.la @T8_P4EST_LDADD@ @T8_SC_LDADD@
-EXTRA_src_libt8_la_DEPENDENCIES = @T8_P4EST_LDADD@ @T8_SC_LDADD@
+
nodist_include_HEADERS += $(libt8_generated_headers)
dist_include_HEADERS = $(libt8_installed_headers)
diff --git a/src/t8.h b/src/t8.h
index cf5d00d356..c4da06a1fe 100644
--- a/src/t8.h
+++ b/src/t8.h
@@ -30,7 +30,9 @@
#define T8_H
/* include config headers */
+#ifndef T8_CMAKE_BUILD
#include
+#endif
#include
#if (defined(T8_ENABLE_MPI) && !defined(SC_ENABLE_MPI)) || (!defined(T8_ENABLE_MPI) && defined(SC_ENABLE_MPI))
#error "MPI configured differently in t8code and libsc"
diff --git a/src/t8_cmesh.h b/src/t8_cmesh.h
index 89c82017a1..2043209a4b 100644
--- a/src/t8_cmesh.h
+++ b/src/t8_cmesh.h
@@ -119,7 +119,7 @@ t8_cmesh_no_negative_volume (t8_cmesh_t cmesh);
*/
/* TODO: write a test for this function */
int
-t8_cmesh_tree_vertices_negative_volume (t8_eclass_t eclass, double *vertices, int num_vertices);
+t8_cmesh_tree_vertices_negative_volume (const t8_eclass_t eclass, const double *vertices, const int num_vertices);
/* TODO: Currently it is not possible to destroy set_from before
* cmesh is destroyed. */
@@ -671,7 +671,7 @@ t8_cmesh_get_attribute (const t8_cmesh_t cmesh, const int package_id, const int
* \param [in] package_id The identifier of a valid software package. \see sc_package_register
* \param [in] key A key used to identify the attribute under all
* attributes of this tree with the same \a package_id.
- * \param [in] tree_id The local number of the tree.
+ * \param [in] ltree_id The local number of the tree.
* \param [in] data_count The number of entries in the array that are requested.
* This must be smaller or equal to the \a data_count parameter
* of the corresponding call to \ref t8_cmesh_set_attribute_gloidx_array
diff --git a/src/t8_cmesh/t8_cmesh.c b/src/t8_cmesh/t8_cmesh.c
index 68c0cd8e25..8187c2f034 100644
--- a/src/t8_cmesh/t8_cmesh.c
+++ b/src/t8_cmesh/t8_cmesh.c
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -388,22 +389,6 @@ t8_cmesh_get_attribute (const t8_cmesh_t cmesh, const int package_id, const int
cmesh->trees, is_ghost ? t8_cmesh_ltreeid_to_ghostid (cmesh, ltree_id) : ltree_id, package_id, key, NULL, is_ghost);
}
-/* Return the attribute pointer of a tree for a gloidx_t array.
- * \param [in] cmesh The cmesh.
- * \param [in] package_id The identifier of a valid software package. \see sc_package_register
- * \param [in] key A key used to identify the attribute under all
- * attributes of this tree with the same \a package_id.
- * \param [in] tree_id The local number of the tree.
- * \param [out] data_count The number of entries in the array that are requested.
- * This must be smaller or equal to the \a data_count parameter
- * of the corresponding call to \ref t8_cmesh_set_attribute_gloidx_array
- * \return The attribute pointer of the tree \a ltree_id or NULL if the attribute is not found.
- * \note \a cmesh must be committed before calling this function.
- * \note No check is performed whether the attribute actually stored \a data_count many entries since
- * we do not store the number of data entries of the attribute array.
- * You can keep track of the data count yourself by using another attribute.
- * \see t8_cmesh_set_attribute_gloidx_array
- */
t8_gloidx_t *
t8_cmesh_get_attribute_gloidx_array (const t8_cmesh_t cmesh, const int package_id, const int key,
const t8_locidx_t ltree_id, const size_t data_count)
@@ -468,7 +453,7 @@ t8_cmesh_set_tree_class (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, t8_eclass_t tre
* coordinates does have negative volume.
*/
int
-t8_cmesh_tree_vertices_negative_volume (t8_eclass_t eclass, double *vertices, int num_vertices)
+t8_cmesh_tree_vertices_negative_volume (const t8_eclass_t eclass, const double *vertices, const int num_vertices)
{
double v_1[3], v_2[3], v_j[3], cross[3], sc_prod;
int i, j;
@@ -549,7 +534,14 @@ t8_cmesh_no_negative_volume (t8_cmesh_t cmesh)
if (vertices != NULL) {
/* Vertices are set */
eclass = t8_cmesh_get_tree_class (cmesh, itree);
- ret = t8_cmesh_tree_vertices_negative_volume (eclass, vertices, t8_eclass_num_vertices[eclass]);
+ const t8_gloidx_t gtree_id = t8_cmesh_get_global_id (cmesh, itree);
+ if (t8_geometry_get_type (cmesh, gtree_id) == T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED) {
+ /* Tree has negative volume if the diagonal goes from v_max to v_min and not vice versa */
+ ret = vertices[3] < vertices[0] && vertices[4] < vertices[1] && vertices[5] < vertices[2];
+ }
+ else {
+ ret = t8_cmesh_tree_vertices_negative_volume (eclass, vertices, t8_eclass_num_vertices[eclass]);
+ }
if (ret) {
t8_debugf ("Detected negative volume in tree %li\n", (long) itree);
}
@@ -561,7 +553,8 @@ t8_cmesh_no_negative_volume (t8_cmesh_t cmesh)
#endif
void
-t8_cmesh_set_tree_vertices (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, double *vertices, int num_vertices)
+t8_cmesh_set_tree_vertices (t8_cmesh_t cmesh, const t8_gloidx_t gtree_id, const double *vertices,
+ const int num_vertices)
{
T8_ASSERT (cmesh != NULL);
T8_ASSERT (vertices != NULL);
diff --git a/src/t8_cmesh/t8_cmesh_occ.cxx b/src/t8_cmesh/t8_cmesh_cad.cxx
similarity index 89%
rename from src/t8_cmesh/t8_cmesh_occ.cxx
rename to src/t8_cmesh/t8_cmesh_cad.cxx
index 94c864e88c..29d5932bc1 100644
--- a/src/t8_cmesh/t8_cmesh_occ.cxx
+++ b/src/t8_cmesh/t8_cmesh_cad.cxx
@@ -20,14 +20,14 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-/** \file t8_cmesh_occ.cxx
+/** \file t8_cmesh_cad.cxx
*
* TODO: document this file
*/
-#include
+#include
#include
-#include
+#include
#if T8_WITH_OCC
#include
@@ -48,16 +48,16 @@
t8_cmesh_t
t8_cmesh_new_hollow_cylinder (sc_MPI_Comm comm, int num_tangential_trees, int num_axial_trees, int num_radial_trees,
- int with_occ_geometry)
+ int with_cad_geometry)
{
/* Create the cmesh and the geometry */
t8_cmesh_t cmesh;
t8_cmesh_init (&cmesh);
t8_cmesh_set_profiling (cmesh, 1);
- if (with_occ_geometry) {
+ if (with_cad_geometry) {
#if T8_WITH_OCC
- /* Create the two occ cylinder surfaces */
+ /* Create the two cad cylinder surfaces */
const double radius_inner = 0.25;
const double radius_outer = 0.5;
const gp_Pnt origin (0, 0, 0);
@@ -75,13 +75,13 @@ t8_cmesh_new_hollow_cylinder (sc_MPI_Comm comm, int num_tangential_trees, int nu
const TopoDS_Face face_inner = TopoDS::Face (BRepPrimAPI_MakePrism (edge_inner, height));
const Handle_Geom_Surface cylinder_inner = BRep_Tool::Surface (face_inner);
- /* Fill a shape with cylinders and register an occ geometry with this shape. */
+ /* Fill a shape with cylinders and register an cad geometry with this shape. */
TopoDS_Shape shape;
shape = BRepBuilderAPI_MakeFace (cylinder_outer, 1e-6).Face ();
shape = BRepAlgoAPI_Fuse (shape, BRepBuilderAPI_MakeFace (cylinder_inner, 1e-6).Face ());
- t8_geometry_occ *geometry_occ = new t8_geometry_occ (3, shape, "occ surface dim=3");
+ t8_geometry_cad *geometry_cad = new t8_geometry_cad (3, shape, "cad surface dim=3");
- t8_cmesh_register_geometry (cmesh, geometry_occ);
+ t8_cmesh_register_geometry (cmesh, geometry_cad);
#else /* !T8_WITH_OCC */
SC_ABORTF ("OCC not linked");
@@ -105,7 +105,7 @@ t8_cmesh_new_hollow_cylinder (sc_MPI_Comm comm, int num_tangential_trees, int nu
const double dphi = 2.0 * M_PI / num_tangential_trees;
const double dh = 1.0 / num_axial_trees;
/* Allocate memory for saving the node coordinates
- * and in case of usage of the occ geometry, the node parameters */
+ * and in case of usage of the cad geometry, the node parameters */
double *vertices;
vertices = T8_ALLOC (double, num_tangential_trees *num_axial_trees *num_radial_trees * 24);
#if T8_WITH_OCC
@@ -164,9 +164,9 @@ t8_cmesh_new_hollow_cylinder (sc_MPI_Comm comm, int num_tangential_trees, int nu
vertices + ((i_tangential_trees * num_axial_trees + i_axial_trees) * num_radial_trees + i_radial_trees) * 24,
24);
- /* Assign parameters if occ is enabled */
+ /* Assign parameters if cad is enabled */
#if T8_WITH_OCC
- if (with_occ_geometry) {
+ if (with_cad_geometry) {
/* Calculate parameters if cell lies on boundary */
const int current_tree_parameters = (i_tangential_trees * num_axial_trees + i_axial_trees) * 8;
if (i_radial_trees == 0 || i_radial_trees == num_radial_trees - 1) {
@@ -185,62 +185,62 @@ t8_cmesh_new_hollow_cylinder (sc_MPI_Comm comm, int num_tangential_trees, int nu
= (i_tangential_trees * num_axial_trees + i_axial_trees) * num_radial_trees + i_radial_trees;
/* If geometry on both sides of cell */
if (num_radial_trees == 1) {
- /* Assign occ geometries to the corresponding faces */
+ /* Assign cad geometries to the corresponding faces */
int faces[6] = { 0 };
faces[0] = cylinder_outer_index;
faces[1] = cylinder_inner_index;
/* Assign attributes to cmesh cells */
- t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces,
+ t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces,
6 * sizeof (int), 0);
- t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY, edges,
+ t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges,
24 * sizeof (int), 0);
t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (),
- T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + 0,
+ T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + 0,
parameters + current_tree_parameters, 8 * sizeof (double), 1);
t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (),
- T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + 1,
+ T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + 1,
parameters + current_tree_parameters, 8 * sizeof (double), 1);
}
/* If geometry only on face 1 */
else if (i_radial_trees == 0) {
- /* Assign occ geometries to the corresponding faces */
+ /* Assign cad geometries to the corresponding faces */
int faces[6] = { 0 };
faces[1] = cylinder_inner_index;
/* Assign attributes to cmesh cells */
- t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces,
+ t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces,
6 * sizeof (int), 0);
- t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY, edges,
+ t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges,
24 * sizeof (int), 0);
t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (),
- T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + 1,
+ T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + 1,
parameters + current_tree_parameters, 8 * sizeof (double), 1);
}
/* If geometry only on face 0 */
else if (i_radial_trees == num_radial_trees - 1) {
- /* Assign occ geometries to the corresponding faces */
+ /* Assign cad geometries to the corresponding faces */
int faces[6] = { 0 };
faces[0] = cylinder_outer_index;
/* Assign attributes to cmesh cells */
- t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces,
+ t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces,
6 * sizeof (int), 0);
- t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY, edges,
+ t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges,
24 * sizeof (int), 0);
t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (),
- T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + 0,
+ T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + 0,
parameters + current_tree_parameters, 8 * sizeof (double), 1);
}
/* If there is no geometry */
else {
- /* Assign occ geometries to the corresponding faces */
+ /* Assign cad geometries to the corresponding faces */
int faces[6] = { 0 };
/* Assign attributes to cmesh cells */
- t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, faces,
+ t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, faces,
6 * sizeof (int), 0);
- t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY, edges,
+ t8_cmesh_set_attribute (cmesh, current_tree, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, edges,
24 * sizeof (int), 0);
}
}
diff --git a/src/t8_cmesh/t8_cmesh_occ.hxx b/src/t8_cmesh/t8_cmesh_cad.hxx
similarity index 84%
rename from src/t8_cmesh/t8_cmesh_occ.hxx
rename to src/t8_cmesh/t8_cmesh_cad.hxx
index 2ebda29fe9..b900bcdb3f 100644
--- a/src/t8_cmesh/t8_cmesh_occ.hxx
+++ b/src/t8_cmesh/t8_cmesh_cad.hxx
@@ -20,28 +20,28 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-/** \file t8_cmesh_occ.hxx
- * We define coarse meshes with occ geometries here
+/** \file t8_cmesh_cad.hxx
+ * We define coarse meshes with cad geometries here
*/
-#ifndef T8_CMESH_OCC_HXX
-#define T8_CMESH_OCC_HXX
+#ifndef T8_CMESH_CAD_HXX
+#define T8_CMESH_CAD_HXX
#include
/** Construct a hollow cylinder out of hexes with an inner diameter of 0.5,
* an outer diameter of 1 and a height of 1. The number of cells used in each direction can be specified.
- * A cylindrical occ surface can be linked to the inner and outer faces of the cylinder trees, to use the
- * occ geometry.
+ * A cylindrical cad surface can be linked to the inner and outer faces of the cylinder trees, to use the
+ * cad geometry.
* \param [in] comm The mpi communicator to use.
* \param [in] num_tangential_trees Number of trees distributed around the cylinder.
* \param [in] num_axial_trees Number of trees distributed along the height of the cylinder.
* \param [in] num_radial_trees Number of trees distributed along the thickness of the cylinder.
- * \param [in] with_occ_geometry Link the cylinder to a occ geometry, 0 or 1.
+ * \param [in] with_cad_geometry Link the cylinder to a cad geometry, 0 or 1.
* \return A valid cmesh, as if _init and _commit had been called.
*/
t8_cmesh_t
t8_cmesh_new_hollow_cylinder (sc_MPI_Comm comm, int num_tangential_trees, int num_axial_trees, int num_radial_trees,
- int with_occ_geometry);
+ int with_cad_geometry);
#endif /* !T8_CMESH_H */
diff --git a/src/t8_cmesh/t8_cmesh_cxx.cxx b/src/t8_cmesh/t8_cmesh_cxx.cxx
index 01060ed504..16b770606c 100644
--- a/src/t8_cmesh/t8_cmesh_cxx.cxx
+++ b/src/t8_cmesh/t8_cmesh_cxx.cxx
@@ -72,7 +72,7 @@ t8_cmesh_uniform_bounds (t8_cmesh_t cmesh, int level, t8_scheme_cxx_t *ts, t8_gl
if (cmesh->num_trees_per_eclass[tree_class] > 0) {
tree_scheme = ts->eclass_schemes[tree_class];
T8_ASSERT (tree_scheme != NULL);
- children_per_tree = tree_scheme->t8_element_count_leafs_from_root (level);
+ children_per_tree = tree_scheme->t8_element_count_leaves_from_root (level);
T8_ASSERT (children_per_tree >= 0);
global_num_children += cmesh->num_trees_per_eclass[tree_class] * children_per_tree;
}
diff --git a/src/t8_cmesh/t8_cmesh_examples.c b/src/t8_cmesh/t8_cmesh_examples.c
index 97aeea2ec6..62e0cfdf51 100644
--- a/src/t8_cmesh/t8_cmesh_examples.c
+++ b/src/t8_cmesh/t8_cmesh_examples.c
@@ -987,7 +987,6 @@ t8_cmesh_set_vertices_2D (t8_cmesh_t cmesh, const t8_eclass_t eclass, const doub
*/
for (t8_locidx_t quad_y_id = 0; quad_y_id < quads_y; quad_y_id++) {
for (t8_locidx_t quad_x_id = 0; quad_x_id < quads_x; quad_x_id++) {
-
memcpy (vertices, box, 3 * sizeof (double)); /* Vertex 0 */
t8_vec_axpyz (box, box_dir, vertices + 6, 1.0); /* Vertex 2 */
@@ -1259,7 +1258,7 @@ t8_cmesh_set_vertices_3D (t8_cmesh_t cmesh, const t8_eclass_t eclass, const doub
t8_cmesh_t
t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const double *boundary, t8_locidx_t polygons_x,
- t8_locidx_t polygons_y, t8_locidx_t polygons_z, const t8_geometry_c *geometry)
+ t8_locidx_t polygons_y, t8_locidx_t polygons_z, const int use_axis_aligned)
{
SC_CHECK_ABORT (eclass != T8_ECLASS_PYRAMID, "Pyramids are not yet supported.");
const int dim = t8_eclass_to_dimension[eclass];
@@ -1280,7 +1279,7 @@ t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const do
t8_cmesh_t cmesh;
t8_cmesh_init (&cmesh);
- const int is_axis_aligned = t8_geom_get_type (geometry) == T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED;
+ t8_geometry_c *geometry = use_axis_aligned ? t8_geometry_linear_axis_aligned_new (dim) : t8_geometry_linear_new (dim);
t8_cmesh_register_geometry (cmesh, geometry);
@@ -1296,11 +1295,11 @@ t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const do
/* Set the vertices of all trees. */
if (dim == 3) {
T8_ASSERT (eclass == T8_ECLASS_HEX || eclass == T8_ECLASS_TET || eclass == T8_ECLASS_PRISM);
- t8_cmesh_set_vertices_3D (cmesh, eclass, boundary, polygons_x, polygons_y, polygons_z, is_axis_aligned);
+ t8_cmesh_set_vertices_3D (cmesh, eclass, boundary, polygons_x, polygons_y, polygons_z, use_axis_aligned);
}
else if (dim == 2) {
T8_ASSERT (eclass == T8_ECLASS_QUAD || eclass == T8_ECLASS_TRIANGLE);
- t8_cmesh_set_vertices_2D (cmesh, eclass, boundary, polygons_x, polygons_y, is_axis_aligned);
+ t8_cmesh_set_vertices_2D (cmesh, eclass, boundary, polygons_x, polygons_y, use_axis_aligned);
}
else if (dim == 1) {
T8_ASSERT (eclass == T8_ECLASS_LINE);
@@ -1316,9 +1315,9 @@ t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const do
double vertices[6];
/* Set first vertex to lower end of line */
- t8_vec_axy (boundary, vertices, 1.0);
+ memcpy (vertices, boundary, 3 * sizeof (double));
/* Set second vertex to lower end of line + line_dir */
- t8_vec_axpyz (vertices + 3, boundary, line_dir, 1.0);
+ t8_vec_axpyz (line_dir, boundary, vertices + 3, 1.0);
for (t8_gloidx_t tree_x = 0; tree_x < polygons_x; tree_x++) {
t8_cmesh_set_tree_vertices (cmesh, tree_x, vertices, 2);
@@ -1421,7 +1420,7 @@ t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const do
if (eclass == T8_ECLASS_HEX) {
const t8_locidx_t tree_id_0 = poly_id_0;
const t8_locidx_t tree_id_1 = poly_id_0 + polygons_y * polygons_x;
- t8_cmesh_set_join (cmesh, tree_id_0, tree_id_1, 5, 4, 4);
+ t8_cmesh_set_join (cmesh, tree_id_0, tree_id_1, 5, 4, 0);
}
else if (eclass == T8_ECLASS_TET) {
t8_locidx_t tree_id_0 = poly_id_0 * 6 + 5;
@@ -2801,7 +2800,7 @@ t8_cmesh_new_squared_disk (const double radius, sc_MPI_Comm comm)
}
t8_cmesh_t
-t8_cmesh_new_triangulated_spherical_surface (const double radius, sc_MPI_Comm comm)
+t8_cmesh_new_triangulated_spherical_surface_octahedron (const double radius, sc_MPI_Comm comm)
{
/* Initialization of the mesh */
t8_cmesh_t cmesh;
@@ -2868,6 +2867,144 @@ t8_cmesh_new_triangulated_spherical_surface (const double radius, sc_MPI_Comm co
return cmesh;
}
+t8_cmesh_t
+t8_cmesh_new_triangulated_spherical_surface_icosahedron (const double radius, sc_MPI_Comm comm)
+{
+ /* Initialization of the mesh */
+ t8_cmesh_t cmesh;
+ t8_cmesh_init (&cmesh);
+
+ t8_geometry_c *geometry = t8_geometry_triangulated_spherical_surface_new ();
+
+ t8_cmesh_register_geometry (cmesh, geometry); /* Use linear geometry */
+
+ const int ntrees = 20; /* Number of cmesh elements resp. trees, i.e. number of triangles in an icosahedron. */
+ const int nverts = 3; /* Number of cmesh element 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 alpha = 63.43494882292201 / 180.0 * M_PI; /* Icosahedral angle. */
+
+ double vertices_top[3 * 3];
+ double vertices_bot[3 * 3];
+
+ {
+ /* Prepare initial triangle on the top of the icosahedron. */
+ double rot_mat[3][3];
+
+ vertices_top[0] = 0.0;
+ vertices_top[1] = 0.0;
+ vertices_top[2] = radius;
+
+ t8_mat_init_yrot (rot_mat, alpha);
+ t8_mat_mult_vec (rot_mat, vertices_top + 0, vertices_top + 3);
+
+ t8_mat_init_zrot (rot_mat, 2.0 / 5.0 * M_PI);
+ t8_mat_mult_vec (rot_mat, vertices_top + 3, vertices_top + 6);
+ }
+
+ {
+ /* Prepare initial triangle on the bottom of the icosahedron. */
+ double rot_mat[3][3];
+ double tmp_vec[3];
+
+ vertices_bot[0] = 0.0;
+ vertices_bot[1] = 0.0;
+ vertices_bot[2] = -radius;
+
+ t8_mat_init_yrot (rot_mat, -alpha);
+ t8_mat_mult_vec (rot_mat, vertices_bot + 0, tmp_vec);
+
+ t8_mat_init_zrot (rot_mat, 0.5 * 2.0 / 5.0 * M_PI);
+ t8_mat_mult_vec (rot_mat, tmp_vec, vertices_bot + 3);
+
+ t8_mat_init_zrot (rot_mat, 2.0 / 5.0 * M_PI);
+ t8_mat_mult_vec (rot_mat, vertices_bot + 3, vertices_bot + 6);
+ }
+
+ /* Create the cmesh in 5 bands of 4 triangles.
+ * Rotate the initial top and bottom triangle around the z axis.
+ * The two triangles on the "belly" that are connecting the top and bottom triangle share vertices
+ * with the top and bottom triangle, so we can construct them in one go as well.
+ */
+ int itree = -1;
+ for (int turn = 0; turn < 5; turn++) {
+ double rot_mat[3][3];
+ double rot_vertices_top[4 * 3];
+ double rot_vertices_bot[4 * 3];
+
+ double belly_top[3 * 3];
+ double belly_bot[3 * 3];
+
+ t8_mat_init_zrot (rot_mat, turn * 2.0 / 5.0 * M_PI);
+
+ for (int ivert = 0; ivert < nverts; ivert++) {
+ t8_mat_mult_vec (rot_mat, vertices_top + 3 * ivert, rot_vertices_top + 3 * ivert);
+ t8_mat_mult_vec (rot_mat, vertices_bot + 3 * ivert, rot_vertices_bot + 3 * ivert);
+ }
+
+ for (int ivert = 0; ivert < 2; ivert++) {
+ for (int icoord = 0; icoord < T8_ECLASS_MAX_DIM; icoord++) {
+ belly_top[3 * ivert + icoord] = rot_vertices_top[3 * (ivert + 1) + icoord];
+ belly_bot[3 * ivert + icoord] = rot_vertices_bot[3 * (ivert + 1) + icoord];
+ }
+ }
+
+ for (int icoord = 0; icoord < T8_ECLASS_MAX_DIM; icoord++) {
+ belly_top[6 + icoord] = rot_vertices_bot[3 * 1 + icoord];
+ belly_bot[6 + icoord] = rot_vertices_top[3 * 2 + icoord];
+ }
+
+ /* Set the tree vertices and gather all vertices, so that the facejoins can in the end be deduced from global vertices */
+ t8_cmesh_set_tree_vertices (cmesh, ++itree, rot_vertices_top, 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_top[3 * ivert + icoord];
+ }
+ }
+
+ t8_cmesh_set_tree_vertices (cmesh, ++itree, belly_top, 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)]
+ = belly_top[3 * ivert + icoord];
+ }
+ }
+
+ t8_cmesh_set_tree_vertices (cmesh, ++itree, belly_bot, 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)]
+ = belly_bot[3 * ivert + icoord];
+ }
+ }
+
+ t8_cmesh_set_tree_vertices (cmesh, ++itree, rot_vertices_bot, 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_bot[3 * ivert + icoord];
+ }
+ }
+ }
+
+ /* 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)
{
@@ -2934,37 +3071,20 @@ t8_cmesh_new_quadrangulated_spherical_surface (const double radius, sc_MPI_Comm
return cmesh;
}
-t8_cmesh_t
-t8_cmesh_new_cubed_spherical_shell (const double inner_radius, const double shell_thickness, const int num_levels,
- const int num_layers, sc_MPI_Comm comm)
+typedef t8_cmesh_t (t8_inner_sphere_creator_t) (const double inner_radius, sc_MPI_Comm comm);
+
+static t8_cmesh_t
+t8_cmesh_new_spherical_shell (t8_eclass_t eclass, t8_geometry_c *geometry,
+ t8_inner_sphere_creator_t inner_sphere_creator, const double inner_radius,
+ const double shell_thickness, const int num_levels, const int num_layers,
+ sc_MPI_Comm comm)
{
/* Initialization of the mesh */
t8_cmesh_t cmesh;
t8_cmesh_init (&cmesh);
- t8_geometry_c *geometry = t8_geometry_cubed_spherical_shell_new ();
t8_cmesh_register_geometry (cmesh, geometry);
- /* Square root of three. */
- const double SQRT3 = 1.7320508075688772;
-
- const int two_to_nl = 1 << num_levels; /* 2^num_levels */
-
- /* clang-format off */
- const int ntrees = t8_eclass_num_faces[T8_ECLASS_HEX] * two_to_nl * two_to_nl * num_layers; /* Number of cmesh cells. */
- const int nverts = t8_eclass_num_vertices[T8_ECLASS_HEX]; /* Number of vertices per cmesh cell. */
-
- /* 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);
- /* clang-format on */
-
- /* 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;
- }
-
/* Here is what we do: Construct a 3D cmesh from a 2D forest. */
int mpi_rank;
@@ -2976,49 +3096,78 @@ t8_cmesh_new_cubed_spherical_shell (const double inner_radius, const double shel
sc_MPI_Comm_split (comm, mpi_rank, mpi_rank, &local_comm);
/* Create 2D quadrangulated spherical surface of given refinement level per patch. */
- t8_forest_t forest = t8_forest_new_uniform (t8_cmesh_new_quadrangulated_spherical_surface (inner_radius, local_comm),
+ t8_forest_t forest = t8_forest_new_uniform (inner_sphere_creator (inner_radius, local_comm),
t8_scheme_new_default_cxx (), num_levels, 0, local_comm);
- /* Get the number of trees that have elements of this process. */
- t8_locidx_t num_local_trees = t8_forest_get_num_local_trees (forest);
+ /* clang-format off */
+ const int ntrees = t8_forest_get_local_num_elements (forest) * num_layers; /* Number of 3D cmesh elements resp. trees. */
+ const int nverts = t8_eclass_num_vertices[eclass]; /* 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);
+ /* clang-format on */
+
+ /* Defitition of the tree class. */
+ for (int itree = 0; itree < ntrees; itree++) {
+ t8_cmesh_set_tree_class (cmesh, itree, eclass);
+ all_eclasses[itree] = eclass;
+ }
/* Tree index of the to-be-created 3D cmesh. */
int itree = 0;
/* Loop over all local trees in the forest. */
- for (t8_locidx_t itree_quad = 0, current_index = 0; itree_quad < num_local_trees; ++itree_quad) {
+ for (t8_locidx_t itree_local = 0; itree_local < t8_forest_get_num_local_trees (forest); ++itree_local) {
/* Get the number of elements of this tree. */
- const t8_locidx_t num_elements_in_tree = t8_forest_get_tree_num_elements (forest, itree_quad);
+ const t8_locidx_t num_elements_in_tree = t8_forest_get_tree_num_elements (forest, itree_local);
+
+ /* Element class scheme of the current tree. */
+ t8_eclass_t eclass_2d = t8_forest_get_eclass (forest, itree_local);
/* Loop over all local elements in the tree. */
- for (t8_locidx_t ielement = 0; ielement < num_elements_in_tree; ++ielement, ++current_index) {
- const t8_element_t *element = t8_forest_get_element_in_tree (forest, itree_quad, ielement);
+ for (t8_locidx_t ielement = 0; ielement < num_elements_in_tree; ++ielement) {
+ const t8_element_t *element = t8_forest_get_element_in_tree (forest, itree_local, ielement);
/* Retrieve 2D element vertices. */
- double quad_vertices[4 * 3];
- for (int ivert = 0; ivert < 4; ivert++) {
- t8_forest_element_coordinate (forest, itree_quad, element, ivert, quad_vertices + ivert * 3);
+ double elem_vertices_2d[T8_ECLASS_MAX_CORNERS * 3];
+ for (int ivert = 0; ivert < t8_eclass_num_vertices[eclass_2d]; ivert++) {
+ t8_forest_element_coordinate (forest, itree_local, element, ivert, elem_vertices_2d + ivert * 3);
}
- /* Transfer the coordinates from the 2D forest mesh to the 2D cmesh and stack hexes along radial direction. */
+ {
+ /* Here, we check if the face normal vector of the 2D element points
+ * outward with respect to the sphere's center. If not, the node ordering is flipped.
+ * Note, this works for triangles and quads.
+ */
+ double normal[3];
+ t8_vec_tri_normal (elem_vertices_2d, elem_vertices_2d + 3, elem_vertices_2d + 6, normal);
+
+ if (t8_vec_dot (elem_vertices_2d, normal) < 0.0) {
+ t8_vec_swap (elem_vertices_2d + 3, elem_vertices_2d + 6);
+ }
+ }
+
+ /* Transfer the coordinates from the 2D forest mesh to the cmesh via stacking 3D elements along radial direction. */
for (int istack = 0; istack < num_layers; istack++) {
- const double iscale = 1.0 + istack * shell_thickness / inner_radius / num_layers / SQRT3;
- const double oscale = 1.0 + (istack + 1) * shell_thickness / inner_radius / num_layers / SQRT3;
+ const double iscale = 1.0 + istack * shell_thickness / inner_radius / num_layers;
+ const double oscale = 1.0 + (istack + 1) * shell_thickness / inner_radius / num_layers;
- double hex_vertices[8 * 3];
- for (int ivert = 0; ivert < 4; ivert++) {
+ double elem_vertices_3d[T8_ECLASS_MAX_CORNERS * 3];
+ for (int ivert = 0; ivert < t8_eclass_num_vertices[eclass_2d]; ivert++) {
for (int i = 0; i < 3; i++) {
- hex_vertices[0 + ivert * 3 + i] = iscale * quad_vertices[ivert * 3 + i];
- hex_vertices[4 * 3 + ivert * 3 + i] = oscale * quad_vertices[ivert * 3 + i];
+ elem_vertices_3d[ivert * 3 + i] = iscale * elem_vertices_2d[ivert * 3 + i];
+ elem_vertices_3d[t8_eclass_num_vertices[eclass] / 2 * 3 + ivert * 3 + i]
+ = oscale * elem_vertices_2d[ivert * 3 + i];
}
}
- t8_cmesh_set_tree_vertices (cmesh, itree, hex_vertices, nverts);
+ t8_cmesh_set_tree_vertices (cmesh, itree, elem_vertices_3d, 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)]
- = hex_vertices[ivert * 3 + icoord];
+ = elem_vertices_3d[ivert * 3 + icoord];
}
}
@@ -3043,3 +3192,30 @@ t8_cmesh_new_cubed_spherical_shell (const double inner_radius, const double shel
return cmesh;
}
+
+t8_cmesh_t
+t8_cmesh_new_prismed_spherical_shell_icosahedron (const double inner_radius, const double shell_thickness,
+ const int num_levels, const int num_layers, sc_MPI_Comm comm)
+{
+ return t8_cmesh_new_spherical_shell (T8_ECLASS_PRISM, t8_geometry_prismed_spherical_shell_new (),
+ t8_cmesh_new_triangulated_spherical_surface_icosahedron, inner_radius,
+ shell_thickness, num_levels, num_layers, comm);
+}
+
+t8_cmesh_t
+t8_cmesh_new_prismed_spherical_shell_octahedron (const double inner_radius, const double shell_thickness,
+ const int num_levels, const int num_layers, sc_MPI_Comm comm)
+{
+ return t8_cmesh_new_spherical_shell (T8_ECLASS_PRISM, t8_geometry_prismed_spherical_shell_new (),
+ t8_cmesh_new_triangulated_spherical_surface_octahedron, inner_radius,
+ shell_thickness, num_levels, num_layers, comm);
+}
+
+t8_cmesh_t
+t8_cmesh_new_cubed_spherical_shell (const double inner_radius, const double shell_thickness, const int num_levels,
+ const int num_layers, sc_MPI_Comm comm)
+{
+ return t8_cmesh_new_spherical_shell (T8_ECLASS_HEX, t8_geometry_cubed_spherical_shell_new (),
+ t8_cmesh_new_quadrangulated_spherical_surface, inner_radius, shell_thickness,
+ num_levels, num_layers, comm);
+}
diff --git a/src/t8_cmesh/t8_cmesh_examples.h b/src/t8_cmesh/t8_cmesh_examples.h
index 51d737841d..13d5f11077 100644
--- a/src/t8_cmesh/t8_cmesh_examples.h
+++ b/src/t8_cmesh/t8_cmesh_examples.h
@@ -131,7 +131,7 @@ t8_cmesh_new_hypercube (t8_eclass_t eclass, sc_MPI_Comm comm, int do_bcast, int
*/
t8_cmesh_t
t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const double *boundary, t8_locidx_t polygons_x,
- t8_locidx_t polygons_y, t8_locidx_t polygons_z, const t8_geometry_c *geometry);
+ t8_locidx_t polygons_y, t8_locidx_t polygons_z, const int use_axis_aligned);
/** Hybercube with 6 Tets, 6 Prism, 4 Hex.
* \param [in] comm The mpi communicator to be used.
@@ -321,13 +321,21 @@ t8_cmesh_new_row_of_cubes (t8_locidx_t num_trees, const int set_attributes, cons
t8_cmesh_t
t8_cmesh_new_squared_disk (const double radius, sc_MPI_Comm comm);
-/** Construct a triangulated spherical surface of given radius.
+/** Construct a triangulated spherical surface of given radius: octahedron 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 (const double radius, sc_MPI_Comm comm);
+t8_cmesh_new_triangulated_spherical_surface_octahedron (const double radius, sc_MPI_Comm comm);
+
+/** Construct a triangulated spherical surface of given radius: icosahedron 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_icosahedron (const double radius, sc_MPI_Comm comm);
/** Construct a quadrangulated spherical surface of given radius.
* \param [in] radius Radius of the sphere.
@@ -337,6 +345,30 @@ t8_cmesh_new_triangulated_spherical_surface (const double radius, sc_MPI_Comm co
t8_cmesh_t
t8_cmesh_new_quadrangulated_spherical_surface (const double radius, sc_MPI_Comm comm);
+/** Construct a spherical shell discretized by prisms of given inner radius and thickness: octahedron version.
+ * \param [in] inner_radius Radius of the inner side of the shell.
+ * \param [in] shell_thickness Thickness of the shell.
+ * \param [in] num_levels Refinement level 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_prismed_spherical_shell_octahedron (const double inner_radius, const double shell_thickness,
+ const int num_levels, const int num_layers, sc_MPI_Comm comm);
+
+/** Construct a spherical shell discretized by prisms of given inner radius and thickness: icosahedron version.
+ * \param [in] inner_radius Radius of the inner side of the shell.
+ * \param [in] shell_thickness Thickness of the shell.
+ * \param [in] num_levels Refinement level 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_prismed_spherical_shell_icosahedron (const double inner_radius, const double shell_thickness,
+ const int num_levels, const int num_layers, sc_MPI_Comm comm);
+
/** 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.
diff --git a/src/t8_cmesh/t8_cmesh_readmshfile.cxx b/src/t8_cmesh/t8_cmesh_readmshfile.cxx
index c0cc748547..d0ad3522f4 100644
--- a/src/t8_cmesh/t8_cmesh_readmshfile.cxx
+++ b/src/t8_cmesh/t8_cmesh_readmshfile.cxx
@@ -23,8 +23,8 @@
#include
#include
#include
-#include
-#include
+#include
+#include
#include "t8_cmesh_types.h"
#include "t8_cmesh_stash.h"
@@ -696,25 +696,25 @@ t8_cmesh_msh_file_2_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
* \param [in] geometry_index The index of the geometry.
* \param [in] num_face_nodes The number of the nodes of the surface.
* NULL if the geometry is an edge.
- * \param [in] geometry_occ The occ_geometry.
+ * \param [in] geometry_cad The cad_geometry.
* \param [in,out] parameters The parameters to be corrected.
*/
static void
t8_cmesh_correct_parameters_on_closed_geometry (const int geometry_dim, const int geometry_index,
- const int num_face_nodes, const t8_geometry_occ_c *geometry_occ,
+ const int num_face_nodes, const t8_geometry_cad_c *geometry_cad,
double *parameters)
{
switch (geometry_dim) {
/* Check for closed U parameter in case of an edge. */
case 1:
/* Only correct the U parameter if the edge is closed. */
- if (geometry_occ->t8_geom_is_edge_closed (geometry_index)) {
+ if (geometry_cad->t8_geom_is_edge_closed (geometry_index)) {
/* Get the parametric bounds of the closed geometry
* edge -> [Umin, Umax]
*/
double parametric_bounds[2];
/* Get the parametric edge bounds. */
- geometry_occ->t8_geom_get_edge_parametric_bounds (geometry_index, parametric_bounds);
+ geometry_cad->t8_geom_get_edge_parametric_bounds (geometry_index, parametric_bounds);
/* Check the upper an the lower parametric bound. */
for (int bound = 0; bound < 2; ++bound) {
/* Iterate over both nodes of the edge. */
@@ -746,12 +746,12 @@ t8_cmesh_correct_parameters_on_closed_geometry (const int geometry_dim, const in
/* Iterate over both parameters. 0 stands for the U parameter an 1 for the V parameter. */
for (int param_dim = 0; param_dim < 2; ++param_dim) {
/* Only correct the surface parameters if they are closed */
- if (geometry_occ->t8_geom_is_surface_closed (geometry_index, param_dim)) {
+ if (geometry_cad->t8_geom_is_surface_closed (geometry_index, param_dim)) {
/* Get the parametric bounds of the closed geometry
* surface -> [Umin, Umax, Vmin, Vmax]
*/
double parametric_bounds[4];
- geometry_occ->t8_geom_get_face_parametric_bounds (geometry_index, parametric_bounds);
+ geometry_cad->t8_geom_get_face_parametric_bounds (geometry_index, parametric_bounds);
/* Check the upper an the lower parametric bound. */
for (int bound = 0; bound < 2; ++bound) {
/* Iterate over every corner node of the tree. */
@@ -797,13 +797,13 @@ t8_cmesh_correct_parameters_on_closed_geometry (const int geometry_dim, const in
* If vertex_indices is not NULL, it is allocated and will store
* for each tree the indices of its vertices.
* They are stored as arrays of long ints.
- * If occ geometry is used, the geometry is passed as a pointer here.
+ * If cad geometry is used, the geometry is passed as a pointer here.
* We cannot access this geometry over the cmesh interface since the cmesh
* is not committed yet. */
static int
t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices, sc_array_t **vertex_indices, int dim,
- const t8_geometry_c *linear_geometry_base, const int use_occ_geometry,
- const t8_geometry_c *occ_geometry_base)
+ const t8_geometry_c *linear_geometry_base, const int use_cad_geometry,
+ const t8_geometry_c *cad_geometry_base)
{
char *line = (char *) malloc (1024), *line_modify;
char first_word[2048] = "\0";
@@ -1003,9 +1003,9 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
*(long **) sc_array_push (*vertex_indices) = stored_indices;
}
- if (!use_occ_geometry) {
+ if (!use_cad_geometry) {
/* Set the geometry of the tree to be linear.
- * If we use an occ geometry, we set the geometry in accordance,
+ * If we use an cad geometry, we set the geometry in accordance,
* if the tree is linked to a geometry or not */
const char *geom_name = linear_geometry_base->t8_geom_get_name ();
t8_cmesh_set_tree_geometry (cmesh, tree_count, geom_name);
@@ -1013,11 +1013,11 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
else {
/* Calculate the parametric geometries of the tree */
#if T8_WITH_OCC
- T8_ASSERT (occ_geometry_base->t8_geom_get_type () == T8_GEOMETRY_TYPE_OCC);
- const t8_geometry_occ_c *occ_geometry = dynamic_cast (occ_geometry_base);
+ T8_ASSERT (cad_geometry_base->t8_geom_get_type () == T8_GEOMETRY_TYPE_CAD);
+ const t8_geometry_cad_c *cad_geometry = dynamic_cast (cad_geometry_base);
/* Check for right element class */
if (eclass != T8_ECLASS_TRIANGLE && eclass != T8_ECLASS_QUAD && eclass != T8_ECLASS_HEX) {
- t8_errorf ("%s element detected. The occ geometry currently only supports quad, tri and hex elements.",
+ t8_errorf ("%s element detected. The cad geometry currently only supports quad, tri and hex elements.",
t8_eclass_to_string[eclass]);
goto die_ele;
}
@@ -1025,7 +1025,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
double parameters[T8_ECLASS_MAX_CORNERS_2D * 2];
int edge_geometries[T8_ECLASS_MAX_EDGES * 2] = { 0 };
int face_geometries[T8_ECLASS_MAX_FACES] = { 0 };
- /* We look at each face to check, if it is linked to a occ surface */
+ /* We look at each face to check, if it is linked to a cad surface */
T8_ASSERT (t8_eclass_to_dimension[eclass] == dim);
int num_faces;
switch (dim) {
@@ -1060,7 +1060,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
}
}
- /* A face can only be linked to an occ surface if all nodes of the face are parametric or on a vertex
+ /* A face can only be linked to an cad surface if all nodes of the face are parametric or on a vertex
* (gmsh labels nodes on vertices as not parametric) */
int all_parametric = 1;
for (int i_face_nodes = 0; i_face_nodes < num_face_nodes; ++i_face_nodes) {
@@ -1113,7 +1113,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
/* If both nodes are on a vertex we look if both vertices share an edge */
if (node1.entity_dim == 0 && node2.entity_dim == 0) {
- int common_edge = occ_geometry->t8_geom_get_common_edge (node1.entity_tag, node2.entity_tag);
+ int common_edge = cad_geometry->t8_geom_get_common_edge (node1.entity_tag, node2.entity_tag);
if (common_edge > 0) {
if (edge1_index == 0) {
edge1_index = common_edge;
@@ -1127,7 +1127,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
}
}
if (edge2_index > 0) {
- surface_index = occ_geometry->t8_geom_get_common_face (edge1_index, edge2_index);
+ surface_index = cad_geometry->t8_geom_get_common_face (edge1_index, edge2_index);
}
else {
continue;
@@ -1148,8 +1148,8 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
else {
/* If it is on another geometry we retrieve its parameters */
if (face_nodes[i_face_nodes].entity_dim == 0) {
- if (occ_geometry->t8_geom_is_vertex_on_face (face_nodes[i_face_nodes].entity_tag, surface_index)) {
- occ_geometry->t8_geom_get_parameters_of_vertex_on_face (
+ if (cad_geometry->t8_geom_is_vertex_on_face (face_nodes[i_face_nodes].entity_tag, surface_index)) {
+ cad_geometry->t8_geom_get_parameters_of_vertex_on_face (
face_nodes[i_face_nodes].entity_tag, surface_index, face_nodes[i_face_nodes].parameters);
face_nodes[i_face_nodes].entity_dim = 2;
}
@@ -1159,8 +1159,8 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
}
}
if (face_nodes[i_face_nodes].entity_dim == 1) {
- if (occ_geometry->t8_geom_is_edge_on_face (face_nodes[i_face_nodes].entity_tag, surface_index)) {
- occ_geometry->t8_geom_edge_parameter_to_face_parameters (
+ if (cad_geometry->t8_geom_is_edge_on_face (face_nodes[i_face_nodes].entity_tag, surface_index)) {
+ cad_geometry->t8_geom_edge_parameter_to_face_parameters (
face_nodes[i_face_nodes].entity_tag, surface_index, num_face_nodes,
face_nodes[i_face_nodes].parameters[0], NULL, face_nodes[i_face_nodes].parameters);
face_nodes[i_face_nodes].entity_dim = 2;
@@ -1173,7 +1173,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
}
}
/* Abort if not all nodes are on the surface or if the surface is a plane */
- if (!all_nodes_on_surface || occ_geometry->t8_geom_is_plane (surface_index)) {
+ if (!all_nodes_on_surface || cad_geometry->t8_geom_is_plane (surface_index)) {
continue;
}
/* If we have found a surface we link it to the face */
@@ -1200,14 +1200,14 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
}
/* Corrects the parameters on the surface if it is closed to prevent disorted elements. */
for (int param_dim = 0; param_dim < 2; ++param_dim) {
- if (occ_geometry->t8_geom_is_surface_closed (surface_index, param_dim)) {
- t8_cmesh_correct_parameters_on_closed_geometry (2, surface_index, num_face_nodes, occ_geometry,
+ if (cad_geometry->t8_geom_is_surface_closed (surface_index, param_dim)) {
+ t8_cmesh_correct_parameters_on_closed_geometry (2, surface_index, num_face_nodes, cad_geometry,
parameters);
}
}
t8_cmesh_set_attribute (cmesh, tree_count, t8_get_package_id (),
- T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + i_tree_faces, parameters,
+ T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + i_tree_faces, parameters,
num_face_nodes * 2 * sizeof (double), 0);
}
}
@@ -1256,19 +1256,19 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
int is_on_geom = 1;
for (int i_edge = 0; i_edge < 2; ++i_edge) {
if (edge_geometry_dim == 2 && edge_nodes[i_edge].entity_dim == 1) {
- if (!occ_geometry->t8_geom_is_edge_on_face (edge_nodes[i_edge].entity_tag, edge_geometry_tag)) {
+ if (!cad_geometry->t8_geom_is_edge_on_face (edge_nodes[i_edge].entity_tag, edge_geometry_tag)) {
is_on_geom = 0;
break;
}
}
else if (edge_geometry_dim == 2 && edge_nodes[i_edge].entity_dim == 0) {
- if (!occ_geometry->t8_geom_is_vertex_on_face (edge_nodes[i_edge].entity_tag, edge_geometry_tag)) {
+ if (!cad_geometry->t8_geom_is_vertex_on_face (edge_nodes[i_edge].entity_tag, edge_geometry_tag)) {
is_on_geom = 0;
break;
}
}
else if (edge_geometry_dim == 1 && edge_nodes[i_edge].entity_dim == 0) {
- if (!occ_geometry->t8_geom_is_vertex_on_edge (edge_nodes[i_edge].entity_tag, edge_geometry_tag)) {
+ if (!cad_geometry->t8_geom_is_vertex_on_edge (edge_nodes[i_edge].entity_tag, edge_geometry_tag)) {
is_on_geom = 0;
break;
}
@@ -1284,7 +1284,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
* If not we can skip this edge. */
if (edge_geometry_dim == 0 && edge_geometry_tag == 0) {
int common_curve
- = occ_geometry->t8_geom_get_common_edge (edge_nodes[0].entity_tag, edge_nodes[1].entity_tag);
+ = cad_geometry->t8_geom_get_common_edge (edge_nodes[0].entity_tag, edge_nodes[1].entity_tag);
if (common_curve > 0) {
edge_geometry_tag = common_curve;
edge_geometry_dim = 1;
@@ -1298,7 +1298,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
if (edge_nodes[0].entity_dim == 1 && edge_nodes[1].entity_dim == 1
&& edge_nodes[0].entity_tag != edge_nodes[1].entity_tag) {
int common_surface
- = occ_geometry->t8_geom_get_common_face (edge_nodes[0].entity_tag, edge_nodes[1].entity_tag);
+ = cad_geometry->t8_geom_get_common_face (edge_nodes[0].entity_tag, edge_nodes[1].entity_tag);
if (common_surface > 0) {
edge_geometry_tag = common_surface;
edge_geometry_dim = 2;
@@ -1312,7 +1312,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
/* Check if adjacent faces carry a surface and if this edge lies on the surface */
for (int i_adjacent_face = 0; i_adjacent_face < 2; ++i_adjacent_face) {
if (face_geometries[t8_edge_to_face[eclass][i_tree_edges][i_adjacent_face]] > 0) {
- if (!occ_geometry->t8_geom_is_edge_on_face (
+ if (!cad_geometry->t8_geom_is_edge_on_face (
edge_geometry_tag, face_geometries[t8_edge_to_face[eclass][i_tree_edges][i_adjacent_face]])) {
t8_global_errorf ("Error: Adjacent edge and face of a tree carry "
"incompatible geometries.\n");
@@ -1336,7 +1336,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
goto die_ele;
}
if (edge_nodes[i_edge_node].entity_dim == 0) {
- if (!occ_geometry->t8_geom_is_vertex_on_edge (edge_nodes[i_edge_node].entity_tag,
+ if (!cad_geometry->t8_geom_is_vertex_on_edge (edge_nodes[i_edge_node].entity_tag,
edge_geometry_tag)) {
t8_global_errorf ("Error: Node %i should lie on a vertex which lies on an edge, "
"but the vertex does not lie on that edge.\n",
@@ -1347,14 +1347,14 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
/* If the node lies on a vertex we retrieve its parameter on the curve */
if (edge_nodes[i_edge_node].entity_dim == 0) {
- occ_geometry->t8_geom_get_parameter_of_vertex_on_edge (
+ cad_geometry->t8_geom_get_parameter_of_vertex_on_edge (
edge_nodes[i_edge_node].entity_tag, edge_geometry_tag, edge_nodes[i_edge_node].parameters);
edge_nodes[i_edge_node].entity_dim = 1;
}
}
/* Abort if the edge is a line */
- if (occ_geometry->t8_geom_is_line (edge_geometry_tag)) {
+ if (cad_geometry->t8_geom_is_line (edge_geometry_tag)) {
continue;
}
@@ -1364,12 +1364,12 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
parameters[1] = edge_nodes[1].parameters[0];
/* Corrects the parameters on the edge if it is closed to prevent disorted elements. */
- if (occ_geometry->t8_geom_is_edge_closed (edge_geometry_tag)) {
- t8_cmesh_correct_parameters_on_closed_geometry (1, edge_geometry_tag, 2, occ_geometry, parameters);
+ if (cad_geometry->t8_geom_is_edge_closed (edge_geometry_tag)) {
+ t8_cmesh_correct_parameters_on_closed_geometry (1, edge_geometry_tag, 2, cad_geometry, parameters);
}
t8_cmesh_set_attribute (cmesh, tree_count, t8_get_package_id (),
- T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_tree_edges, parameters,
+ T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_tree_edges, parameters,
2 * sizeof (double), 0);
}
/* If we have found a surface we can look for the parameters.
@@ -1385,7 +1385,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
goto die_ele;
}
if (edge_nodes[i_edge_node].entity_dim == 0) {
- if (!occ_geometry->t8_geom_is_vertex_on_face (edge_nodes[i_edge_node].entity_tag,
+ if (!cad_geometry->t8_geom_is_vertex_on_face (edge_nodes[i_edge_node].entity_tag,
edge_geometry_tag)) {
t8_global_errorf ("Error: Node %i should lie on a vertex which lies on a face, "
"but the vertex does not lie on that face.\n",
@@ -1394,7 +1394,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
}
}
if (edge_nodes[i_edge_node].entity_dim == 1) {
- if (!occ_geometry->t8_geom_is_edge_on_face (edge_nodes[i_edge_node].entity_tag, edge_geometry_tag)) {
+ if (!cad_geometry->t8_geom_is_edge_on_face (edge_nodes[i_edge_node].entity_tag, edge_geometry_tag)) {
t8_global_errorf ("Error: Node %i should lie on an edge which lies on a face, "
"but the edge does not lie on that face.\n",
edge_nodes[i_edge_node].index);
@@ -1404,14 +1404,14 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
/* If the node lies on a vertex we retrieve its parameters on the surface */
if (edge_nodes[i_edge_node].entity_dim == 0) {
- occ_geometry->t8_geom_get_parameters_of_vertex_on_face (
+ cad_geometry->t8_geom_get_parameters_of_vertex_on_face (
edge_nodes[i_edge_node].entity_tag, edge_geometry_tag, edge_nodes[i_edge_node].parameters);
edge_nodes[i_edge_node].entity_dim = 2;
}
/* If the node lies on an edge we have to do the same */
if (edge_nodes[i_edge_node].entity_dim == 1) {
const int num_face_nodes = t8_eclass_num_vertices[eclass];
- occ_geometry->t8_geom_edge_parameter_to_face_parameters (
+ cad_geometry->t8_geom_edge_parameter_to_face_parameters (
edge_nodes[i_edge_node].entity_tag, edge_geometry_tag, num_face_nodes,
edge_nodes[i_edge_node].parameters[0], parameters, edge_nodes[i_edge_node].parameters);
edge_nodes[i_edge_node].entity_dim = 2;
@@ -1419,7 +1419,7 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
}
/* Abort if the edge is a line */
- if (occ_geometry->t8_geom_is_line (edge_geometry_tag)) {
+ if (cad_geometry->t8_geom_is_line (edge_geometry_tag)) {
continue;
}
@@ -1432,13 +1432,13 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
/* Corrects the parameters on the surface if it is closed to prevent disorted elements. */
for (int param_dim = 0; param_dim < 2; ++param_dim) {
- if (occ_geometry->t8_geom_is_surface_closed (edge_geometry_tag, param_dim)) {
- t8_cmesh_correct_parameters_on_closed_geometry (2, edge_geometry_tag, 2, occ_geometry, parameters);
+ if (cad_geometry->t8_geom_is_surface_closed (edge_geometry_tag, param_dim)) {
+ t8_cmesh_correct_parameters_on_closed_geometry (2, edge_geometry_tag, 2, cad_geometry, parameters);
}
}
t8_cmesh_set_attribute (cmesh, tree_count, t8_get_package_id (),
- T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_tree_edges, parameters,
+ T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_tree_edges, parameters,
4 * sizeof (double), 0);
}
}
@@ -1448,15 +1448,15 @@ t8_cmesh_msh_file_4_read_eles (t8_cmesh_t cmesh, FILE *fp, sc_hash_t *vertices,
edge_geometries[i_edge] = 0;
}
}
- t8_cmesh_set_attribute (cmesh, tree_count, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY,
+ t8_cmesh_set_attribute (cmesh, tree_count, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY,
face_geometries, num_faces * sizeof (int), 0);
- t8_cmesh_set_attribute (cmesh, tree_count, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY,
+ t8_cmesh_set_attribute (cmesh, tree_count, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY,
edge_geometries, 2 * num_edges * sizeof (int), 0);
/* Now we set the tree geometry according to the tree linkage status. */
const char *geom_name;
if (tree_is_linked) {
- geom_name = occ_geometry_base->t8_geom_get_name ();
+ geom_name = cad_geometry_base->t8_geom_get_name ();
}
else {
geom_name = linear_geometry_base->t8_geom_get_name ();
@@ -1725,28 +1725,28 @@ T8_EXTERN_C_BEGIN ();
/* This is a helper function to properly register the
* geometries for the cmesh created in t8_cmesh_from_msh_file.
* It should be called by all processes of the cmesh.
- * Returns 1 on success, 0 on OCC usage error: use_occ_geometry true, but occ not linked.
+ * Returns 1 on success, 0 on cad usage error: use_cad_geometry true, but OCC not linked.
* The linear_geometry pointer will point to the newly created linear geometry.
- * The occ_geometry pointer will point to the newly created occ geometry, or to NULL if
- * no occ geometry is used.
+ * The cad_geometry pointer will point to the newly created cad geometry, or to NULL if
+ * no cad geometry is used.
*/
static int
-t8_cmesh_from_msh_file_register_geometries (t8_cmesh_t cmesh, const int use_occ_geometry, const int dim,
+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 **occ_geometry)
+ const t8_geometry_c **cad_geometry)
{
const t8_geometry_c *linear_geom = new t8_geometry_linear (dim);
/* Register linear geometry */
t8_cmesh_register_geometry (cmesh, linear_geom);
*linear_geometry = linear_geom;
- if (use_occ_geometry) {
+ if (use_cad_geometry) {
#if T8_WITH_OCC
- const t8_geometry_c *occ_geom = t8_geometry_occ_new (dim, fileprefix, "brep_geometry");
- t8_cmesh_register_geometry (cmesh, occ_geom);
- *occ_geometry = occ_geom;
+ const t8_geometry_c *cad_geom = t8_geometry_cad_new (dim, fileprefix, "brep_geometry");
+ t8_cmesh_register_geometry (cmesh, cad_geom);
+ *cad_geometry = cad_geom;
#else /* !T8_WITH_OCC */
- *occ_geometry = NULL;
+ *cad_geometry = NULL;
return 0;
#endif
}
@@ -1755,7 +1755,7 @@ t8_cmesh_from_msh_file_register_geometries (t8_cmesh_t cmesh, const int use_occ_
t8_cmesh_t
t8_cmesh_from_msh_file (const char *fileprefix, int partition, sc_MPI_Comm comm, int dim, int main_proc,
- int use_occ_geometry)
+ int use_cad_geometry)
{
int mpirank, mpisize, mpiret;
t8_cmesh_t cmesh;
@@ -1769,7 +1769,7 @@ t8_cmesh_from_msh_file (const char *fileprefix, int partition, sc_MPI_Comm comm,
t8_gloidx_t num_trees, first_tree, last_tree = -1;
int main_proc_read_successful = 0;
int msh_version;
- const t8_geometry_c *occ_geometry = NULL;
+ const t8_geometry_c *cad_geometry = NULL;
const t8_geometry_c *linear_geometry = NULL;
mpiret = sc_MPI_Comm_size (comm, &mpisize);
@@ -1791,10 +1791,10 @@ t8_cmesh_from_msh_file (const char *fileprefix, int partition, sc_MPI_Comm comm,
/* Register the geometries for the cmesh. */
const int registered_geom_success = t8_cmesh_from_msh_file_register_geometries (
- cmesh, use_occ_geometry, dim, fileprefix, &linear_geometry, &occ_geometry);
+ cmesh, use_cad_geometry, dim, fileprefix, &linear_geometry, &cad_geometry);
if (!registered_geom_success) {
/* Registering failed */
- t8_errorf ("OCC is not linked. Cannot use OCC geometry.\n");
+ t8_errorf ("cad is not linked. Cannot use cad geometry.\n");
t8_cmesh_destroy (&cmesh);
return NULL;
}
@@ -1833,9 +1833,9 @@ t8_cmesh_from_msh_file (const char *fileprefix, int partition, sc_MPI_Comm comm,
/* read nodes from the file */
switch (msh_version) {
case 2:
- if (use_occ_geometry) {
+ if (use_cad_geometry) {
fclose (file);
- t8_errorf ("WARNING: The occ geometry is only supported for msh files of version 4\n");
+ t8_errorf ("WARNING: The cad geometry is only supported for msh files of version 4\n");
t8_cmesh_destroy (&cmesh);
if (partition) {
/* Communicate to the other processes that reading failed. */
@@ -1850,8 +1850,8 @@ t8_cmesh_from_msh_file (const char *fileprefix, int partition, sc_MPI_Comm comm,
case 4:
vertices = t8_msh_file_4_read_nodes (file, &num_vertices, &node_mempool);
- t8_cmesh_msh_file_4_read_eles (cmesh, file, vertices, &vertex_indices, dim, linear_geometry, use_occ_geometry,
- occ_geometry);
+ t8_cmesh_msh_file_4_read_eles (cmesh, file, vertices, &vertex_indices, dim, linear_geometry, use_cad_geometry,
+ cad_geometry);
break;
default:
diff --git a/src/t8_cmesh/t8_cmesh_types.h b/src/t8_cmesh/t8_cmesh_types.h
index b391658b30..e412d52392 100644
--- a/src/t8_cmesh/t8_cmesh_types.h
+++ b/src/t8_cmesh/t8_cmesh_types.h
@@ -52,16 +52,299 @@ typedef struct t8_cprofile t8_cprofile_t; /* Defined below */
* T8_CMESH_NEXT_POSSIBLE_KEY is the first unused key, hence it can be repurposed for different attributes.*/
#define T8_CMESH_VERTICES_ATTRIBUTE_KEY 0 /* Used to store vertex coordinates. */
#define T8_CMESH_GEOMETRY_ATTRIBUTE_KEY 1 /* Used to store the name of a tree's geometry. */
-#define T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY 2 /* Used to store which edge is linked to which geometry */
-#define T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY 3 /* Used to store edge parameters */
-#define T8_CMESH_OCC_FACE_ATTRIBUTE_KEY \
- T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY \
+#define T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY 2 /* Used to store which edge is linked to which geometry */
+#define T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY 3 /* Used to store edge parameters */
+#define T8_CMESH_CAD_FACE_ATTRIBUTE_KEY \
+ T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY \
+T8_ECLASS_MAX_EDGES /* Used to store which face is linked to which surface */
-#define T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY \
- T8_CMESH_OCC_FACE_ATTRIBUTE_KEY + 1 /* Used to store face parameters */
+#define T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY \
+ T8_CMESH_CAD_FACE_ATTRIBUTE_KEY + 1 /* Used to store face parameters */
#define T8_CMESH_NEXT_POSSIBLE_KEY \
- T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY \
- +T8_ECLASS_MAX_FACES /* The next free value for a t8code attribute key */
+ T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + T8_ECLASS_MAX_FACES /* 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
+ * mesh, or partitioned. In the latter case, each process only stores a local
+ * portion of the mesh plus information about ghost elements.
+ *
+ * The coarse mesh is a collection of coarse trees that can be identified
+ * along faces.
+ * TODO: this description is outdated. rewrite it.
+ * The array ctrees stores these coarse trees sorted by their (global) tree_id.
+ * If the mesh if partitioned it is partitioned according to an (possible only
+ * virtually existing) underlying fine mesh. Therefore the ctrees array can
+ * store duplicated trees on different processes, if each of these processes
+ * owns elements of the same tree in the fine mesh.
+ *
+ * Each tree stores information about its face-neighbours in an array of
+ * \ref t8_ctree_fneighbor. \see t8_ctree_fneighbor
+ *
+ * If partitioned the ghost trees are stored in a hash table that is backed up
+ * by an array. The hash value of a ghost tree is its tree_id modulo the number
+ * of ghosts on this process.
+ */
+typedef struct t8_cmesh
+{
+ /* TODO: make the comments more legible */
+ int committed; /**< Flag that specifies whether the cmesh is committed or not. \ref t8_cmesh_commit */
+ int dimension; /**< The dimension of the cmesh. It is set when the first tree is inserted. */
+
+ int set_partition; /**< If nonzero the cmesh is partitioned.
+ If zero each process has the whole cmesh. */
+ int face_knowledge; /**< If partitioned the level of face knowledge that is expected. \ref t8_mesh_set_partitioned;
+ see \ref t8_cmesh_set_partition.
+*/
+
+ t8_scheme_cxx_t *set_partition_scheme; /**< If the cmesh is to be partitioned according to a uniform level,
+ the scheme that describes the refinement pattern. See \ref t8_cmesh_set_partition. */
+ int8_t set_partition_level; /**< Non-negative if the cmesh should be partitioned from an already existing cmesh
+ with an assumed \a level uniform mesh underneath. */
+ struct t8_cmesh *set_from; /**< If this cmesh shall be derived from an
+ existing cmesh by copy or more elaborate
+ modification, we store a pointer to this
+ other cmesh here. */
+ int mpirank; /**< Number of this MPI process. */
+ int mpisize; /**< Number of MPI processes. */
+ t8_refcount_t rc; /**< The reference count of the cmesh. */
+ t8_gloidx_t num_trees; /**< The global number of trees */
+ t8_locidx_t num_local_trees; /**< If partitioned the number of trees on this process.
+ Otherwise the global number of trees. */
+ t8_locidx_t num_ghosts; /**< If partitioned the number of neighbor trees
+ owned by different processes. */
+ /* TODO: wouldnt a local num_trees_per_eclass be better?
+ * only as an additional info. we need the global count. i.e. for forest_maxlevel computation.
+ */
+ t8_locidx_t num_local_trees_per_eclass[T8_ECLASS_COUNT]; /**< After commit the number of local
+ trees for each eclass.
+ Stores the same entries as \a num_trees_per_eclass,
+ if the cmesh is replicated. */
+ t8_gloidx_t num_trees_per_eclass[T8_ECLASS_COUNT]; /**< After commit the number of global
+ trees for each eclass. */
+
+ t8_cmesh_trees_t trees; /**< structure that holds all local trees and ghosts */
+
+ t8_gloidx_t first_tree; /**< The global index of the first local tree on this process.
+ Zero if the cmesh is not partitioned. -1 if this processor is empty.
+ See also https://github.com/DLR-AMR/t8code/wiki/Tree-indexing */
+ int8_t first_tree_shared; /**< If partitioned true if the first tree on this process is also the last tree
+ on the next process. Always zero if num_local_trees = 0 */
+
+ t8_shmem_array_t tree_offsets; /**< If partitioned for each process the global index of its first local tree
+ or -(first local tree) - 1
+ if the first tree on that process is shared.
+ Since this is very memory consuming we only fill it when needed. */
+
+ t8_geometry_handler_t *geometry_handler; /**< Handles all geometries that are used by trees in this cmesh. */
+
+#ifdef T8_ENABLE_DEBUG
+ t8_locidx_t inserted_trees; /**< Count the number of inserted trees to
+ check at commit if it equals the total number. */
+ t8_locidx_t inserted_ghosts; /**< Count the number of inserted ghosts to
+ check at commit if it equals the total number. */
+#endif
+ t8_stash_t stash; /**< Used as temporary storage for the trees before commit. */
+ t8_cprofile_t *profile; /**< Used to measure runtimes and statistics of the cmesh algorithms. */
+} t8_cmesh_struct_t;
+
+/* TODO: cghost could be the same type as ctree.
+ * treeid for ghosts then negative?!
+ * 1. typedef cghost ctree
+ * 2. completely replace
+ */
+/* TODO: document */
+typedef struct t8_cghost
+{
+ t8_gloidx_t treeid; /**< The global number of this ghost. */
+ t8_eclass_t eclass; /**< The eclass of this ghost. */
+ size_t neigh_offset; /** Offset to the array of face neighbors of this ghost.
+ This count has to be added to the address of the ghost to get its face neighbors. */
+ size_t att_offset; /**< Adding this offset to the address of the ghost
+ yields the array of attribute_info entries */
+ /* TODO: Could be a size_t */
+ int num_attributes; /**< The number of attributes at this ghost */
+} t8_cghost_struct_t;
+
+/** This structure holds the data of a local tree including the information
+ * about face neighbors. For those
+ * the tree_to_face index is computed as follows.
+ * Let F be the maximal number of faces of any eclass of the cmesh's dimension, then
+ * ttf % F is the face number and ttf / F is the orientation. (\ref t8_eclass_max_num_faces)
+ * The orientation is determined as follows. Let my_face and other_face
+ * be the two face numbers of the connecting trees.
+ * We chose a main_face from them as follows: Either both trees have the same
+ * element class, then the face with the lower face number is the main_face or
+ * the trees belong to different classes in which case the face belonging to the
+ * tree with the lower class according to the ordering
+ * triangle < square,
+ * hex < tet < prism < pyramid,
+ * is the main_face.
+ * Then face corner 0 of the main_face connects to a face
+ * corner k in the other face. The face orientation is defined as the number k.
+ * If the classes are equal and my_face == other_face, treating
+ * either of both faces as the main_face leads to the same result.
+ * See https://arxiv.org/pdf/1611.02929.pdf for more details.
+ */
+typedef struct t8_ctree
+{
+ t8_locidx_t treeid; /**< The local number of this tree. */
+ /* TODO: The local id of a tree should be clear from context, the entry can
+ * be optimized out. */
+ t8_eclass_t eclass; /**< The eclass of this tree. */
+ size_t neigh_offset; /**< Adding this offset to the address of the tree
+ yields the array of face_neighbor entries */
+ size_t att_offset; /**< Adding this offset to the address of the tree
+ yields the array of attribute_info entries */
+ /* TODO: Could be a size_t */
+ int num_attributes; /**< The number of attributes at this tree */
+} t8_ctree_struct_t;
+
+/** This structure holds the information associated to an attribute of a tree.
+ * The attributes of each are stored in a key-value storage, where the key consists
+ * of the two entries (package_id,key) both being integers.
+ * The package_id serves to identify the application layer that added the attribute
+ * and the key identifies the attribute within that application layer.
+ *
+ * All attribute info objects of one tree are stored in an array and adding
+ * a tree's att_offset entry to the tree's address yields this array.
+ * The attributes themselves are stored in an array directly behind the array of
+ * the attribute infos.
+ */
+typedef struct t8_attribute_info
+{
+ int package_id;
+ /**< The identifier of the application layer that added this attribute */
+ int key;
+ /**< The (tree unique) key of the attribute within this AL. */
+ size_t attribute_offset;
+ /**< The offset of the attribute data from the first
+ attribute info of the tree.
+ (Thus, the attribute is stored at address tree + tree->att_offset + attribute_offset) */
+ /* TODO: eventually remove the size */
+ size_t attribute_size;
+ /**< The size in bytes of the attribute */
+} t8_attribute_info_struct_t;
+
+/* TODO: document, process is a bad naming, since it does not refer to MPI ranks here */
+typedef struct t8_cmesh_trees
+{
+ sc_array_t *from_proc; /* array of t8_part_tree, one for each process */
+ int *tree_to_proc; /* for each tree its process */
+ int *ghost_to_proc; /* for each ghost its process */
+ sc_hash_t *ghost_globalid_to_local_id; /* A hash table storing the map
+ global_id -> local_id for the ghost trees.
+ The local_id is the local ghost id starting at num_local_trees */
+ sc_mempool_t *global_local_mempool; /* Memory pool for the entries in the hash table */
+} t8_cmesh_trees_struct_t;
+
+/* TODO: document */
+typedef struct t8_part_tree
+{
+ char *first_tree; /* Stores the trees, the ghosts and the attributes.
+ The last 2*sizeof(t8_locidx) bytes store num_trees and num_ghosts */
+ t8_locidx_t first_tree_id; /* local tree_id of the first tree. -1 if num_trees = 0 */
+ t8_locidx_t first_ghost_id; /* TODO: document. -1 if num_ghost=0, 0 for the first part, (not num_local_trees!)
+ 0 <= first_ghost_id < num_ghosts */
+ t8_locidx_t num_trees;
+ t8_locidx_t num_ghosts;
+} t8_part_tree_struct_t;
+
+/* TODO: Extend this structure with meaningful entries.
+ * Maybe the number of shipped trees per process is useful?
+ */
+/** This struct is used to profile cmesh algorithms.
+ * The cmesh struct stores a pointer to a profile struct, and if
+ * it is nonzero, various runtimes and data measurements are stored here.
+ * \see t8_cmesh_set_profiling and \see t8_cmesh_print_profile
+ */
+typedef struct t8_cprofile
+{
+ t8_locidx_t partition_trees_shipped; /**< The number of trees this process has
+ sent to other in the last partition call. */
+ t8_locidx_t partition_ghosts_shipped; /**< The number of ghosts this process has
+ sent to other in the last partition call. */
+ t8_locidx_t partition_trees_recv; /**< The number of trees this process has
+ received from other in the last partition call. */
+ t8_locidx_t partition_ghosts_recv; /**< The number of ghosts this process has
+ received from other in the last partition call. */
+ size_t partition_bytes_sent; /**< The total number of bytes sent to other processes in the
+ last partition call. */
+ int partition_procs_sent; /**< The number of different processes this process has send
+ local trees or ghosts to in the last partition call. */
+ int first_tree_shared; /**< 1 if this processes' first tree is shared. 0 if not. */
+ double partition_runtime; /**< The runtime of the last call to \a t8_cmesh_partition. */
+ double commit_runtime; /**< The runtime of the last call to \a t8_cmesh_commit. */
+ double geometry_evaluate_num_calls; /**< The number of calls to \a t8_geometry_evaluate. */
+ double geometry_evaluate_runtime; /**< The accumulated runtime of calls to \a t8_geometry_evaluate. */
+} t8_cprofile_struct_t;
+
+/** The number of entries in a cprofile struct */
+#define T8_CPROFILE_NUM_STATS 11
+
+#endif /* !T8_CMESH_TYPES_H */
+
+/*
+ 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_CMESH_TYPES_H
+#define T8_CMESH_TYPES_H
+
+#include
+#include
+#include
+#include
+#include "t8_cmesh_stash.h"
+#include "t8_element.h"
+
+/** \file t8_cmesh_types.h
+ * We define here the datatypes needed for internal cmesh routines.
+ */
+
+typedef struct t8_part_tree *t8_part_tree_t;
+typedef struct t8_cmesh_trees *t8_cmesh_trees_t;
+typedef struct t8_cprofile t8_cprofile_t; /* Defined below */
+
+/* TODO: no longer needed.
+ * User may use set_derived_from, then set_from is non-NULL.
+ * When refinement is desired, level shall be set positive.
+ * When partition is desired, we expect set_partition to be true.
+ * Any combination can be called.
+ * In t8_commit we check whether the parameters are consistent,
+ * and whether a combination is currently supported,
+ * and provide informative error messages both in debug and non-debug.
+ */
+
+/* Definitions for attribute identifiers that are reserved for a special purpose.
+ * T8_CMESH_NEXT_POSSIBLE_KEY is the first unused key, hence it can be repurposed for different attributes.*/
+#define T8_CMESH_VERTICES_ATTRIBUTE_KEY 0 /* Used to store vertex coordinates. */
+#define T8_CMESH_GEOMETRY_ATTRIBUTE_KEY 1 /* Used to store the name of a tree's geometry. */
+#define T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY 2 /* Used to store which edge is linked to which geometry */
+#define T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY 3 /* Used to store edge parameters */
+#define T8_CMESH_CAD_FACE_ATTRIBUTE_KEY \
+ T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY \
+ +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_NEXT_POSSIBLE_KEY \
+ T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + T8_ECLASS_MAX_FACES /* 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_writer.c b/src/t8_cmesh/t8_cmesh_vtk_writer.c
index 9008c2e369..53bf54b0f4 100644
--- a/src/t8_cmesh/t8_cmesh_vtk_writer.c
+++ b/src/t8_cmesh/t8_cmesh_vtk_writer.c
@@ -55,14 +55,12 @@ t8_cmesh_get_num_vertices (t8_cmesh_t cmesh, int count_ghosts)
return num_vertices;
}
-/* TODO: implement for scale < 1 */
static int
-t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double scale, int write_ghosts)
+t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, int write_ghosts)
{
T8_ASSERT (cmesh != NULL);
T8_ASSERT (t8_cmesh_is_committed (cmesh));
T8_ASSERT (fileprefix != NULL);
- T8_ASSERT (scale == 1.); /* scale = 1 not implemented yet */
if (cmesh->mpirank == 0) {
/* Write the pvtu header file. */
@@ -103,9 +101,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
}
fprintf (vtufile, "\n");
fprintf (vtufile, "\n");
#else
@@ -122,7 +117,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
" NumberOfComponents=\"3\" format=\"%s\">\n",
T8_VTK_FLOAT_NAME, T8_VTK_FORMAT_STRING);
-#ifdef T8_VTK_ASCII
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);
@@ -163,9 +157,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
}
} /* end ghost loop */
}
-#else
- SC_ABORT ("Binary vtk file not implemented\n");
-#endif /* T8_VTK_ASCII */
fprintf (vtufile, " \n");
fprintf (vtufile, " \n");
fprintf (vtufile, " \n");
@@ -175,7 +166,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
" \n",
T8_VTK_LOCIDX, T8_VTK_FORMAT_STRING);
-#ifdef T8_VTK_ASCII
for (tree = t8_cmesh_get_first_tree (cmesh), count_vertices = 0; tree != NULL;
tree = t8_cmesh_get_next_tree (cmesh, tree)) {
fprintf (vtufile, " ");
@@ -195,9 +185,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
fprintf (vtufile, "\n");
}
}
-#else
- SC_ABORT ("Binary vtk file not implemented\n");
-#endif /* T8_VTK_ASCII */
fprintf (vtufile, " \n");
/* write offset data */
@@ -205,7 +192,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
" \n",
T8_VTK_LOCIDX, T8_VTK_FORMAT_STRING);
-#ifdef T8_VTK_ASCII
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) {
@@ -225,16 +211,12 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
}
}
fprintf (vtufile, "\n");
-#else
- SC_ABORT ("Binary vtk file not implemented\n");
-#endif /* T8_VTK_ASCII */
fprintf (vtufile, " \n");
/* write type data */
fprintf (vtufile,
" \n",
T8_VTK_FORMAT_STRING);
-#ifdef T8_VTK_ASCII
fprintf (vtufile, " ");
for (tree = t8_cmesh_get_first_tree (cmesh), sk = 1; tree != NULL;
tree = t8_cmesh_get_next_tree (cmesh, tree), ++sk) {
@@ -252,9 +234,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
}
}
fprintf (vtufile, "\n");
-#else
- SC_ABORT ("Binary vtk file not implemented\n");
-#endif /* T8_VTK_ASCII */
fprintf (vtufile, " \n");
fprintf (vtufile, " \n");
/* write treeif data */
@@ -263,7 +242,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
" \n",
T8_VTK_GLOIDX, T8_VTK_FORMAT_STRING);
-#ifdef T8_VTK_ASCII
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) {
@@ -292,16 +270,12 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
}
}
fprintf (vtufile, "\n");
-#else
- SC_ABORT ("Binary vtk file not implemented\n");
-#endif /* T8_VTK_ASCII */
fprintf (vtufile, " \n");
/* write mpirank data */
fprintf (vtufile,
" \n",
"Int32", T8_VTK_FORMAT_STRING);
-#ifdef T8_VTK_ASCII
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) {
@@ -318,9 +292,6 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
}
}
fprintf (vtufile, "\n");
-#else
- SC_ABORT ("Binary vtk file not implemented\n");
-#endif /* T8_VTK_ASCII */
fprintf (vtufile, " \n");
fprintf (vtufile, " \n");
/* write type data */
@@ -333,8 +304,7 @@ t8_cmesh_vtk_write_file_ext (t8_cmesh_t cmesh, const char *fileprefix, double sc
}
int
-t8_cmesh_vtk_write_file (t8_cmesh_t cmesh, const char *fileprefix, double scale)
+t8_cmesh_vtk_write_file (t8_cmesh_t cmesh, const char *fileprefix)
{
- T8_ASSERT (scale == 1.0);
- return t8_cmesh_vtk_write_file_ext (cmesh, fileprefix, 1.0, 1);
+ return t8_cmesh_vtk_write_file_ext (cmesh, fileprefix, 1);
}
diff --git a/src/t8_cmesh_readmshfile.h b/src/t8_cmesh_readmshfile.h
index e63f468dd3..5acfeaddc9 100644
--- a/src/t8_cmesh_readmshfile.h
+++ b/src/t8_cmesh_readmshfile.h
@@ -87,14 +87,14 @@ T8_EXTERN_C_BEGIN ();
* dimension to read has to be set manually.
* \param [in] master If partition is true, a valid MPI rank that will
* read the file and store all the trees alone.
- * \param [in] use_occ_geometry Read the parameters of a parametric msh file and use the
- * occ geometry.
+ * \param [in] use_cad_geometry Read the parameters of a parametric msh file and use the
+ * cad geometry.
* \return A committed cmesh holding the mesh of dimension \a dim in the
* specified .msh file.
*/
t8_cmesh_t
t8_cmesh_from_msh_file (const char *fileprefix, int partition, sc_MPI_Comm comm, int dim, int master,
- int use_occ_geometry);
+ int use_cad_geometry);
T8_EXTERN_C_END ();
diff --git a/src/t8_cmesh_vtk_writer.h b/src/t8_cmesh_vtk_writer.h
index cf1f14a5db..7283bc7471 100644
--- a/src/t8_cmesh_vtk_writer.h
+++ b/src/t8_cmesh_vtk_writer.h
@@ -36,7 +36,7 @@ T8_EXTERN_C_BEGIN ();
/* TODO: document this function */
int
-t8_cmesh_vtk_write_file (t8_cmesh_t cmesh, const char *fileprefix, double scale);
+t8_cmesh_vtk_write_file (t8_cmesh_t cmesh, const char *fileprefix);
T8_EXTERN_C_END ();
diff --git a/src/t8_element_c_interface.cxx b/src/t8_element_c_interface.cxx
index 1f0ee7a733..4dc8721a04 100644
--- a/src/t8_element_c_interface.cxx
+++ b/src/t8_element_c_interface.cxx
@@ -383,19 +383,19 @@ t8_element_vertex_reference_coords (const t8_eclass_scheme_c *ts, const t8_eleme
}
t8_gloidx_t
-t8_element_count_leafs (const t8_eclass_scheme_c *ts, const t8_element_t *t, int level)
+t8_element_count_leaves (const t8_eclass_scheme_c *ts, const t8_element_t *t, int level)
{
T8_ASSERT (ts != NULL);
- return ts->t8_element_count_leafs (t, level);
+ return ts->t8_element_count_leaves (t, level);
}
t8_gloidx_t
-t8_element_count_leafs_from_root (const t8_eclass_scheme_c *ts, int level)
+t8_element_count_leaves_from_root (const t8_eclass_scheme_c *ts, int level)
{
T8_ASSERT (ts != NULL);
- return ts->t8_element_count_leafs_from_root (level);
+ return ts->t8_element_count_leaves_from_root (level);
}
void
diff --git a/src/t8_element_c_interface.h b/src/t8_element_c_interface.h
index 52b11ab2c0..60eef83a43 100644
--- a/src/t8_element_c_interface.h
+++ b/src/t8_element_c_interface.h
@@ -507,7 +507,7 @@ t8_element_shape (const t8_eclass_scheme_c *ts, const t8_element_t *elem);
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
void
t8_element_set_linear_id (const t8_eclass_scheme_c *ts, t8_element_t *elem, int level, t8_linearidx_t id);
@@ -584,19 +584,19 @@ t8_element_vertex_reference_coords (const t8_eclass_scheme_c *ts, const t8_eleme
* Thus, if \a t's level is 0, and \a level = 3, the return value is 2^3 = 8.
*/
t8_gloidx_t
-t8_element_count_leafs (const t8_eclass_scheme_c *ts, const t8_element_t *t, int level);
+t8_element_count_leaves (const t8_eclass_scheme_c *ts, const t8_element_t *t, int level);
/** Count how many leaf descendants of a given uniform level the root element will produce.
* \param [in] ts Implementation of a class scheme.
* \param [in] level A refinement level.
- * \return The value of \ref t8_element_count_leafs if the input element
+ * \return The value of \ref t8_element_count_leaves if the input element
* is the root (level 0) element.
*
* This is a convenience function, and can be implemented via
- * \ref t8_element_count_leafs.
+ * \ref t8_element_count_leaves.
*/
t8_gloidx_t
-t8_element_count_leafs_from_root (const t8_eclass_scheme_c *ts, int level);
+t8_element_count_leaves_from_root (const t8_eclass_scheme_c *ts, int level);
/** This function has no defined effect but each implementation is free to
* provide its own meaning of it. Thus this function can be used to compute or
diff --git a/src/t8_element_cxx.hxx b/src/t8_element_cxx.hxx
index 258c6dffc4..e2135a701c 100644
--- a/src/t8_element_cxx.hxx
+++ b/src/t8_element_cxx.hxx
@@ -547,7 +547,7 @@ struct t8_eclass_scheme
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const
@@ -641,19 +641,19 @@ struct t8_eclass_scheme
* Thus, if \a t's level is 0, and \a level = 3, the return value is 2^3 = 8.
*/
virtual t8_gloidx_t
- t8_element_count_leafs (const t8_element_t *t, int level) const
+ t8_element_count_leaves (const t8_element_t *t, int level) const
= 0;
/** 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_leafs if the input element
+ * \return The value of \ref t8_element_count_leaves if the input element
* is the root (level 0) element.
*
* This is a convenience function, and can be implemented via
- * \ref t8_element_count_leafs.
+ * \ref t8_element_count_leaves.
*/
virtual t8_gloidx_t
- t8_element_count_leafs_from_root (int level) const
+ t8_element_count_leaves_from_root (int level) const
= 0;
/** This function has no defined effect but each implementation is free to
diff --git a/src/t8_forest/t8_forest.c b/src/t8_forest/t8_forest.c
index 0f414c220e..7a0a6c397c 100644
--- a/src/t8_forest/t8_forest.c
+++ b/src/t8_forest/t8_forest.c
@@ -837,7 +837,7 @@ t8_forest_get_tree_vertices (t8_forest_t forest, t8_locidx_t ltreeid)
}
t8_element_array_t *
-t8_forest_tree_get_leafs (const t8_forest_t forest, const t8_locidx_t ltree_id)
+t8_forest_tree_get_leaves (const t8_forest_t forest, const t8_locidx_t ltree_id)
{
T8_ASSERT (t8_forest_is_committed (forest));
T8_ASSERT (0 <= ltree_id && ltree_id < t8_forest_get_num_local_trees (forest));
@@ -1061,6 +1061,29 @@ t8_forest_get_local_id (const t8_forest_t forest, const t8_gloidx_t gtreeid)
return -1;
}
}
+t8_locidx_t
+t8_forest_get_local_or_ghost_id (const t8_forest_t forest, const t8_gloidx_t gtreeid)
+{
+ t8_gloidx_t ltreeid;
+ T8_ASSERT (t8_forest_is_committed (forest));
+ T8_ASSERT (0 <= gtreeid && gtreeid < t8_forest_get_num_global_trees (forest));
+
+ /* If the tree is local then its local id is the global id minus the
+ * first global tree id on this forest. If this number is not in the
+ * range of local tree ids then the tree is not local. */
+ /* we use a gloidx for ltreeid to prevent overflow and false positives */
+ ltreeid = gtreeid - t8_forest_get_first_local_tree_id (forest);
+ /* Check if this tree is a local tree and if so return its local id */
+ if (0 <= ltreeid && ltreeid < t8_forest_get_num_local_trees (forest)) {
+ return ltreeid;
+ }
+ else {
+ t8_locidx_t ghost_id = t8_forest_ghost_get_ghost_treeid (forest, gtreeid);
+ if (ghost_id >= 0)
+ return t8_forest_get_num_local_trees (forest) + ghost_id;
+ return -1;
+ }
+}
t8_locidx_t
t8_forest_ltreeid_to_cmesh_ltreeid (t8_forest_t forest, t8_locidx_t ltreeid)
diff --git a/src/t8_forest/t8_forest_cxx.cxx b/src/t8_forest/t8_forest_cxx.cxx
index eca88d80c8..8c060c3c37 100644
--- a/src/t8_forest/t8_forest_cxx.cxx
+++ b/src/t8_forest/t8_forest_cxx.cxx
@@ -38,6 +38,7 @@
#include
#if T8_ENABLE_DEBUG
#include
+#include
#endif
/* We want to export the whole implementation to be callable from "C" */
@@ -1088,325 +1089,16 @@ t8_forest_element_face_normal (t8_forest_t forest, t8_locidx_t ltreeid, const t8
}
}
-/**
- * Check if a point lies inside a vertex
- *
- * \param[in] vertex_coords The coordinates of the vertex
- * \param[in] point The coordinates of the point to check
- * \param[in] tolerance A double > 0 defining the tolerance
- * \return 0 if the point is outside, 1 otherwise.
- */
-static int
-t8_vertex_point_inside (const double vertex_coords[3], const double point[3], const double tolerance)
-{
- T8_ASSERT (tolerance > 0);
- if (t8_vec_dist (vertex_coords, point) > tolerance) {
- return 0;
- }
- return 1;
-}
-
-/**
- * Check if a point is inside a line that is defined by a starting point \a p_0
- * and a vector \a vec
- *
- * \param[in] p_0 Starting point of the line
- * \param[in] vec Direction of the line (not normalized)
- * \param[in] point The coordinates of the point to check
- * \param[in] tolerance A double > 0 defining the tolerance
- * \return 0 if the point is outside, 1 otherwise.
- */
-static int
-t8_line_point_inside (const double *p_0, const double *vec, const double *point, const double tolerance)
-{
- T8_ASSERT (tolerance > 0);
- double b[3];
- /* b = p - p_0 */
- t8_vec_axpyz (p_0, point, b, -1);
- double x = 0; /* Initialized to prevent compiler warning. */
- int i;
- /* So x is the solution to
- * vec * x = b.
- * We can compute it as
- * x = b[i] / vec[i]
- * if any vec[i] is not 0.
- *
- * Otherwise the line is degenerated (which should not happen).
- */
- for (i = 0; i < 3; ++i) {
- if (vec[i] != 0) {
- x = b[i] / vec[i];
- break; /* found a non-zero coordinate. We can stop now. */
- }
- }
-
- /* If i == 3 here, then vec = 0 and hence the line is degenerated. */
- SC_CHECK_ABORT (i < 3, "Degenerated line element. Both endpoints are the same.");
-
- if (x < -tolerance || x > 1 + tolerance) {
- /* x is not an admissible solution. */
- return 0;
- }
-
- /* we can check whether x gives us a solution by
- * checking whether
- * vec * x = b
- * is actually true.
- */
- double vec_check[3] = { vec[0], vec[1], vec[2] };
- t8_vec_ax (vec_check, x);
- if (t8_vec_dist (vec_check, b) > tolerance) {
- /* Point does not lie on the line. */
- return 0;
- }
- /* The point is on the line. */
- return 1;
-}
-
-/**
- * Check if a point is inside of a triangle described by a point \a p_0 and two vectors \a v and \a w.
- *
- * \param[in] p_0 The first vertex of a triangle
- * \param[in] v The vector from p_0 to p_1 (second vertex in the triangle)
- * \param[in] w The vector from p_0 to p_2 (third vertex in the triangle)
- * \param[in] point The coordinates of the point to check
- * \param[in] tolerance A double > 0 defining the tolerance
- * \return 0 if the point is outside, 1 otherwise.
- */
-static int
-t8_triangle_point_inside (const double p_0[3], const double v[3], const double w[3], const double point[3],
- const double tolerance)
-{
- /* A point p is inside the triangle that is spanned
- * by the point p_0 and vectors v and w if and only if the linear system
- * vx + wy = point - p_0
- * has a solution with 0 <= x,y and x + y <= 1.
- *
- * We check whether such a solution exists by computing
- * certain determinants of 2x2 submatrizes of the 3x3 matrix
- *
- * | v w e_3 | with v = p_1 - p_0, w = p_2 - p_0, and e_3 = (0 0 1)^t (third unit vector)
- */
-
- T8_ASSERT (tolerance > 0); /* negative values and zero are not allowed */
- double b[3];
- /* b = point - p_0 */
- t8_vec_axpyz (p_0, point, b, -1);
-
- /* Let d = det (v w e_3) */
- const double det_vwe3 = v[0] * w[1] - v[1] * w[0];
-
- /* The system has a solution, we need to compute it and
- * check whether 0 <= x,y and x + y <= 1 */
- /* x = det (b w e_3) / d
- * y = det (v b e_3) / d
- */
- const double x = (b[0] * w[1] - b[1] * w[0]) / det_vwe3;
- const double y = (v[0] * b[1] - v[1] * b[0]) / det_vwe3;
-
- if (x < -tolerance || y < -tolerance || x + y > 1 + tolerance) {
- /* The solution is not admissible.
- * x < 0 or y < 0 or x + y > 1 */
- return 0;
- }
- /* The solution may be admissible, but we have to
- * check whether the result of
- * (p_1 - p_0)x + (p_2 - p_0)y ( = vx + wy)
- * is actually p - p_0.
- * Since the system of equations is overrepresented (3 equations, 2 variables)
- * this may actually break.
- * If it breaks, it will break in the z coordinate of the result.
- */
- const double z = v[2] * x + w[2] * y;
- /* Must match the last coordinate of b = p - p_0 */
- if (fabs (z - b[2]) > tolerance) {
- /* Does not match. Point lies outside. */
- return 0;
- }
- /* All checks passed. Point lies inside. */
- return 1;
-}
-
-/** Check if a point lays on the inner side of a plane of a bilinearly interpolated volume element.
- * the plane is described by a point and the normal of the face.
- * \param[in] point_on_face A point on the plane
- * \param[in] face_normal The normal of the face
- * \param[in] point The point to check
- * \return 0 if the point is outside, 1 otherwise.
- */
-static int
-t8_plane_point_inside (const double point_on_face[3], const double face_normal[3], const double point[3])
-{
- /* Set x = x - p */
- double pof[3] = { point_on_face[0], point_on_face[1], point_on_face[2] };
- t8_vec_axpy (point, pof, -1);
- /* Compute */
- const double dot_product = t8_vec_dot (pof, face_normal);
- if (dot_product < 0) {
- /* The point is on the wrong side of the plane */
- return 0;
- }
- return 1;
-}
-
void
-t8_forest_element_point_batch_inside (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element,
- const double *points, int num_points, int *is_inside, const double tolerance)
+t8_forest_element_points_inside (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element,
+ const double *points, int num_points, int *is_inside, const double tolerance)
{
- const t8_eclass_t tree_class = t8_forest_get_tree_class (forest, ltreeid);
- t8_eclass_scheme_c *ts = t8_forest_get_eclass_scheme (forest, tree_class);
- const t8_element_shape_t element_shape = ts->t8_element_shape (element);
-
-#if T8_ENABLE_DEBUG
/* Check whether the provided geometry is linear */
const t8_cmesh_t cmesh = t8_forest_get_cmesh (forest);
const t8_locidx_t cltreeid = t8_forest_ltreeid_to_cmesh_ltreeid (forest, ltreeid);
const t8_gloidx_t cgtreeid = t8_cmesh_get_global_id (cmesh, cltreeid);
- T8_ASSERT (t8_geometry_get_type (cmesh, cgtreeid) == T8_GEOMETRY_TYPE_LINEAR);
-#endif
-
- switch (element_shape) {
- case T8_ECLASS_VERTEX: {
- /* A point is 'inside' a vertex if they have the same coordinates */
- double vertex_coords[3];
- /* Get the vertex coordinates */
- t8_forest_element_coordinate (forest, ltreeid, element, 0, vertex_coords);
- /* Check whether the point and the vertex are within tolerance distance
- * to each other */
- for (int ipoint = 0; ipoint < num_points; ipoint++) {
- is_inside[ipoint] = t8_vertex_point_inside (vertex_coords, &points[ipoint * 3], tolerance);
- }
- return;
- }
- case T8_ECLASS_LINE: {
- /* A point p is inside a line that is defined by the edge nodes
- * p_0 and p_1
- * if and only if the linear system
- * (p_1 - p_0)x = p - p_0
- * has a solution x with 0 <= x <= 1
- */
- double p_0[3], v[3];
-
- /* Compute the vertex coordinates of the line */
- t8_forest_element_coordinate (forest, ltreeid, element, 0, p_0);
- /* v = p_1 */
- t8_forest_element_coordinate (forest, ltreeid, element, 1, v);
- /* v = p_1 - p_0 */
- t8_vec_axpy (p_0, v, -1);
- for (int ipoint = 0; ipoint < num_points; ipoint++) {
- is_inside[ipoint] = t8_line_point_inside (p_0, v, &points[ipoint * 3], tolerance);
- }
- return;
- }
- case T8_ECLASS_QUAD: {
- /* We divide the quad in two triangles and use the triangle check. */
- double p_0[3], p_1[3], p_2[3], p_3[3];
- /* Compute the vertex coordinates of the quad */
- t8_forest_element_coordinate (forest, ltreeid, element, 0, p_0);
- t8_forest_element_coordinate (forest, ltreeid, element, 1, p_1);
- t8_forest_element_coordinate (forest, ltreeid, element, 2, p_2);
- t8_forest_element_coordinate (forest, ltreeid, element, 3, p_3);
-
-#if T8_ENABLE_DEBUG
- /* Issue a warning if the points of the quad do not lie in the same plane */
- if (!t8_four_points_coplanar (p_0, p_1, p_2, p_3, tolerance)) {
- t8_debugf ("WARNING: Testing if point is inside a quad that is not coplanar. This test will be inaccurate.\n");
- }
-#endif
- double v[3];
- double w[3];
- /* v = v - p_0 = p_1 - p_0 */
- t8_vec_axpyz (p_0, p_1, v, -1);
- /* w = w - p_0 = p_2 - p_0 */
- t8_vec_axpyz (p_0, p_2, w, -1);
- /* Check whether the point is inside the first triangle. */
- for (int ipoint = 0; ipoint < num_points; ipoint++) {
- is_inside[ipoint] = t8_triangle_point_inside (p_0, v, w, &points[ipoint * 3], tolerance);
- }
- /* If not, check whether the point is inside the second triangle. */
- /* v = v - p_0 = p_1 - p_0 */
- t8_vec_axpyz (p_1, p_2, v, -1);
- /* w = w - p_0 = p_2 - p_0 */
- t8_vec_axpyz (p_1, p_3, w, -1);
- for (int ipoint = 0; ipoint < num_points; ipoint++) {
- if (!is_inside[ipoint]) {
- /* point_inside is true if the point was inside the first or second triangle. Otherwise it is false. */
- is_inside[ipoint] = t8_triangle_point_inside (p_1, v, w, &points[ipoint * 3], tolerance);
- }
- }
- return;
- }
- case T8_ECLASS_TRIANGLE: {
- double p_0[3], p_1[3], p_2[3];
-
- /* Compute the vertex coordinates of the triangle */
- t8_forest_element_coordinate (forest, ltreeid, element, 0, p_0);
- t8_forest_element_coordinate (forest, ltreeid, element, 1, p_1);
- t8_forest_element_coordinate (forest, ltreeid, element, 2, p_2);
- double v[3];
- double w[3];
- /* v = v - p_0 = p_1 - p_0 */
- t8_vec_axpyz (p_0, p_1, v, -1);
- /* w = w - p_0 = p_2 - p_0 */
- t8_vec_axpyz (p_0, p_2, w, -1);
-
- for (int ipoint = 0; ipoint < num_points; ipoint++) {
- is_inside[ipoint] = t8_triangle_point_inside (p_0, v, w, &points[ipoint * 3], tolerance);
- }
- return;
- }
- case T8_ECLASS_TET:
- case T8_ECLASS_HEX:
- case T8_ECLASS_PRISM:
- case T8_ECLASS_PYRAMID: {
- /* For bilinearly interpolated volume elements, a point is inside an element
- * if and only if it lies on the inner side of each face.
- * The inner side is defined as the side where the outside normal vector does not
- * point to.
- * The point is on this inner side if and only if the scalar product of
- * a point on the plane minus the point with the outer normal of the face
- * is >= 0.
- *
- * In other words, let p be the point to check, n the outer normal and x a point
- * on the plane, then p is on the inner side if and only if
- * >= 0
- */
-
- const int num_faces = ts->t8_element_num_faces (element);
- /* Assume that every point is inside of the element */
- for (int ipoint = 0; ipoint < num_points; ipoint++) {
- is_inside[ipoint] = 1;
- }
- for (int iface = 0; iface < num_faces; ++iface) {
- double face_normal[3];
- /* Compute the outer normal n of the face */
- t8_forest_element_face_normal (forest, ltreeid, element, iface, face_normal);
- /* Compute a point x on the face */
- const int afacecorner = ts->t8_element_get_face_corner (element, iface, 0);
- double point_on_face[3];
- t8_forest_element_coordinate (forest, ltreeid, element, afacecorner, point_on_face);
- for (int ipoint = 0; ipoint < num_points; ipoint++) {
- const int is_inside_iface = t8_plane_point_inside (point_on_face, face_normal, &points[ipoint * 3]);
- if (is_inside_iface == 0) {
- /* Point is on the outside of face iface. Update is_inside */
- is_inside[ipoint] = 0;
- }
- }
- }
- return;
- }
- default:
- SC_ABORT_NOT_REACHED ();
- }
-}
-
-int
-t8_forest_element_point_inside (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element,
- const double point[3], const double tolerance)
-{
- int is_inside = 0;
- t8_forest_element_point_batch_inside (forest, ltreeid, element, point, 1, &is_inside, tolerance);
- return is_inside;
+ const t8_geometry_c *geometry = t8_cmesh_get_tree_geometry (cmesh, cgtreeid);
+ geometry->t8_geom_point_batch_inside_element (forest, ltreeid, element, points, num_points, is_inside, tolerance);
}
/* For each tree in a forest compute its first and last descendant */
@@ -1511,7 +1203,7 @@ t8_forest_populate (t8_forest_t forest)
/* calculate first and last element on this tree */
start = (jt == forest->first_local_tree) ? child_in_tree_begin : 0;
end = (jt == forest->last_local_tree) ? child_in_tree_end
- : eclass_scheme->t8_element_count_leafs_from_root (forest->set_level);
+ : eclass_scheme->t8_element_count_leaves_from_root (forest->set_level);
num_tree_elements = end - start;
T8_ASSERT (num_tree_elements > 0);
/* Allocate elements for this processor. */
@@ -2001,10 +1693,10 @@ t8_forest_element_half_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid,
}
void
-t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *leaf,
- t8_element_t **pneighbor_leafs[], int face, int *dual_faces[], int *num_neighbors,
- t8_locidx_t **pelement_indices, t8_eclass_scheme_c **pneigh_scheme,
- int forest_is_balanced)
+t8_forest_leaf_face_neighbors_ext (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *leaf,
+ t8_element_t **pneighbor_leaves[], int face, int *dual_faces[], int *num_neighbors,
+ t8_locidx_t **pelement_indices, t8_eclass_scheme_c **pneigh_scheme,
+ int forest_is_balanced, t8_gloidx_t *gneigh_tree)
{
t8_eclass_t neigh_class, eclass;
t8_gloidx_t gneigh_treeid;
@@ -2012,7 +1704,7 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
t8_locidx_t lghost_treeid = -1, *element_indices, element_index;
t8_eclass_scheme_c *ts, *neigh_scheme;
t8_element_array_t *element_array;
- t8_element_t *ancestor, **neighbor_leafs;
+ t8_element_t *ancestor, **neighbor_leaves;
t8_linearidx_t neigh_id;
int num_children_at_face, at_maxlevel;
int ineigh, *owners, different_owners, have_ghosts;
@@ -2039,37 +1731,40 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
at_maxlevel = ts->t8_element_level (leaf) == t8_forest_get_maxlevel (forest);
if (at_maxlevel) {
num_children_at_face = 1;
- neighbor_leafs = *pneighbor_leafs = T8_ALLOC (t8_element_t *, 1);
+ neighbor_leaves = *pneighbor_leaves = T8_ALLOC (t8_element_t *, 1);
*dual_faces = T8_ALLOC (int, 1);
- neigh_scheme->t8_element_new (num_children_at_face, neighbor_leafs);
+ neigh_scheme->t8_element_new (num_children_at_face, neighbor_leaves);
/* Compute neighbor element and global treeid of the neighbor */
gneigh_treeid
- = t8_forest_element_face_neighbor (forest, ltreeid, leaf, neighbor_leafs[0], neigh_scheme, face, *dual_faces);
+ = t8_forest_element_face_neighbor (forest, ltreeid, leaf, neighbor_leaves[0], neigh_scheme, face, *dual_faces);
}
else {
/* Allocate neighbor element */
num_children_at_face = ts->t8_element_num_face_children (leaf, face);
- neighbor_leafs = *pneighbor_leafs = T8_ALLOC (t8_element_t *, num_children_at_face);
+ neighbor_leaves = *pneighbor_leaves = T8_ALLOC (t8_element_t *, num_children_at_face);
*dual_faces = T8_ALLOC (int, num_children_at_face);
- neigh_scheme->t8_element_new (num_children_at_face, neighbor_leafs);
+ neigh_scheme->t8_element_new (num_children_at_face, neighbor_leaves);
/* Compute neighbor elements and global treeid of the neighbor */
- gneigh_treeid = t8_forest_element_half_face_neighbors (forest, ltreeid, leaf, neighbor_leafs, neigh_scheme, face,
+ gneigh_treeid = t8_forest_element_half_face_neighbors (forest, ltreeid, leaf, neighbor_leaves, neigh_scheme, face,
num_children_at_face, *dual_faces);
}
+ if (gneigh_tree) {
+ *gneigh_tree = gneigh_treeid;
+ }
if (gneigh_treeid < 0) {
/* There exists no face neighbor across this face, we return with this info */
- neigh_scheme->t8_element_destroy (num_children_at_face, neighbor_leafs);
- T8_FREE (neighbor_leafs);
+ neigh_scheme->t8_element_destroy (num_children_at_face, neighbor_leaves);
+ T8_FREE (neighbor_leaves);
T8_FREE (*dual_faces);
*dual_faces = NULL;
*num_neighbors = 0;
*pelement_indices = NULL;
- *pneighbor_leafs = NULL;
+ *pneighbor_leaves = NULL;
return;
}
T8_ASSERT (gneigh_treeid >= 0 && gneigh_treeid < forest->global_num_trees);
/* We have computed the half face neighbor elements, we now compute their owners,
- * if they differ, we know that the half face neighbors are the neighbor leafs.
+ * if they differ, we know that the half face neighbors are the neighbor leaves.
* If the owners do not differ, we have to check if the neighbor leaf is their
* parent or grandparent. */
owners = T8_ALLOC (int, num_children_at_face);
@@ -2078,14 +1773,14 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
for (ineigh = 0; ineigh < num_children_at_face; ineigh++) {
/* At first, we check whether the current rank owns the neighbor, since
* this is a constant time check and it is the most common case */
- if (t8_forest_element_check_owner (forest, neighbor_leafs[ineigh], gneigh_treeid, neigh_class, forest->mpirank,
+ if (t8_forest_element_check_owner (forest, neighbor_leaves[ineigh], gneigh_treeid, neigh_class, forest->mpirank,
at_maxlevel)) {
owners[ineigh] = forest->mpirank;
/* The neighbor tree is also a local tree. we store its local treeid */
lneigh_treeid = t8_forest_get_local_id (forest, gneigh_treeid);
}
else {
- owners[ineigh] = t8_forest_element_find_owner (forest, gneigh_treeid, neighbor_leafs[ineigh], neigh_class);
+ owners[ineigh] = t8_forest_element_find_owner (forest, gneigh_treeid, neighbor_leaves[ineigh], neigh_class);
/* Store that at least one neighbor is a ghost */
have_ghosts = 1;
}
@@ -2105,8 +1800,8 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
if (!different_owners) {
/* The face neighbors belong to the same process, we thus need to determine
- * if they are leafs or their parent or grandparent. */
- neigh_id = neigh_scheme->t8_element_get_linear_id (neighbor_leafs[0], forest->maxlevel);
+ * if they are leaves or their parent or grandparent. */
+ neigh_id = neigh_scheme->t8_element_get_linear_id (neighbor_leaves[0], forest->maxlevel);
if (owners[0] != forest->mpirank) {
/* The elements are ghost elements of the same owner */
element_array = t8_forest_ghost_get_tree_elements (forest, lghost_treeid);
@@ -2134,7 +1829,7 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
/* Add the element offset of this tree to the index */
element_index += t8_forest_get_tree_element_offset (forest, lneigh_treeid);
}
- if (neigh_scheme->t8_element_compare (ancestor, neighbor_leafs[0]) < 0) {
+ if (neigh_scheme->t8_element_compare (ancestor, neighbor_leaves[0]) < 0) {
/* ancestor is a real ancestor, and thus the neighbor is either the parent
* or the grandparent of the half neighbors. We can return it and the indices. */
/* We need to determine the dual face */
@@ -2142,27 +1837,27 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
/* The ancestor is the same-level neighbor of leaf */
if (!at_maxlevel) {
/* its dual face is the face of the parent of the first neighbor leaf */
- *dual_faces[0] = neigh_scheme->t8_element_face_parent_face (neighbor_leafs[0], *dual_faces[0]);
+ *dual_faces[0] = neigh_scheme->t8_element_face_parent_face (neighbor_leaves[0], *dual_faces[0]);
}
}
else {
/* The ancestor is the parent of the parent */
T8_ASSERT (neigh_scheme->t8_element_level (ancestor) == ts->t8_element_level (leaf) - 1);
- *dual_faces[0] = neigh_scheme->t8_element_face_parent_face (neighbor_leafs[0], *dual_faces[0]);
+ *dual_faces[0] = neigh_scheme->t8_element_face_parent_face (neighbor_leaves[0], *dual_faces[0]);
if (!at_maxlevel) {
/* We need to compute the dual face of the grandparent. */
/* Construct the parent of the grand child */
- neigh_scheme->t8_element_parent (neighbor_leafs[0], neighbor_leafs[0]);
+ neigh_scheme->t8_element_parent (neighbor_leaves[0], neighbor_leaves[0]);
/* Compute the face id of the parent's face */
- *dual_faces[0] = neigh_scheme->t8_element_face_parent_face (neighbor_leafs[0], *dual_faces[0]);
+ *dual_faces[0] = neigh_scheme->t8_element_face_parent_face (neighbor_leaves[0], *dual_faces[0]);
}
}
/* free memory */
- neigh_scheme->t8_element_destroy (num_children_at_face - 1, neighbor_leafs + 1);
+ neigh_scheme->t8_element_destroy (num_children_at_face - 1, neighbor_leaves + 1);
/* copy the ancestor */
- neigh_scheme->t8_element_copy (ancestor, neighbor_leafs[0]);
+ neigh_scheme->t8_element_copy (ancestor, neighbor_leaves[0]);
/* set return values */
*num_neighbors = 1;
*pelement_indices = T8_ALLOC (t8_locidx_t, 1);
@@ -2172,18 +1867,18 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
return;
}
}
- /* The leafs are the face neighbors that we are looking for. */
- /* The face neighbors either belong to different processes and thus must be leafs
+ /* The leaves are the face neighbors that we are looking for. */
+ /* The face neighbors either belong to different processes and thus must be leaves
* in the forest, or the ancestor leaf of the first half neighbor is the half
- * neighbor itself and thus all half neighbors must be leafs.
- * Since the forest is balanced, we found all neighbor leafs.
+ * neighbor itself and thus all half neighbors must be leaves.
+ * Since the forest is balanced, we found all neighbor leaves.
* It remains to compute their local ids */
*num_neighbors = num_children_at_face;
*pelement_indices = T8_ALLOC (t8_locidx_t, num_children_at_face);
element_indices = *pelement_indices;
for (ineigh = 0; ineigh < num_children_at_face; ineigh++) {
/* Compute the linear id at maxlevel of the neighbor leaf */
- neigh_id = neigh_scheme->t8_element_get_linear_id (neighbor_leafs[ineigh], forest->maxlevel);
+ neigh_id = neigh_scheme->t8_element_get_linear_id (neighbor_leaves[ineigh], forest->maxlevel);
/* Get a pointer to the element array in which the neighbor lies and search for the element's index in this array.
* This is either the local leaf array of the local tree or the corresponding leaf array in the ghost structure */
if (owners[ineigh] == forest->mpirank) {
@@ -2200,7 +1895,7 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
t8_locidx_t check_ltreeid;
const t8_element_t *check_element = t8_forest_get_element (forest, element_indices[ineigh], &check_ltreeid);
T8_ASSERT (check_ltreeid == lneigh_treeid);
- T8_ASSERT (neigh_scheme->t8_element_equal (check_element, neighbor_leafs[ineigh]));
+ T8_ASSERT (neigh_scheme->t8_element_equal (check_element, neighbor_leaves[ineigh]));
}
#endif
}
@@ -2215,7 +1910,7 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
{
t8_element_t *check_element;
check_element = t8_forest_ghost_get_element (forest, lghost_treeid, element_indices[ineigh]);
- T8_ASSERT (neigh_scheme->t8_element_equal (check_element, neighbor_leafs[ineigh]));
+ T8_ASSERT (neigh_scheme->t8_element_equal (check_element, neighbor_leaves[ineigh]));
}
#endif
/* Add the element offset of previous ghosts to this index */
@@ -2223,7 +1918,7 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
/* Add the number of all local elements to this index */
element_indices[ineigh] += t8_forest_get_local_num_elements (forest);
}
- } /* End for loop over neighbor leafs */
+ } /* End for loop over neighbor leaves */
T8_FREE (owners);
}
else {
@@ -2232,11 +1927,21 @@ t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8
}
}
+void
+t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *leaf,
+ t8_element_t **pneighbor_leaves[], int face, int *dual_faces[], int *num_neighbors,
+ t8_locidx_t **pelement_indices, t8_eclass_scheme_c **pneigh_scheme,
+ int forest_is_balanced)
+{
+ t8_forest_leaf_face_neighbors_ext (forest, ltreeid, leaf, pneighbor_leaves, face, dual_faces, num_neighbors,
+ pelement_indices, pneigh_scheme, forest_is_balanced, NULL);
+}
+
void
t8_forest_print_all_leaf_neighbors (t8_forest_t forest)
{
t8_locidx_t ltree, ielem;
- t8_element_t **neighbor_leafs;
+ t8_element_t **neighbor_leaves;
int iface, num_neighbors, ineigh;
t8_eclass_t eclass;
t8_eclass_scheme_c *ts, *neigh_scheme;
@@ -2265,7 +1970,7 @@ t8_forest_print_all_leaf_neighbors (t8_forest_t forest)
ts = t8_forest_get_eclass_scheme (forest, eclass);
/* Iterate over all faces */
for (iface = 0; iface < ts->t8_element_num_faces (leaf); iface++) {
- t8_forest_leaf_face_neighbors (forest, ltree, leaf, &neighbor_leafs, iface, &dual_faces, &num_neighbors,
+ t8_forest_leaf_face_neighbors (forest, ltree, leaf, &neighbor_leaves, iface, &dual_faces, &num_neighbors,
&element_indices, &neigh_scheme, 1);
t8_debugf ("Element %li across face %i has %i leaf neighbors (with dual faces).\n", (long) ielem, iface,
num_neighbors);
@@ -2276,10 +1981,10 @@ t8_forest_print_all_leaf_neighbors (t8_forest_t forest)
}
t8_debugf ("%s\n", buffer);
if (num_neighbors > 0) {
- neigh_scheme->t8_element_destroy (num_neighbors, neighbor_leafs);
+ neigh_scheme->t8_element_destroy (num_neighbors, neighbor_leaves);
T8_FREE (element_indices);
- T8_FREE (neighbor_leafs);
+ T8_FREE (neighbor_leaves);
T8_FREE (dual_faces);
}
}
diff --git a/src/t8_forest/t8_forest_general.h b/src/t8_forest/t8_forest_general.h
index 8b06def117..9672f3db3f 100644
--- a/src/t8_forest/t8_forest_general.h
+++ b/src/t8_forest/t8_forest_general.h
@@ -448,6 +448,21 @@ t8_forest_get_eclass (const t8_forest_t forest, const t8_locidx_t ltreeid);
t8_locidx_t
t8_forest_get_local_id (const t8_forest_t forest, const t8_gloidx_t gtreeid);
+/** Given a global tree id compute the forest local id of this tree.
+ * If the tree is a local tree, then the local id is between 0 and the number
+ * of local trees. If the tree is a ghost, then the local id is between num_local_trees and
+ * num_local_trees + num_ghost_trees.
+ * If the tree is neither a local tree nor a ghost tree, a negative number is returned.
+ * \param [in] forest The forest.
+ * \param [in] gtreeid The global id of a tree.
+ * \return The tree's local id in \a forest, if it is a local tree.
+ * num_local_trees + the ghosts id, if it is a ghost tree.
+ * A negative number if not.
+ * \see https://github.com/DLR-AMR/t8code/wiki/Tree-indexing for more details about tree indexing.
+ */
+t8_locidx_t
+t8_forest_get_local_or_ghost_id (const t8_forest_t forest, const t8_gloidx_t gtreeid);
+
/** Given the local id of a tree in a forest, compute the tree's local id in the associated cmesh.
* \param [in] forest The forest.
* \param [in] ltreeid The local id of a tree or ghost in the forest.
@@ -482,30 +497,36 @@ t8_forest_get_coarse_tree (t8_forest_t forest, t8_locidx_t ltreeid);
* \param [in] forest The forest. Must have a valid ghost layer.
* \param [in] ltreeid A local tree id.
* \param [in] leaf A leaf in tree \a ltreeid of \a forest.
- * \param [out] neighbor_leafs Unallocated on input. On output the neighbor
- * leafs are stored here.
+ * \param [out] neighbor_leaves Unallocated on input. On output the neighbor
+ * leaves are stored here.
* \param [in] face The index of the face across which the face neighbors
* are searched.
* \param [out] dual_face On output the face id's of the neighboring elements' faces.
- * \param [out] num_neighbors On output the number of neighbor leafs.
+ * \param [out] num_neighbors On output the number of neighbor leaves.
* \param [out] pelement_indices Unallocated on input. On output the element indices
- * of the neighbor leafs are stored here.
- * 0, 1, ... num_local_el - 1 for local leafs and
+ * of the neighbor leaves are stored here.
+ * 0, 1, ... num_local_el - 1 for local leaves and
* num_local_el , ... , num_local_el + num_ghosts - 1 for ghosts.
* \param [out] pneigh_scheme On output the eclass scheme of the neighbor elements.
* \param [in] forest_is_balanced True if we know that \a forest is balanced, false
* otherwise.
- * \note If there are no face neighbors, then *neighbor_leafs = NULL, num_neighbors = 0,
+ * \note If there are no face neighbors, then *neighbor_leaves = NULL, num_neighbors = 0,
* and *pelement_indices = NULL on output.
* \note Currently \a forest must be balanced.
* \note \a forest must be committed before calling this function.
*/
void
t8_forest_leaf_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *leaf,
- t8_element_t **pneighbor_leafs[], int face, int *dual_faces[], int *num_neighbors,
+ t8_element_t **pneighbor_leaves[], int face, int *dual_faces[], int *num_neighbors,
t8_locidx_t **pelement_indices, t8_eclass_scheme_c **pneigh_scheme,
int forest_is_balanced);
+void
+t8_forest_leaf_face_neighbors_ext (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *leaf,
+ t8_element_t **pneighbor_leaves[], int face, int *dual_faces[], int *num_neighbors,
+ t8_locidx_t **pelement_indices, t8_eclass_scheme_c **pneigh_scheme,
+ int forest_is_balanced, t8_gloidx_t *gneigh_tree);
+
/** Exchange ghost information of user defined element data.
* \param[in] forest The forest. Must be committed.
* \param[in] element_data An array of length num_local_elements + num_ghosts
@@ -610,7 +631,7 @@ t8_forest_get_tree_vertices (t8_forest_t forest, t8_locidx_t ltreeid);
* of this tree.
*/
t8_element_array_t *
-t8_forest_tree_get_leafs (const t8_forest_t forest, const t8_locidx_t ltree_id);
+t8_forest_tree_get_leaves (const t8_forest_t forest, const t8_locidx_t ltree_id);
/** Return a cmesh associated to a forest.
* \param [in] forest The forest.
@@ -740,27 +761,6 @@ t8_forest_element_face_neighbor (t8_forest_t forest, t8_locidx_t ltreeid, const
void
t8_forest_iterate (t8_forest_t forest);
-/** Query whether a given point lies inside an element or not. For bilinearly interpolated elements.
- * \note For 2D quadrilateral elements this function is only an approximation. It is correct
- * if the four vertices lie in the same plane, but it may produce only approximate results if
- * the vertices do not lie in the same plane.
- * \param [in] forest The forest.
- * \param [in] ltree_id The forest local id of the tree in which the element is.
- * \param [in] element The element.
- * \param [in] point 3-dimensional coordinates of the point to check
- * \param [in] tolerance tolerance that we allow the point to not exactly match the element.
- * If this value is larger we detect more points.
- * If it is zero we probably do not detect points even if they are inside
- * due to rounding errors.
- * \return True (non-zero) if \a point lies within \a element, false otherwise.
- * The return value is also true if the point lies on the element boundary.
- * Thus, this function may return true for different leaf elements, if they
- * are neighbors and the point lies on the common boundary.
- */
-int
-t8_forest_element_point_inside (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element,
- const double point[3], const double tolerance);
-
/** Query whether a batch of points lies inside an element. For bilinearly interpolated elements.
* \note For 2D quadrilateral elements this function is only an approximation. It is correct
* if the four vertices lie in the same plane, but it may produce only approximate results if
@@ -780,8 +780,8 @@ t8_forest_element_point_inside (t8_forest_t forest, t8_locidx_t ltreeid, const t
* due to rounding errors.
*/
void
-t8_forest_element_point_batch_inside (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element,
- const double *points, int num_points, int *is_inside, const double tolerance);
+t8_forest_element_points_inside (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element,
+ const double *points, int num_points, int *is_inside, const double tolerance);
/* TODO: if set level and partition/adapt/balance all give NULL, then
* refine uniformly and partition/adapt/balance the unfiform forest. */
diff --git a/src/t8_forest/t8_forest_ghost.cxx b/src/t8_forest/t8_forest_ghost.cxx
index 55c3ff2d17..64ba73fb77 100644
--- a/src/t8_forest/t8_forest_ghost.cxx
+++ b/src/t8_forest/t8_forest_ghost.cxx
@@ -506,7 +506,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 *leafs, const t8_locidx_t tree_leaf_index,
+ 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)
{
@@ -596,7 +596,7 @@ t8_forest_ghost_search_boundary (t8_forest_t forest, t8_locidx_t ltreeid, const
new_bounds[iface * 2] = lower;
new_bounds[iface * 2 + 1] = upper;
if (lower == upper && lower == forest->mpirank) {
- /* All neighbor leafs at this face are owned by the current rank */
+ /* All neighbor leaves at this face are owned by the current rank */
faces_totally_owned = faces_totally_owned && 1;
}
else {
@@ -625,7 +625,7 @@ t8_forest_ghost_search_boundary (t8_forest_t forest, t8_locidx_t ltreeid, const
* We do not continue the search */
#ifdef T8_ENABLE_DEBUG
if (tree_leaf_index < 0) {
- data->left_out += t8_element_array_get_count (leafs);
+ data->left_out += t8_element_array_get_count (leaves);
}
#endif
return 0;
diff --git a/src/t8_forest/t8_forest_iterate.cxx b/src/t8_forest/t8_forest_iterate.cxx
index c4dd6facd3..606f7613b0 100644
--- a/src/t8_forest/t8_forest_iterate.cxx
+++ b/src/t8_forest/t8_forest_iterate.cxx
@@ -86,14 +86,14 @@ t8_forest_iterate_faces (t8_forest_t forest, t8_locidx_t ltreeid, const t8_eleme
int child_face, num_face_children, iface;
int *child_indices;
size_t *split_offsets, indexa, indexb, elem_count;
- t8_element_array_t face_child_leafs;
+ t8_element_array_t face_child_leaves;
T8_ASSERT (t8_forest_is_committed (forest));
T8_ASSERT (0 <= ltreeid && ltreeid < t8_forest_get_num_local_trees (forest));
elem_count = t8_element_array_get_count (leaf_elements);
if (elem_count == 0) {
- /* There are no leafs left, so we have nothing to do */
+ /* There are no leaves left, so we have nothing to do */
return;
}
eclass = t8_forest_get_tree_class (forest, ltreeid);
@@ -131,20 +131,20 @@ t8_forest_iterate_faces (t8_forest_t forest, t8_locidx_t ltreeid, const t8_eleme
split_offsets = T8_ALLOC (size_t, ts->t8_element_num_children (element) + 1);
/* Compute the face children */
ts->t8_element_children_at_face (element, face, face_children, num_face_children, child_indices);
- /* Split the leafs array in portions belonging to the children of element */
+ /* Split the leaves array in portions belonging to the children of element */
t8_forest_split_array (element, leaf_elements, split_offsets);
for (iface = 0; iface < num_face_children; iface++) {
/* Check if there are any leaf elements for this face child */
indexa = split_offsets[child_indices[iface]]; /* first leaf of this face child */
indexb = split_offsets[child_indices[iface] + 1]; /* first leaf of next child */
if (indexa < indexb) {
- /* There exist leafs of this face child in leaf_elements,
- * we construct an array of these leafs */
- t8_element_array_init_view (&face_child_leafs, leaf_elements, indexa, indexb - indexa);
+ /* There exist leaves of this face child in leaf_elements,
+ * we construct an array of these leaves */
+ t8_element_array_init_view (&face_child_leaves, leaf_elements, indexa, indexb - indexa);
/* Compute the corresponding face number of this face child */
child_face = ts->t8_element_face_child_face (element, face, iface);
/* Enter the recursion */
- t8_forest_iterate_faces (forest, ltreeid, face_children[iface], child_face, &face_child_leafs, user_data,
+ t8_forest_iterate_faces (forest, ltreeid, face_children[iface], child_face, &face_child_leaves, user_data,
indexa + tree_lindex_of_first_leaf, callback);
}
}
@@ -185,7 +185,7 @@ t8_forest_search_recursion (t8_forest_t forest, const t8_locidx_t ltreeid, t8_el
const size_t elem_count = t8_element_array_get_count (leaf_elements);
if (elem_count == 0) {
- /* There are no leafs left, so we have nothing to do */
+ /* There are no leaves left, so we have nothing to do */
return;
}
const size_t num_active = queries == NULL ? 0 : active_queries->elem_count;
@@ -260,19 +260,19 @@ t8_forest_search_recursion (t8_forest_t forest, const t8_locidx_t ltreeid, t8_el
size_t *split_offsets = T8_ALLOC (size_t, num_children + 1);
/* Compute the children */
ts->t8_element_children (element, num_children, children);
- /* Split the leafs array in portions belonging to the children of element */
+ /* Split the leaves array in portions belonging to the children of element */
t8_forest_split_array (element, leaf_elements, split_offsets);
for (int ichild = 0; ichild < num_children; ichild++) {
/* Check if there are any leaf elements for this child */
const size_t indexa = split_offsets[ichild]; /* first leaf of this child */
const size_t indexb = split_offsets[ichild + 1]; /* first leaf of next child */
if (indexa < indexb) {
- t8_element_array_t child_leafs;
- /* There exist leafs of this child in leaf_elements,
- * we construct an array of these leafs */
- t8_element_array_init_view (&child_leafs, leaf_elements, indexa, indexb - indexa);
+ t8_element_array_t child_leaves;
+ /* There exist leaves of this child in leaf_elements,
+ * we construct an array of these leaves */
+ t8_element_array_init_view (&child_leaves, leaf_elements, indexa, indexb - indexa);
/* Enter the recursion */
- t8_forest_search_recursion (forest, ltreeid, children[ichild], ts, &child_leafs,
+ t8_forest_search_recursion (forest, ltreeid, children[ichild], ts, &child_leaves,
indexa + tree_lindex_of_first_leaf, search_fn, query_fn, queries, new_active_queries);
}
}
@@ -294,7 +294,7 @@ t8_forest_search_tree (t8_forest_t forest, t8_locidx_t ltreeid, t8_forest_search
/* Get the element class, scheme and leaf elements of this tree */
const t8_eclass_t eclass = t8_forest_get_eclass (forest, ltreeid);
const t8_eclass_scheme_c *ts = t8_forest_get_eclass_scheme (forest, eclass);
- t8_element_array_t *leaf_elements = t8_forest_tree_get_leafs (forest, ltreeid);
+ t8_element_array_t *leaf_elements = t8_forest_tree_get_leaves (forest, ltreeid);
/* assert for empty tree */
T8_ASSERT (t8_element_array_get_count (leaf_elements) >= 0);
diff --git a/src/t8_forest/t8_forest_iterate.h b/src/t8_forest/t8_forest_iterate.h
index 79f37c6fe6..b90537beb3 100644
--- a/src/t8_forest/t8_forest_iterate.h
+++ b/src/t8_forest/t8_forest_iterate.h
@@ -66,10 +66,10 @@ void
t8_forest_split_array (const t8_element_t *element, t8_element_array_t *leaf_elements, size_t *offsets);
/* TODO: comment */
-/* Iterate over all leafs of an element that touch a given face of the element */
+/* Iterate over all leaves of an element that touch a given face of the element */
/* Callback is called in each recursive step with element as input.
* leaf_index is only not negative if element is a leaf, in which case it indicates
- * the index of the leaf in the leafs of the tree. If it is negative, it is
+ * the index of the leaf in the leaves of the tree. If it is negative, it is
* - (index + 1) */
/* Top-down iteration and callback is called on each intermediate level.
* If it returns false, the current element is not traversed further */
diff --git a/src/t8_forest/t8_forest_private.h b/src/t8_forest/t8_forest_private.h
index 09add74644..160c08d75d 100644
--- a/src/t8_forest/t8_forest_private.h
+++ b/src/t8_forest/t8_forest_private.h
@@ -299,7 +299,7 @@ t8_forest_element_owners_bounds (t8_forest_t forest, t8_gloidx_t gtreeid, const
t8_eclass_t eclass, int *lower, int *upper);
/** Constant time algorithm to compute lower and upper bounds for the owner
- * processes of the face leafs of a given element.
+ * processes of the face leaves of a given element.
* \param [in] forest The forest.
* \param [in] gtreeid The global id of the tree in which the element lies.
* \param [in] element The element to look for.
@@ -381,8 +381,8 @@ t8_forest_element_half_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid,
t8_element_t *neighs[], t8_eclass_scheme_c *neigh_scheme, int face,
int num_neighs, int dual_faces[]);
-/** Iterate over all leafs of a forest and for each face compute the face neighbor
- * leafs with \ref t8_forest_leaf_face_neighbors and print their local element ids.
+/** Iterate over all leaves of a forest and for each face compute the face neighbor
+ * leaves with \ref t8_forest_leaf_face_neighbors and print their local element ids.
* This function is meant for debugging only.
* \param [in] forest The forest.
* \note Currently \a forest must be balanced.
diff --git a/src/t8_forest/t8_forest_vtk.cxx b/src/t8_forest/t8_forest_vtk.cxx
index 40a3372de6..aab57e42f3 100644
--- a/src/t8_forest/t8_forest_vtk.cxx
+++ b/src/t8_forest/t8_forest_vtk.cxx
@@ -151,8 +151,8 @@ const double t8_forest_vtk_point_to_element_ref_coords[T8_ECLASS_COUNT][T8_FORES
{ -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, 1, 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 }, { 0, 1, 0.5 },
+ { 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 },
@@ -1275,9 +1275,6 @@ t8_forest_vtk_write_file (t8_forest_t forest, const char *fileprefix, const int
}
T8_ASSERT (forest->ghosts != NULL || !write_ghosts);
- /* Currently we only support output in ascii format, not binary */
- T8_ASSERT (T8_VTK_ASCII == 1);
-
/* process 0 creates the .pvtu file */
if (forest->mpirank == 0) {
if (t8_write_pvtu (fileprefix, forest->mpisize, write_treeid, write_mpirank, write_level, write_element_id,
diff --git a/src/t8_geometry/t8_geometry.cxx b/src/t8_geometry/t8_geometry.cxx
index c4c61b6973..8ba392d219 100644
--- a/src/t8_geometry/t8_geometry.cxx
+++ b/src/t8_geometry/t8_geometry.cxx
@@ -260,7 +260,7 @@ t8_geom_handler_get_unique_geometry (const t8_geometry_handler_t *geom_handler)
T8_ASSERT (t8_geom_handler_get_num_geometries (geom_handler) == 1);
sc_array *geometries = (sc_array *) &geom_handler->registered_geometries;
- return *(const t8_geometry_c **) sc_array_index_int (geometries, 0);
+ return *(t8_geometry_c **) sc_array_index_int (geometries, 0);
}
void
diff --git a/src/t8_geometry/t8_geometry.h b/src/t8_geometry/t8_geometry.h
index 9394fedf03..d42d78ac83 100644
--- a/src/t8_geometry/t8_geometry.h
+++ b/src/t8_geometry/t8_geometry.h
@@ -41,8 +41,8 @@ typedef enum t8_geometry_type {
T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED,
/** The analytic geometry uses a user-defined analytic function to map into the physical domain. */
T8_GEOMETRY_TYPE_ANALYTIC,
- /** The OCC geometry uses OCC CAD shapes to map trees exactly to the underlying CAD model. */
- T8_GEOMETRY_TYPE_OCC,
+ /** The opencascade geometry uses CAD shapes to map trees exactly to the underlying CAD model. */
+ T8_GEOMETRY_TYPE_CAD,
/** This is no geometry type but can be used as the number of geometry types. */
T8_GEOMETRY_TYPE_COUNT,
/** This is no geometry type but is used for every geometry, where no type is defined */
diff --git a/src/t8_geometry/t8_geometry_base.hxx b/src/t8_geometry/t8_geometry_base.hxx
index ee3d47ef2b..e95564af11 100644
--- a/src/t8_geometry/t8_geometry_base.hxx
+++ b/src/t8_geometry/t8_geometry_base.hxx
@@ -30,6 +30,7 @@
#include
#include
+#include
#include
T8_EXTERN_C_BEGIN ();
@@ -96,6 +97,52 @@ struct t8_geometry
t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid)
= 0;
+ /** Query whether a batch of points lies inside an element.
+ * \param [in] forest The forest.
+ * \param [in] ltree_id The forest local id of the tree in which the element is.
+ * \param [in] element The element.
+ * \param [in] points 3-dimensional coordinates of the points to check
+ * \param [in] num_points The number of points to check
+ * \param [in, out] is_inside An array of length \a num_points, filled with 0/1 on output. True (non-zero) if a \a point
+ * lies within an \a element, false otherwise. The return value is also true if the point
+ * lies on the element boundary. Thus, this function may return true for different leaf
+ * elements, if they are neighbors and the point lies on the common boundary.
+ * \param [in] tolerance Tolerance that we allow the point to not exactly match the element.
+ * If this value is larger we detect more points.
+ * If it is zero we probably do not detect points even if they are inside
+ * due to rounding errors.
+ */
+ virtual 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
+ {
+ SC_ABORTF ("Function not yet implemented");
+ };
+
+ /** Query whether a single points lies inside an element.
+ * \param [in] forest The forest.
+ * \param [in] ltree_id The forest local id of the tree in which the element is.
+ * \param [in] element The element.
+ * \param [in] points 3-dimensional coordinates of the points to check
+ * \param [in] num_points The number of points to check
+ * \param [in, out] is_inside An array of length \a num_points, filled with 0/1 on output. True (non-zero) if a \a point
+ * lies within an \a element, false otherwise. The return value is also true if the point
+ * lies on the element boundary. Thus, this function may return true for different leaf
+ * elements, if they are neighbors and the point lies on the common boundary.
+ * \param [in] tolerance Tolerance that we allow the point to not exactly match the element.
+ * If this value is larger we detect more points.
+ * If it is zero we probably do not detect points even if they are inside
+ * due to rounding errors.
+ */
+ inline int
+ t8_geom_point_inside_element (t8_forest_t forest, t8_locidx_t ltreeid, const t8_element_t *element,
+ const double *points, const int num_points, const double tolerance) const
+ {
+ int is_inside = 0;
+ t8_geom_point_batch_inside_element (forest, ltreeid, element, points, 1, &is_inside, tolerance);
+ return is_inside;
+ }
/**
* Get the dimension of this geometry.
* \return The dimension.
diff --git a/src/t8_geometry/t8_geometry_helpers.c b/src/t8_geometry/t8_geometry_helpers.c
index 2a8738b5c3..d70a77771e 100644
--- a/src/t8_geometry/t8_geometry_helpers.c
+++ b/src/t8_geometry/t8_geometry_helpers.c
@@ -23,7 +23,7 @@
#include
#include
#include
-#include
+#include
void
t8_geom_linear_interpolation (const double *coefficients, const double *corner_values, const int corner_value_dim,
@@ -298,19 +298,16 @@ t8_geom_get_ref_intersection (int edge_index, const double *ref_coords, double r
break;
}
else {
- /* intersectionX = (x1y2-y1x2)(x3-x4)-(x1-x2)(x3y4-y3x4)
- * /(x1-x2)(y3-y4)-(y1-y2)(x3-x4)
- * intersectionY = (x1y2-y1x2)(y3-y4)-(y1-y2)(x3y4-y3x4)
- * /(x1-x2)(y3-y4)-(y1-y2)(x3-x4)
- *
- * x1=0 y1=0 x2=1 y2=1 x3=ref_coords[0] y3=ref_coords[1] x4=ref_opposite_vertex[0] y4=ref_opposite_vertex[1]
- *
- * Since the intersection point lies on edge 2, which has a slope of 1, the x and the y value has to be equal
- */
- ref_intersection[0] = ref_intersection[1]
- = ((ref_coords[0] * ref_opposite_vertex[1] - ref_coords[1] * ref_opposite_vertex[0])
- / -(ref_coords[1] - ref_opposite_vertex[1])
- + (ref_coords[0] - ref_opposite_vertex[0]));
+ /* To find the ref_intersection for edge 1, we calculate the intersection of edge 1 with a stright line from
+ * vertex 1, through the reference point and reaching until x = 0. The y-axis intersect for that line is at
+ * slope * (-1).
+ * Since the the ref_intersection lies on edge 1, which has a slope of 1,
+ * the x and y coordinates have to be the same.
+ * The intersection is calculated via the line equations:
+ * edge 1: y = ax + c
+ * line: y = bx + d
+ * intersection: (d - c) / (a - b) */
+ ref_intersection[0] = ref_intersection[1] = -ref_slope / (1 - ref_slope);
break;
}
case 2: /* edge 2 */
@@ -373,3 +370,129 @@ t8_geom_get_triangle_scaling_factor (int edge_index, const double *tree_vertices
double scaling_factor = dist_ref / dist_intersection;
return scaling_factor;
}
+
+int
+t8_vertex_point_inside (const double vertex_coords[3], const double point[3], const double tolerance)
+{
+ T8_ASSERT (tolerance > 0);
+ if (t8_vec_dist (vertex_coords, point) > tolerance) {
+ return 0;
+ }
+ return 1;
+}
+
+int
+t8_line_point_inside (const double *p_0, const double *vec, const double *point, const double tolerance)
+{
+ T8_ASSERT (tolerance > 0);
+ double b[3];
+ /* b = p - p_0 */
+ t8_vec_axpyz (p_0, point, b, -1);
+ double x = 0; /* Initialized to prevent compiler warning. */
+ int i;
+ /* So x is the solution to
+ * vec * x = b.
+ * We can compute it as
+ * x = b[i] / vec[i]
+ * if any vec[i] is not 0.
+ *
+ * Otherwise the line is degenerated (which should not happen).
+ */
+ for (i = 0; i < 3; ++i) {
+ if (vec[i] != 0) {
+ x = b[i] / vec[i];
+ break; /* found a non-zero coordinate. We can stop now. */
+ }
+ }
+
+ /* If i == 3 here, then vec = 0 and hence the line is degenerated. */
+ SC_CHECK_ABORT (i < 3, "Degenerated line element. Both endpoints are the same.");
+
+ if (x < -tolerance || x > 1 + tolerance) {
+ /* x is not an admissible solution. */
+ return 0;
+ }
+
+ /* we can check whether x gives us a solution by
+ * checking whether
+ * vec * x = b
+ * is actually true.
+ */
+ double vec_check[3] = { vec[0], vec[1], vec[2] };
+ t8_vec_ax (vec_check, x);
+ if (t8_vec_dist (vec_check, b) > tolerance) {
+ /* Point does not lie on the line. */
+ return 0;
+ }
+ /* The point is on the line. */
+ return 1;
+}
+
+int
+t8_triangle_point_inside (const double p_0[3], const double v[3], const double w[3], const double point[3],
+ const double tolerance)
+{
+ /* A point p is inside the triangle that is spanned
+ * by the point p_0 and vectors v and w if and only if the linear system
+ * vx + wy = point - p_0
+ * has a solution with 0 <= x,y and x + y <= 1.
+ *
+ * We check whether such a solution exists by computing
+ * certain determinants of 2x2 submatrizes of the 3x3 matrix
+ *
+ * | v w e_3 | with v = p_1 - p_0, w = p_2 - p_0, and e_3 = (0 0 1)^t (third unit vector)
+ */
+
+ T8_ASSERT (tolerance > 0); /* negative values and zero are not allowed */
+ double b[3];
+ /* b = point - p_0 */
+ t8_vec_axpyz (p_0, point, b, -1);
+
+ /* Let d = det (v w e_3) */
+ const double det_vwe3 = v[0] * w[1] - v[1] * w[0];
+
+ /* The system has a solution, we need to compute it and
+ * check whether 0 <= x,y and x + y <= 1 */
+ /* x = det (b w e_3) / d
+ * y = det (v b e_3) / d
+ */
+ const double x = (b[0] * w[1] - b[1] * w[0]) / det_vwe3;
+ const double y = (v[0] * b[1] - v[1] * b[0]) / det_vwe3;
+
+ if (x < -tolerance || y < -tolerance || x + y > 1 + tolerance) {
+ /* The solution is not admissible.
+ * x < 0 or y < 0 or x + y > 1 */
+ return 0;
+ }
+ /* The solution may be admissible, but we have to
+ * check whether the result of
+ * (p_1 - p_0)x + (p_2 - p_0)y ( = vx + wy)
+ * is actually p - p_0.
+ * Since the system of equations is overrepresented (3 equations, 2 variables)
+ * this may actually break.
+ * If it breaks, it will break in the z coordinate of the result.
+ */
+ const double z = v[2] * x + w[2] * y;
+ /* Must match the last coordinate of b = p - p_0 */
+ if (fabs (z - b[2]) > tolerance) {
+ /* Does not match. Point lies outside. */
+ return 0;
+ }
+ /* All checks passed. Point lies inside. */
+ return 1;
+}
+
+int
+t8_plane_point_inside (const double point_on_face[3], const double face_normal[3], const double point[3])
+{
+ /* Set x = x - p */
+ double pof[3] = { point_on_face[0], point_on_face[1], point_on_face[2] };
+ t8_vec_axpy (point, pof, -1);
+ /* Compute */
+ const double dot_product = t8_vec_dot (pof, face_normal);
+ if (dot_product < 0) {
+ /* The point is on the wrong side of the plane */
+ return 0;
+ }
+ return 1;
+}
\ No newline at end of file
diff --git a/src/t8_geometry/t8_geometry_helpers.h b/src/t8_geometry/t8_geometry_helpers.h
index 5b3eac2d27..498ed9b8b3 100644
--- a/src/t8_geometry/t8_geometry_helpers.h
+++ b/src/t8_geometry/t8_geometry_helpers.h
@@ -132,6 +132,53 @@ double
t8_geom_get_triangle_scaling_factor (int edge_index, const double *tree_vertices, const double *glob_intersection,
const double *glob_ref_point);
+/** Check if a point lies inside a vertex
+ *
+ * \param[in] vertex_coords The coordinates of the vertex
+ * \param[in] point The coordinates of the point to check
+ * \param[in] tolerance A double > 0 defining the tolerance
+ * \return 0 if the point is outside, 1 otherwise.
+ */
+int
+t8_vertex_point_inside (const double vertex_coords[3], const double point[3], const double tolerance);
+
+/**
+ * Check if a point is inside a line that is defined by a starting point \a p_0
+ * and a vector \a vec
+ *
+ * \param[in] p_0 Starting point of the line
+ * \param[in] vec Direction of the line (not normalized)
+ * \param[in] point The coordinates of the point to check
+ * \param[in] tolerance A double > 0 defining the tolerance
+ * \return 0 if the point is outside, 1 otherwise.
+ */
+int
+t8_line_point_inside (const double *p_0, const double *vec, const double *point, const double tolerance);
+
+/**
+ * Check if a point is inside of a triangle described by a point \a p_0 and two vectors \a v and \a w.
+ *
+ * \param[in] p_0 The first vertex of a triangle
+ * \param[in] v The vector from p_0 to p_1 (second vertex in the triangle)
+ * \param[in] w The vector from p_0 to p_2 (third vertex in the triangle)
+ * \param[in] point The coordinates of the point to check
+ * \param[in] tolerance A double > 0 defining the tolerance
+ * \return 0 if the point is outside, 1 otherwise.
+ */
+int
+t8_triangle_point_inside (const double p_0[3], const double v[3], const double w[3], const double point[3],
+ const double tolerance);
+
+/** Check if a point lays on the inner side of a plane of a bilinearly interpolated volume element.
+ * the plane is described by a point and the normal of the face.
+ * \param[in] point_on_face A point on the plane
+ * \param[in] face_normal The normal of the face
+ * \param[in] point The point to check
+ * \return 0 if the point is outside, 1 otherwise.
+ */
+int
+t8_plane_point_inside (const double point_on_face[3], const double face_normal[3], const double point[3]);
+
T8_EXTERN_C_END ();
#endif /* !T8_GEOMETRY_HELPERS_H! */
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 d0c56b332b..576e11bd36 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.cxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.cxx
@@ -66,10 +66,32 @@ t8_geometry_analytic::t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtre
}
}
+T8_EXTERN_C_BEGIN ();
+
+void
+t8_geometry_analytic_destroy (t8_geometry_c **geom)
+{
+ T8_ASSERT (geom != NULL);
+
+ delete *geom;
+ *geom = NULL;
+}
+
+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,
+ const void *user_data)
+{
+ t8_geometry_analytic *geom = new t8_geometry_analytic (dim, name, analytical, jacobian, load_tree_data, user_data);
+ return (t8_geometry_c *) geom;
+}
+
void
-t8_geom_load_tree_data_vertices (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const void **vertices_out)
+t8_geom_load_tree_data_vertices (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const void **user_data)
{
T8_ASSERT (t8_cmesh_is_committed (cmesh));
t8_locidx_t ltreeid = t8_cmesh_get_local_id (cmesh, gtreeid);
- *vertices_out = t8_cmesh_get_tree_vertices (cmesh, ltreeid);
+ *user_data = t8_cmesh_get_tree_vertices (cmesh, ltreeid);
}
+
+T8_EXTERN_C_END ();
diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.h
new file mode 100644
index 0000000000..72a3a26818
--- /dev/null
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.h
@@ -0,0 +1,96 @@
+/*
+ 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.
+*/
+
+/** \file t8_geometry_analytic.h
+ * This header provides the C interface to create an analytical geometry.
+ */
+
+#ifndef T8_GEOMETRY_ANALYTIC_H
+#define T8_GEOMETRY_ANALYTIC_H
+
+/**
+ * Definition of an analytic geometry function.
+ * This function maps reference coordinates to physical
+ * coordinates.
+ * \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 dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$.
+ * \param [in] num_coords
+ * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3.
+ * \param [in] tree_data The data of the current tree as loaded by a \ref t8_geom_load_tree_data_fn.
+ * \param [in] user_data The user data pointer stored in the geometry.
+ */
+typedef void (*t8_geom_analytic_fn) (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
+ const size_t num_coords, double *out_coords, const void *tree_data,
+ const void *user_data);
+
+/**
+ * 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] 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$).
+ * \param [in] tree_data The data of the current tree as loaded by a \ref t8_geom_load_tree_data_fn.
+ * \param [in] user_data The user data pointer stored in the geometry.
+ */
+typedef void (*t8_geom_analytic_jacobian_fn) (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
+ const size_t num_coords, double *jacobian, const void *tree_data,
+ const void *user_data);
+
+/**
+ * Definition for the load tree data function.
+ * \param [in] cmesh The cmesh.
+ * \param [in] gtreeid The global tree (of the cmesh) in which the reference point is.
+ * \param [in] tree_data The data of the trees.
+ */
+typedef void (*t8_geom_load_tree_data_fn) (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const void **tree_data);
+
+T8_EXTERN_C_BEGIN ();
+
+/** Destroy a geometry analytic object.
+ * \param [in,out] geom A pointer to a geometry object. Set to NULL on output.
+ */
+void
+t8_geometry_analytic_destroy (t8_geometry_c **geom);
+
+/** Create a new analytical geometry.
+ * \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,
+ 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.
+ */
+void
+t8_geom_load_tree_data_vertices (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const void **user_data);
+
+T8_EXTERN_C_END ();
+
+#endif /* T8_GEOMETRY_ANALYTIC_H */
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 5927c53927..bf44ffe83c 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.hxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_analytic.hxx
@@ -21,7 +21,9 @@
*/
/** \file t8_geometry_analytic.hxx
- * TODO: Add description
+ * This geometry implements analytic geometries. It provides an interface to
+ * define custom functions for evaluation, Jacobians and the loading of the
+ * tree data.
*/
#ifndef T8_GEOMETRY_ANALYTIC_HXX
@@ -30,40 +32,7 @@
#include
#include
#include
-
-/**
- * Definition of an analytic geometry function.
- * This function maps reference coordinates to physical
- * coordinates.
- * \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 dimension x \a num_coords many entries, specifying a point in \f$ [0,1]^\mathrm{dim} \f$.
- * \param [in] num_coords
- * \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3.
- * \param [in] tree_data The data of the current tree as loaded by a \ref t8_geom_load_tree_data_fn.
- * \param [in] user_data The user data pointer stored in the geometry.
- */
-typedef void (*t8_geom_analytic_fn) (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
- const size_t num_coords, double *out_coords, const void *tree_data,
- const void *user_data);
-
-/**
- * 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] 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$).
- * \param [in] tree_data The data of the current tree as loaded by a \ref t8_geom_load_tree_data_fn.
- * \param [in] user_data The user data pointer stored in the geometry.
- */
-typedef void (*t8_geom_analytic_jacobian_fn) (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
- const size_t num_coords, double *jacobian, const void *tree_data,
- const void *user_data);
-
-/* TODO: Document. */
-typedef void (*t8_geom_load_tree_data_fn) (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const void **tree_data);
+#include
struct t8_geometry_analytic: public t8_geometry
{
@@ -129,6 +98,23 @@ struct t8_geometry_analytic: public t8_geometry
t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
double *jacobian) const;
+ /**
+ * \param[in] forest The forest of the element.
+ * \param[in] ltreeid The local tree id of the element's tree
+ * \param[in] element The element
+ * \param[in] points points to check
+ * \param[in] num_points Number of points to check
+ * \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
+ 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)
+ {
+ SC_ABORTF ("Function not yet implemented");
+ }
+
/** 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
@@ -159,8 +145,4 @@ struct t8_geometry_analytic: public t8_geometry
* and modified via \ref t8_geom_analytic_get_user_data. */
};
-/* TODO: Document */
-void
-t8_geom_load_tree_data_vertices (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const void **vertices_out);
-
#endif /* !T8_GEOMETRY_ANALYTICAL_HXX! */
diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.cxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx
similarity index 82%
rename from src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.cxx
rename to src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx
index a7f7b37a89..7b3afb315e 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.cxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.cxx
@@ -21,8 +21,8 @@
*/
#include
-#include
-#include
+#include
+#include
#include
#include
@@ -41,7 +41,7 @@
#include
#include
-t8_geometry_occ::t8_geometry_occ (int dim, const char *fileprefix, const char *name_in)
+t8_geometry_cad::t8_geometry_cad (int dim, const char *fileprefix, const char *name_in)
{
T8_ASSERT (0 <= dim && dim <= 3);
@@ -54,52 +54,52 @@ t8_geometry_occ::t8_geometry_occ (int dim, const char *fileprefix, const char *n
if (is.is_open () == false) {
SC_ABORTF ("Cannot find the file %s.brep.\n", fileprefix);
}
- BRepTools::Read (occ_shape, is, builder);
+ BRepTools::Read (cad_shape, is, builder);
is.close ();
- if (occ_shape.IsNull ()) {
+ if (cad_shape.IsNull ()) {
SC_ABORTF ("Could not read brep file or brep file contains no shape. "
- "The OCC file may be written with a newer OCC version. "
- "Linked OCC version: %s",
+ "The cad file may be written with a newer cad version. "
+ "Linked cad version: %s",
OCC_VERSION_COMPLETE);
}
- TopExp::MapShapes (occ_shape, TopAbs_VERTEX, occ_shape_vertex_map);
- TopExp::MapShapes (occ_shape, TopAbs_EDGE, occ_shape_edge_map);
- TopExp::MapShapes (occ_shape, TopAbs_FACE, occ_shape_face_map);
- TopExp::MapShapesAndUniqueAncestors (occ_shape, TopAbs_VERTEX, TopAbs_EDGE, occ_shape_vertex2edge_map);
- TopExp::MapShapesAndUniqueAncestors (occ_shape, TopAbs_EDGE, TopAbs_FACE, occ_shape_edge2face_map);
+ TopExp::MapShapes (cad_shape, TopAbs_VERTEX, cad_shape_vertex_map);
+ TopExp::MapShapes (cad_shape, TopAbs_EDGE, cad_shape_edge_map);
+ TopExp::MapShapes (cad_shape, TopAbs_FACE, cad_shape_face_map);
+ TopExp::MapShapesAndUniqueAncestors (cad_shape, TopAbs_VERTEX, TopAbs_EDGE, cad_shape_vertex2edge_map);
+ TopExp::MapShapesAndUniqueAncestors (cad_shape, TopAbs_EDGE, TopAbs_FACE, cad_shape_edge2face_map);
}
-t8_geometry_occ::t8_geometry_occ (int dim, const TopoDS_Shape occ_shape, const char *name_in)
+t8_geometry_cad::t8_geometry_cad (int dim, const TopoDS_Shape cad_shape, const char *name_in)
{
T8_ASSERT (0 <= dim && dim <= 3);
name = name_in;
dimension = dim;
- if (occ_shape.IsNull ()) {
+ if (cad_shape.IsNull ()) {
SC_ABORTF ("Shape is null. \n");
}
- TopExp::MapShapes (occ_shape, TopAbs_VERTEX, occ_shape_vertex_map);
- TopExp::MapShapes (occ_shape, TopAbs_EDGE, occ_shape_edge_map);
- TopExp::MapShapes (occ_shape, TopAbs_FACE, occ_shape_face_map);
- TopExp::MapShapesAndUniqueAncestors (occ_shape, TopAbs_VERTEX, TopAbs_EDGE, occ_shape_vertex2edge_map);
- TopExp::MapShapesAndUniqueAncestors (occ_shape, TopAbs_EDGE, TopAbs_FACE, occ_shape_edge2face_map);
+ TopExp::MapShapes (cad_shape, TopAbs_VERTEX, cad_shape_vertex_map);
+ TopExp::MapShapes (cad_shape, TopAbs_EDGE, cad_shape_edge_map);
+ TopExp::MapShapes (cad_shape, TopAbs_FACE, cad_shape_face_map);
+ TopExp::MapShapesAndUniqueAncestors (cad_shape, TopAbs_VERTEX, TopAbs_EDGE, cad_shape_vertex2edge_map);
+ TopExp::MapShapesAndUniqueAncestors (cad_shape, TopAbs_EDGE, TopAbs_FACE, cad_shape_edge2face_map);
}
void
-t8_geometry_occ::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
+t8_geometry_cad::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
const size_t num_coords, double *out_coords) const
{
if (num_coords != 1)
SC_ABORT ("Error: Batch computation of geometry not yet supported.");
switch (active_tree_class) {
case T8_ECLASS_TRIANGLE:
- t8_geometry_occ::t8_geom_evaluate_occ_triangle (cmesh, gtreeid, ref_coords, 1, out_coords);
+ t8_geometry_cad::t8_geom_evaluate_cad_triangle (cmesh, gtreeid, ref_coords, 1, out_coords);
break;
case T8_ECLASS_QUAD:
- t8_geometry_occ::t8_geom_evaluate_occ_quad (cmesh, gtreeid, ref_coords, 1, out_coords);
+ t8_geometry_cad::t8_geom_evaluate_cad_quad (cmesh, gtreeid, ref_coords, 1, out_coords);
break;
case T8_ECLASS_HEX:
- t8_geometry_occ::t8_geom_evaluate_occ_hex (cmesh, gtreeid, ref_coords, 1, out_coords);
+ t8_geometry_cad::t8_geom_evaluate_cad_hex (cmesh, gtreeid, ref_coords, 1, out_coords);
break;
default:
SC_ABORTF ("Error: Curved %s geometry not yet implemented. \n", t8_eclass_to_string[active_tree_class]);
@@ -107,7 +107,7 @@ t8_geometry_occ::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const
}
void
-t8_geometry_occ::t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
+t8_geometry_cad::t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
const size_t num_coords, double *jacobian_out) const
{
if (num_coords != 1)
@@ -129,8 +129,8 @@ t8_geometry_occ::t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreei
in1[dim] -= 0.5 * h;
in2[dim] += 0.5 * h;
}
- t8_geometry_occ::t8_geom_evaluate (cmesh, gtreeid, in1, 1, out1);
- t8_geometry_occ::t8_geom_evaluate (cmesh, gtreeid, in2, 1, out2);
+ t8_geometry_cad::t8_geom_evaluate (cmesh, gtreeid, in1, 1, out1);
+ t8_geometry_cad::t8_geom_evaluate (cmesh, gtreeid, in2, 1, out2);
for (int dim2 = 0; dim2 < 3; ++dim2) {
jacobian_out[dim * 3 + dim2] = (out2[dim2] - out1[dim2]) / h;
}
@@ -138,17 +138,18 @@ t8_geometry_occ::t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreei
}
inline void
-t8_geometry_occ::t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid)
+t8_geometry_cad::t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid)
{
+ const t8_locidx_t ltreeid = t8_cmesh_get_local_id (cmesh, gtreeid);
t8_geometry_with_vertices::t8_geom_load_tree_data (cmesh, gtreeid);
- edges = (const int *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_OCC_EDGE_ATTRIBUTE_KEY, gtreeid);
- faces = (const int *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_OCC_FACE_ATTRIBUTE_KEY, gtreeid);
+ edges = (const int *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_CAD_EDGE_ATTRIBUTE_KEY, ltreeid);
+ faces = (const int *) t8_cmesh_get_attribute (cmesh, t8_get_package_id (), T8_CMESH_CAD_FACE_ATTRIBUTE_KEY, ltreeid);
T8_ASSERT (edges != NULL);
T8_ASSERT (faces != NULL);
}
void
-t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
+t8_geometry_cad::t8_geom_evaluate_cad_triangle (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
const size_t num_coords, double *out_coords) const
{
T8_ASSERT (active_tree_class == T8_ECLASS_TRIANGLE);
@@ -192,7 +193,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gt
#endif /* T8_ENABLE_DEBUG */
/* Retrieve surface parameters */
const double *face_parameters = (double *) t8_cmesh_get_attribute (
- cmesh, t8_get_package_id (), T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY, ltreeid);
+ cmesh, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY, ltreeid);
T8_ASSERT (face_parameters != NULL);
/* Retrieve surface_parameter in global space by triangular interpolation from ref_coords to global space */
@@ -210,7 +211,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gt
glob_intersection);
/* Get parameters of the current edge if the edge is curved */
const double *edge_parameters = (double *) t8_cmesh_get_attribute (
- cmesh, t8_get_package_id (), T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
+ cmesh, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
T8_ASSERT (edge_parameters != NULL);
/* Linear interpolation between parameters */
@@ -227,7 +228,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gt
double converted_edge_surface_parameters[2];
const int num_face_nodes = t8_eclass_num_vertices[active_tree_class];
- t8_geometry_occ::t8_geom_edge_parameter_to_face_parameters (edges[i_edge], *faces, num_face_nodes,
+ t8_geometry_cad::t8_geom_edge_parameter_to_face_parameters (edges[i_edge], *faces, num_face_nodes,
interpolated_curve_parameter, face_parameters,
converted_edge_surface_parameters);
@@ -259,8 +260,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gt
}
}
/* Retrieve surface */
- T8_ASSERT (*faces <= occ_shape_face_map.Size ());
- surface = BRep_Tool::Surface (TopoDS::Face (occ_shape_face_map.FindKey (*faces)));
+ T8_ASSERT (*faces <= cad_shape_face_map.Size ());
+ surface = BRep_Tool::Surface (TopoDS::Face (cad_shape_face_map.FindKey (*faces)));
/* Check if surface is valid */
T8_ASSERT (!surface.IsNull ());
@@ -280,7 +281,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gt
if (edges[i_edge] > 0 || edges[i_edge + num_edges] > 0) {
/* Get parameters of the current edge if the edge is curved */
const double *parameters = (double *) t8_cmesh_get_attribute (
- cmesh, t8_get_package_id (), T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
+ cmesh, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
T8_ASSERT (parameters != NULL);
double ref_intersection[2];
@@ -302,8 +303,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gt
t8_geom_linear_interpolation (&ref_intersection[0], parameters, 1, 1, &interpolated_curve_parameter);
}
/* Retrieve curve */
- T8_ASSERT (edges[i_edge] <= occ_shape_edge_map.Size ());
- curve = BRep_Tool::Curve (TopoDS::Edge (occ_shape_edge_map.FindKey (edges[i_edge])), first, last);
+ T8_ASSERT (edges[i_edge] <= cad_shape_edge_map.Size ());
+ curve = BRep_Tool::Curve (TopoDS::Edge (cad_shape_edge_map.FindKey (edges[i_edge])), first, last);
/* Check if curve is valid */
T8_ASSERT (!curve.IsNull ());
@@ -321,8 +322,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gt
t8_geom_linear_interpolation (&ref_intersection[0], parameters, 2, 1, interpolated_surface_parameters);
}
- T8_ASSERT (edges[i_edge + num_edges] <= occ_shape_face_map.Size ());
- surface = BRep_Tool::Surface (TopoDS::Face (occ_shape_face_map.FindKey (edges[i_edge + num_edges])));
+ T8_ASSERT (edges[i_edge + num_edges] <= cad_shape_face_map.Size ());
+ surface = BRep_Tool::Surface (TopoDS::Face (cad_shape_face_map.FindKey (edges[i_edge + num_edges])));
/* Check if surface is valid */
T8_ASSERT (!surface.IsNull ());
@@ -348,7 +349,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gt
}
void
-t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
+t8_geometry_cad::t8_geom_evaluate_cad_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
const size_t num_coords, double *out_coords) const
{
T8_ASSERT (active_tree_class == T8_ECLASS_QUAD);
@@ -371,7 +372,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreei
#endif /* T8_ENABLE_DEBUG */
/* Retrieve surface parameters */
const double *face_parameters = (double *) t8_cmesh_get_attribute (
- cmesh, t8_get_package_id (), T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY, ltreeid);
+ cmesh, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY, ltreeid);
T8_ASSERT (face_parameters != NULL);
/* Interpolate between surface parameters */
@@ -396,11 +397,11 @@ t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreei
const int edge_direction = 1 - edge_orthogonal_direction;
/* Retrieve edge parameters and interpolate */
const double *edge_parameters = (double *) t8_cmesh_get_attribute (
- cmesh, t8_get_package_id (), T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
+ cmesh, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
T8_ASSERT (edge_parameters != NULL);
- T8_ASSERT (edges[i_edge] <= occ_shape_edge_map.Size ());
+ T8_ASSERT (edges[i_edge] <= cad_shape_edge_map.Size ());
- curve = BRep_Tool::Curve (TopoDS::Edge (occ_shape_edge_map.FindKey (edges[i_edge])), first, last);
+ curve = BRep_Tool::Curve (TopoDS::Edge (cad_shape_edge_map.FindKey (edges[i_edge])), first, last);
/* Check if curve is valid */
T8_ASSERT (!curve.IsNull ());
@@ -412,7 +413,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreei
/* Convert edge parameter to surface parameters */
double converted_edge_surface_parameters[2];
const int num_face_nodes = t8_eclass_num_vertices[active_tree_class];
- t8_geometry_occ::t8_geom_edge_parameter_to_face_parameters (edges[i_edge], *faces, num_face_nodes,
+ t8_geometry_cad::t8_geom_edge_parameter_to_face_parameters (edges[i_edge], *faces, num_face_nodes,
interpolated_curve_parameter, face_parameters,
converted_edge_surface_parameters);
@@ -439,8 +440,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreei
}
/* Retrieve surface */
- T8_ASSERT (*faces <= occ_shape_face_map.Size ());
- surface = BRep_Tool::Surface (TopoDS::Face (occ_shape_face_map.FindKey (*faces)));
+ T8_ASSERT (*faces <= cad_shape_face_map.Size ());
+ surface = BRep_Tool::Surface (TopoDS::Face (cad_shape_face_map.FindKey (*faces)));
/* Check if surface is valid */
T8_ASSERT (!surface.IsNull ());
@@ -483,7 +484,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreei
t8_geom_linear_interpolation (&ref_coords[edge_direction], temp_edge_vertices, 3, 1, interpolated_coords);
/* Interpolate parameters between edge vertices. Same procedure as above. */
const double *parameters = (double *) t8_cmesh_get_attribute (
- cmesh, t8_get_package_id (), T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
+ cmesh, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
T8_ASSERT (parameters != NULL);
/* Curves have only one parameter u, surfaces have two, u and v.
* Therefore, we have to distinguish if the edge has a curve or surface linked to it. */
@@ -492,8 +493,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreei
double interpolated_curve_parameter;
t8_geom_linear_interpolation (&ref_coords[edge_direction], parameters, 1, 1, &interpolated_curve_parameter);
- T8_ASSERT (edges[i_edge] <= occ_shape_edge_map.Size ());
- curve = BRep_Tool::Curve (TopoDS::Edge (occ_shape_edge_map.FindKey (edges[i_edge])), first, last);
+ T8_ASSERT (edges[i_edge] <= cad_shape_edge_map.Size ());
+ curve = BRep_Tool::Curve (TopoDS::Edge (cad_shape_edge_map.FindKey (edges[i_edge])), first, last);
/* Check if curve are valid */
T8_ASSERT (!curve.IsNull ());
@@ -506,8 +507,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreei
/* Linear interpolation between parameters */
t8_geom_linear_interpolation (&ref_coords[edge_direction], parameters, 2, 1, interpolated_surface_parameters);
- T8_ASSERT (edges[i_edge + num_edges] <= occ_shape_face_map.Size ());
- surface = BRep_Tool::Surface (TopoDS::Face (occ_shape_face_map.FindKey (edges[i_edge + num_edges])));
+ T8_ASSERT (edges[i_edge + num_edges] <= cad_shape_face_map.Size ());
+ surface = BRep_Tool::Surface (TopoDS::Face (cad_shape_face_map.FindKey (edges[i_edge + num_edges])));
/* Check if surface is valid */
T8_ASSERT (!surface.IsNull ());
@@ -534,7 +535,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreei
}
void
-t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
+t8_geometry_cad::t8_geom_evaluate_cad_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
const size_t num_coords, double *out_coords) const
{
T8_ASSERT (active_tree_class == T8_ECLASS_HEX);
@@ -588,7 +589,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
t8_geom_linear_interpolation (&ref_coords[edge_direction], temp_edge_vertices, 3, 1, interpolated_coords);
/* Interpolate parameters between edge vertices. Same procedure as above. */
const double *parameters = (double *) t8_cmesh_get_attribute (
- cmesh, t8_get_package_id (), T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
+ cmesh, t8_get_package_id (), T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + i_edge, ltreeid);
T8_ASSERT (parameters != NULL);
/* Curves have only one parameter u, surfaces have two, u and v.
* Therefore, we have to distinguish if the edge has a curve or surface linked to it. */
@@ -596,8 +597,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
/* Linear interpolation between parameters */
t8_geom_linear_interpolation (&ref_coords[edge_direction], parameters, 1, 1, &interpolated_curve_param);
- T8_ASSERT (edges[i_edge] <= occ_shape_edge_map.Size ());
- curve = BRep_Tool::Curve (TopoDS::Edge (occ_shape_edge_map.FindKey (edges[i_edge])), first, last);
+ T8_ASSERT (edges[i_edge] <= cad_shape_edge_map.Size ());
+ curve = BRep_Tool::Curve (TopoDS::Edge (cad_shape_edge_map.FindKey (edges[i_edge])), first, last);
/* Check if curve are valid */
T8_ASSERT (!curve.IsNull ());
@@ -609,8 +610,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
/* Linear interpolation between parameters */
t8_geom_linear_interpolation (&ref_coords[edge_direction], parameters, 2, 1, interpolated_surface_params);
- T8_ASSERT (edges[i_edge + num_edges] <= occ_shape_face_map.Size ());
- surface = BRep_Tool::Surface (TopoDS::Face (occ_shape_face_map.FindKey (edges[i_edge + num_edges])));
+ T8_ASSERT (edges[i_edge + num_edges] <= cad_shape_face_map.Size ());
+ surface = BRep_Tool::Surface (TopoDS::Face (cad_shape_face_map.FindKey (edges[i_edge + num_edges])));
/* Check if surface is valid */
T8_ASSERT (!surface.IsNull ());
@@ -670,7 +671,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
surface_parameters_from_curve[2] = { 0 };
/* Retrieve surface parameters of nodes */
const double *surface_parameters = (double *) t8_cmesh_get_attribute (
- cmesh, t8_get_package_id (), T8_CMESH_OCC_FACE_PARAMETERS_ATTRIBUTE_KEY + i_faces, ltreeid);
+ cmesh, t8_get_package_id (), T8_CMESH_CAD_FACE_PARAMETERS_ATTRIBUTE_KEY + i_faces, ltreeid);
T8_ASSERT (surface_parameters != NULL);
/* Iterate over each edge of face */
for (int i_face_edge = 0; i_face_edge < 4; ++i_face_edge) {
@@ -695,7 +696,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
/* Retrieve parameters of nodes und curve */
const double *curve_parameters = (double *) t8_cmesh_get_attribute (
cmesh, t8_get_package_id (),
- T8_CMESH_OCC_EDGE_PARAMETERS_ATTRIBUTE_KEY + t8_face_edge_to_tree_edge[T8_ECLASS_HEX][i_faces][i_face_edge],
+ T8_CMESH_CAD_EDGE_PARAMETERS_ATTRIBUTE_KEY + t8_face_edge_to_tree_edge[T8_ECLASS_HEX][i_faces][i_face_edge],
ltreeid);
T8_ASSERT (curve_parameters != NULL);
/* Interpolate linearly between the parameters of the two nodes on the curve */
@@ -717,8 +718,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
/* Retrieve the curve of the edge */
T8_ASSERT (edges[t8_face_edge_to_tree_edge[T8_ECLASS_HEX][i_faces][i_face_edge]]
- <= occ_shape_edge_map.Size ());
- curve = BRep_Tool::Curve (TopoDS::Edge (occ_shape_edge_map.FindKey (
+ <= cad_shape_edge_map.Size ());
+ curve = BRep_Tool::Curve (TopoDS::Edge (cad_shape_edge_map.FindKey (
edges[t8_face_edge_to_tree_edge[T8_ECLASS_HEX][i_faces][i_face_edge]])),
first, last);
/* Check if curve is valid */
@@ -741,7 +742,7 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
}
/* Convert the interpolated parameter of the curve into the corresponding parameters on the surface */
const int num_face_nodes = t8_eclass_num_vertices[active_tree_class];
- t8_geometry_occ::t8_geom_edge_parameter_to_face_parameters (
+ t8_geometry_cad::t8_geom_edge_parameter_to_face_parameters (
edges[t8_face_edge_to_tree_edge[T8_ECLASS_HEX][i_faces][i_face_edge]], faces[i_faces], num_face_nodes,
interpolated_curve_param, surface_parameters, surface_parameters_from_curve);
@@ -805,8 +806,8 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
}
/* Retrieve the surface of the edge */
- T8_ASSERT (faces[i_faces] <= occ_shape_face_map.Size ());
- surface = BRep_Tool::Surface (TopoDS::Face (occ_shape_face_map.FindKey (faces[i_faces])));
+ T8_ASSERT (faces[i_faces] <= cad_shape_face_map.Size ());
+ surface = BRep_Tool::Surface (TopoDS::Face (cad_shape_face_map.FindKey (faces[i_faces])));
/* Check if surface is valid */
T8_ASSERT (!surface.IsNull ());
@@ -831,71 +832,71 @@ t8_geometry_occ::t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid
}
int
-t8_geometry_occ::t8_geom_is_line (const int curve_index) const
+t8_geometry_cad::t8_geom_is_line (const int curve_index) const
{
- const Handle_Geom_Curve curve = t8_geom_get_occ_curve (curve_index);
+ const Handle_Geom_Curve curve = t8_geom_get_cad_curve (curve_index);
const GeomAdaptor_Curve curve_adaptor (curve);
return curve_adaptor.GetType () == GeomAbs_Line;
}
int
-t8_geometry_occ::t8_geom_is_plane (const int surface_index) const
+t8_geometry_cad::t8_geom_is_plane (const int surface_index) const
{
- const Handle_Geom_Surface surface = t8_geom_get_occ_surface (surface_index);
+ const Handle_Geom_Surface surface = t8_geom_get_cad_surface (surface_index);
const GeomAdaptor_Surface surface_adaptor (surface);
return surface_adaptor.GetType () == GeomAbs_Plane;
}
const gp_Pnt
-t8_geometry_occ::t8_geom_get_occ_point (const int index) const
+t8_geometry_cad::t8_geom_get_cad_point (const int index) const
{
- T8_ASSERT (index <= occ_shape_vertex_map.Size ());
- return BRep_Tool::Pnt (TopoDS::Vertex (occ_shape_vertex_map.FindKey (index)));
+ T8_ASSERT (index <= cad_shape_vertex_map.Size ());
+ return BRep_Tool::Pnt (TopoDS::Vertex (cad_shape_vertex_map.FindKey (index)));
}
const Handle_Geom_Curve
-t8_geometry_occ::t8_geom_get_occ_curve (const int index) const
+t8_geometry_cad::t8_geom_get_cad_curve (const int index) const
{
- T8_ASSERT (index <= occ_shape_edge_map.Size ());
+ T8_ASSERT (index <= cad_shape_edge_map.Size ());
Standard_Real first, last;
- return BRep_Tool::Curve (TopoDS::Edge (occ_shape_edge_map.FindKey (index)), first, last);
+ return BRep_Tool::Curve (TopoDS::Edge (cad_shape_edge_map.FindKey (index)), first, last);
}
const Handle_Geom_Surface
-t8_geometry_occ::t8_geom_get_occ_surface (const int index) const
+t8_geometry_cad::t8_geom_get_cad_surface (const int index) const
{
- T8_ASSERT (index <= occ_shape_face_map.Size ());
- return BRep_Tool::Surface (TopoDS::Face (occ_shape_face_map.FindKey (index)));
+ T8_ASSERT (index <= cad_shape_face_map.Size ());
+ return BRep_Tool::Surface (TopoDS::Face (cad_shape_face_map.FindKey (index)));
}
const TopTools_IndexedMapOfShape
-t8_geometry_occ::t8_geom_get_occ_shape_vertex_map () const
+t8_geometry_cad::t8_geom_get_cad_shape_vertex_map () const
{
- return occ_shape_vertex_map;
+ return cad_shape_vertex_map;
}
const TopTools_IndexedMapOfShape
-t8_geometry_occ::t8_geom_get_occ_shape_edge_map () const
+t8_geometry_cad::t8_geom_get_cad_shape_edge_map () const
{
- return occ_shape_edge_map;
+ return cad_shape_edge_map;
}
const TopTools_IndexedMapOfShape
-t8_geometry_occ::t8_geom_get_occ_shape_face_map () const
+t8_geometry_cad::t8_geom_get_cad_shape_face_map () const
{
- return occ_shape_face_map;
+ return cad_shape_face_map;
}
int
-t8_geometry_occ::t8_geom_get_common_edge (const int vertex1_index, const int vertex2_index) const
+t8_geometry_cad::t8_geom_get_common_edge (const int vertex1_index, const int vertex2_index) const
{
- const TopTools_ListOfShape collection1 = occ_shape_vertex2edge_map.FindFromIndex (vertex1_index);
- const TopTools_ListOfShape collection2 = occ_shape_vertex2edge_map.FindFromIndex (vertex2_index);
+ const TopTools_ListOfShape collection1 = cad_shape_vertex2edge_map.FindFromIndex (vertex1_index);
+ const TopTools_ListOfShape collection2 = cad_shape_vertex2edge_map.FindFromIndex (vertex2_index);
for (auto edge1 = collection1.begin (); edge1 != collection1.end (); ++edge1) {
for (auto edge2 = collection2.begin (); edge2 != collection2.end (); ++edge2) {
if (edge1->IsEqual (*edge2)) {
- return occ_shape_edge2face_map.FindIndex (*edge1);
+ return cad_shape_edge2face_map.FindIndex (*edge1);
}
}
}
@@ -903,15 +904,15 @@ t8_geometry_occ::t8_geom_get_common_edge (const int vertex1_index, const int ver
}
int
-t8_geometry_occ::t8_geom_get_common_face (const int edge1_index, const int edge2_index) const
+t8_geometry_cad::t8_geom_get_common_face (const int edge1_index, const int edge2_index) const
{
- const TopTools_ListOfShape collection1 = occ_shape_edge2face_map.FindFromIndex (edge1_index);
- const TopTools_ListOfShape collection2 = occ_shape_edge2face_map.FindFromIndex (edge2_index);
+ const TopTools_ListOfShape collection1 = cad_shape_edge2face_map.FindFromIndex (edge1_index);
+ const TopTools_ListOfShape collection2 = cad_shape_edge2face_map.FindFromIndex (edge2_index);
for (auto face1 = collection1.begin (); face1 != collection1.end (); ++face1) {
for (auto face2 = collection2.begin (); face2 != collection2.end (); ++face2) {
if (face1->IsEqual (*face2)) {
- return occ_shape_face_map.FindIndex (*face1);
+ return cad_shape_face_map.FindIndex (*face1);
}
}
}
@@ -919,26 +920,26 @@ t8_geometry_occ::t8_geom_get_common_face (const int edge1_index, const int edge2
}
int
-t8_geometry_occ::t8_geom_is_vertex_on_edge (const int vertex_index, const int edge_index) const
+t8_geometry_cad::t8_geom_is_vertex_on_edge (const int vertex_index, const int edge_index) const
{
- const TopTools_ListOfShape collection = occ_shape_vertex2edge_map.FindFromIndex (vertex_index);
- return collection.Contains (occ_shape_edge_map.FindKey (edge_index));
+ const TopTools_ListOfShape collection = cad_shape_vertex2edge_map.FindFromIndex (vertex_index);
+ return collection.Contains (cad_shape_edge_map.FindKey (edge_index));
}
int
-t8_geometry_occ::t8_geom_is_edge_on_face (const int edge_index, const int face_index) const
+t8_geometry_cad::t8_geom_is_edge_on_face (const int edge_index, const int face_index) const
{
- const TopTools_ListOfShape collection = occ_shape_edge2face_map.FindFromIndex (edge_index);
- return collection.Contains (occ_shape_face_map.FindKey (face_index));
+ const TopTools_ListOfShape collection = cad_shape_edge2face_map.FindFromIndex (edge_index);
+ return collection.Contains (cad_shape_face_map.FindKey (face_index));
}
int
-t8_geometry_occ::t8_geom_is_vertex_on_face (const int vertex_index, const int face_index) const
+t8_geometry_cad::t8_geom_is_vertex_on_face (const int vertex_index, const int face_index) const
{
- const TopTools_ListOfShape edge_collection = occ_shape_vertex2edge_map.FindFromIndex (vertex_index);
+ const TopTools_ListOfShape edge_collection = cad_shape_vertex2edge_map.FindFromIndex (vertex_index);
for (auto edge = edge_collection.begin (); edge != edge_collection.end (); ++edge) {
- const TopTools_ListOfShape face_collection = occ_shape_edge2face_map.FindFromKey (*edge);
- if (face_collection.Contains (occ_shape_face_map.FindKey (face_index))) {
+ const TopTools_ListOfShape face_collection = cad_shape_edge2face_map.FindFromKey (*edge);
+ if (face_collection.Contains (cad_shape_face_map.FindKey (face_index))) {
return 1;
}
}
@@ -946,38 +947,38 @@ t8_geometry_occ::t8_geom_is_vertex_on_face (const int vertex_index, const int fa
}
void
-t8_geometry_occ::t8_geom_get_parameter_of_vertex_on_edge (const int vertex_index, const int edge_index,
+t8_geometry_cad::t8_geom_get_parameter_of_vertex_on_edge (const int vertex_index, const int edge_index,
double *edge_param) const
{
- T8_ASSERT (t8_geometry_occ::t8_geom_is_vertex_on_edge (vertex_index, edge_index));
- TopoDS_Vertex vertex = TopoDS::Vertex (occ_shape_vertex_map.FindKey (vertex_index));
- TopoDS_Edge edge = TopoDS::Edge (occ_shape_edge_map.FindKey (edge_index));
+ T8_ASSERT (t8_geometry_cad::t8_geom_is_vertex_on_edge (vertex_index, edge_index));
+ TopoDS_Vertex vertex = TopoDS::Vertex (cad_shape_vertex_map.FindKey (vertex_index));
+ TopoDS_Edge edge = TopoDS::Edge (cad_shape_edge_map.FindKey (edge_index));
*edge_param = BRep_Tool::Parameter (vertex, edge);
}
void
-t8_geometry_occ::t8_geom_get_parameters_of_vertex_on_face (const int vertex_index, const int face_index,
+t8_geometry_cad::t8_geom_get_parameters_of_vertex_on_face (const int vertex_index, const int face_index,
double *face_params) const
{
- T8_ASSERT (t8_geometry_occ::t8_geom_is_vertex_on_face (vertex_index, face_index));
+ T8_ASSERT (t8_geometry_cad::t8_geom_is_vertex_on_face (vertex_index, face_index));
gp_Pnt2d uv;
- TopoDS_Vertex vertex = TopoDS::Vertex (occ_shape_vertex_map.FindKey (vertex_index));
- TopoDS_Face face = TopoDS::Face (occ_shape_face_map.FindKey (face_index));
+ TopoDS_Vertex vertex = TopoDS::Vertex (cad_shape_vertex_map.FindKey (vertex_index));
+ TopoDS_Face face = TopoDS::Face (cad_shape_face_map.FindKey (face_index));
uv = BRep_Tool::Parameters (vertex, face);
face_params[0] = uv.X ();
face_params[1] = uv.Y ();
}
void
-t8_geometry_occ::t8_geom_edge_parameter_to_face_parameters (const int edge_index, const int face_index,
+t8_geometry_cad::t8_geom_edge_parameter_to_face_parameters (const int edge_index, const int face_index,
const int num_face_nodes, const double edge_param,
const double *surface_params, double *face_params) const
{
- T8_ASSERT (t8_geometry_occ::t8_geom_is_edge_on_face (edge_index, face_index));
+ T8_ASSERT (t8_geometry_cad::t8_geom_is_edge_on_face (edge_index, face_index));
Standard_Real first, last;
gp_Pnt2d uv;
- TopoDS_Edge edge = TopoDS::Edge (occ_shape_edge_map.FindKey (edge_index));
- TopoDS_Face face = TopoDS::Face (occ_shape_face_map.FindKey (face_index));
+ TopoDS_Edge edge = TopoDS::Edge (cad_shape_edge_map.FindKey (edge_index));
+ TopoDS_Face face = TopoDS::Face (cad_shape_face_map.FindKey (face_index));
Handle_Geom2d_Curve curve_on_surface = BRep_Tool::CurveOnSurface (edge, face, first, last);
Handle_Geom_Surface surface = BRep_Tool::Surface (face);
curve_on_surface->D0 (edge_param, uv);
@@ -1022,37 +1023,37 @@ t8_geometry_occ::t8_geom_edge_parameter_to_face_parameters (const int edge_index
}
void
-t8_geometry_occ::t8_geom_get_face_parametric_bounds (const int surface_index, double *bounds) const
+t8_geometry_cad::t8_geom_get_face_parametric_bounds (const int surface_index, double *bounds) const
{
- const Handle_Geom_Surface occ_surface = t8_geom_get_occ_surface (surface_index);
- occ_surface->Bounds (bounds[0], bounds[1], bounds[2], bounds[3]);
+ const Handle_Geom_Surface cad_surface = t8_geom_get_cad_surface (surface_index);
+ cad_surface->Bounds (bounds[0], bounds[1], bounds[2], bounds[3]);
}
void
-t8_geometry_occ::t8_geom_get_edge_parametric_bounds (const int edge_index, double *bounds) const
+t8_geometry_cad::t8_geom_get_edge_parametric_bounds (const int edge_index, double *bounds) const
{
- const Handle_Geom_Curve occ_edge = t8_geom_get_occ_curve (edge_index);
- bounds[0] = occ_edge->FirstParameter ();
- bounds[1] = occ_edge->LastParameter ();
+ const Handle_Geom_Curve cad_edge = t8_geom_get_cad_curve (edge_index);
+ bounds[0] = cad_edge->FirstParameter ();
+ bounds[1] = cad_edge->LastParameter ();
}
int
-t8_geometry_occ::t8_geom_is_edge_closed (int edge_index) const
+t8_geometry_cad::t8_geom_is_edge_closed (int edge_index) const
{
- const Handle_Geom_Curve occ_edge = t8_geom_get_occ_curve (edge_index);
- return occ_edge->IsClosed ();
+ const Handle_Geom_Curve cad_edge = t8_geom_get_cad_curve (edge_index);
+ return cad_edge->IsClosed ();
}
int
-t8_geometry_occ::t8_geom_is_surface_closed (int geometry_index, int parameter) const
+t8_geometry_cad::t8_geom_is_surface_closed (int geometry_index, int parameter) const
{
- const Handle_Geom_Surface occ_surface = t8_geom_get_occ_surface (geometry_index);
+ const Handle_Geom_Surface cad_surface = t8_geom_get_cad_surface (geometry_index);
switch (parameter) {
case 0:
- return occ_surface->IsUClosed ();
+ return cad_surface->IsUClosed ();
break;
case 1:
- return occ_surface->IsVClosed ();
+ return cad_surface->IsVClosed ();
break;
default:
SC_ABORT_NOT_REACHED ();
@@ -1063,20 +1064,20 @@ t8_geometry_occ::t8_geom_is_surface_closed (int geometry_index, int parameter) c
/* This part should be callable from C */
T8_EXTERN_C_BEGIN ();
-/* Satisfy the C interface from t8_geometry_occ.h.
+/* Satisfy the C interface from t8_geometry_cad.h.
* Create a new geometry with given dimension. */
-t8_geometry_occ_c *
-t8_geometry_occ_new (int dimension, const char *fileprefix, const char *name_in)
+t8_geometry_cad_c *
+t8_geometry_cad_new (int dimension, const char *fileprefix, const char *name_in)
{
- t8_geometry_occ *geom = new t8_geometry_occ (dimension, fileprefix, name_in);
- return (t8_geometry_occ_c *) geom;
+ t8_geometry_cad *geom = new t8_geometry_cad (dimension, fileprefix, name_in);
+ return (t8_geometry_cad_c *) geom;
}
void
-t8_geometry_occ_destroy (t8_geometry_occ_c **geom)
+t8_geometry_cad_destroy (t8_geometry_cad_c **geom)
{
T8_ASSERT (geom != NULL);
- T8_ASSERT ((*geom)->t8_geom_get_type () == T8_GEOMETRY_TYPE_OCC);
+ T8_ASSERT ((*geom)->t8_geom_get_type () == T8_GEOMETRY_TYPE_CAD);
delete *geom;
*geom = NULL;
diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.h b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.h
similarity index 73%
rename from src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.h
rename to src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.h
index 689d3938f2..40d2b278e3 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.h
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.h
@@ -20,27 +20,27 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-/** \file t8_geometry_occ.h
- * This header provides the C interface to create a occ geometry.
+/** \file t8_geometry_cad.h
+ * This header provides the C interface to create a cad geometry.
*/
-#ifndef T8_GEOMETRY_OCC_H
-#define T8_GEOMETRY_OCC_H
+#ifndef T8_GEOMETRY_cad_H
+#define T8_GEOMETRY_cad_H
#include
#include
#include
/** This typedef holds virtual functions for a particular geometry.
- * We need it so that we can use t8_geometry_occ_c pointers in .c files
+ * We need it so that we can use t8_geometry_cad_c pointers in .c files
* without them seeing the actual C++ code (and then not compiling)
*/
-typedef struct t8_geometry_occ t8_geometry_occ_c;
+typedef struct t8_geometry_cad t8_geometry_cad_c;
T8_EXTERN_C_BEGIN ();
/**
- * Create a new occ geometry with a given dimension. The geometry
+ * Create a new cad geometry with a given dimension. 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.
@@ -48,22 +48,22 @@ T8_EXTERN_C_BEGIN ();
* 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] fileprefix Prefix of a .brep file from which to extract an occ 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.
- * \return A pointer to an allocated t8_geometry_occ struct, as
- * if the \ref t8_geometry_occ (int dim, const *char fileprefix,
+ * \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)
* constructor was called.
*/
-t8_geometry_occ_c *
-t8_geometry_occ_new (int dim, const char *fileprefix, const char *name_in);
+t8_geometry_cad_c *
+t8_geometry_cad_new (int dim, const char *fileprefix, const char *name_in);
-/** Destroy a occ geometry that was created with \ref t8_geometry_occ_new.
- * \param [in,out] geom A occ geometry. Set to NULL on output.
+/** 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.
*/
void
-t8_geometry_occ_destroy (t8_geometry_occ_c **geom);
+t8_geometry_cad_destroy (t8_geometry_cad_c **geom);
T8_EXTERN_C_END ();
-#endif /* !T8_GEOMETRY_OCC_H! */
+#endif /* !T8_GEOMETRY_cad_H! */
diff --git a/src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.hxx b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx
similarity index 73%
rename from src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.hxx
rename to src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx
index 077d43c632..3f97814b12 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_occ.hxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_cad.hxx
@@ -20,20 +20,20 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-/** \file t8_geometry_occ.hxx
+/** \file t8_geometry_cad.hxx
* This geometry implements OpenCASCADE geometries. It enables the option to link different
- * 1 and 2 dimensional occ geometries to the edges and faces of refinement trees.
+ * 1 and 2 dimensional cad geometries to the edges and faces of refinement trees.
* The geometry of the refinement tree is extended into the volume accordingly.
*/
-#ifndef T8_GEOMETRY_OCC_HXX
-#define T8_GEOMETRY_OCC_HXX
+#ifndef T8_GEOMETRY_CAD_HXX
+#define T8_GEOMETRY_CAD_HXX
#include
#include
#include
#include
-#include
+#include
#if T8_WITH_OCC
@@ -43,11 +43,11 @@
#include
#include
-struct t8_geometry_occ: public t8_geometry_with_vertices
+struct t8_geometry_cad: public t8_geometry_with_vertices
{
public:
/**
- * Constructor of the occ geometry with a given dimension. The geometry
+ * Constructor of the cad geometry with a given dimension. 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.
@@ -55,30 +55,30 @@ struct t8_geometry_occ: public t8_geometry_with_vertices
* 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 occ 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_occ (int dim, const char *fileprefix, const char *name);
+ t8_geometry_cad (int dim, const char *fileprefix, const char *name);
/**
- * Constructor of the occ geometry with a given dimension. The geometry
+ * Constructor of the cad geometry with a given dimension. 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 occ_shape.
+ * 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_occ (int dim, const char *fileprefix, const char *name) constructor.
+ * \ref t8_geometry_cad (int dim, const char *fileprefix, const char *name) constructor.
* \param [in] dim The dimension of this geometry.
- * \param [in] occ_shape Occ shape geometry.
+ * \param [in] cad_shape cad shape geometry.
* \param [in] name The name to give this geometry.
*/
- t8_geometry_occ (int dim, const TopoDS_Shape occ_shape, const char *name);
+ t8_geometry_cad (int dim, const TopoDS_Shape cad_shape, const char *name);
/** The destructor.
* Clears the allocated memory.
*/
- virtual ~t8_geometry_occ ()
+ virtual ~t8_geometry_cad ()
{
/* Nothing to do. */
}
@@ -90,7 +90,7 @@ struct t8_geometry_occ: public t8_geometry_with_vertices
inline t8_geometry_type_t
t8_geom_get_type () const
{
- return T8_GEOMETRY_TYPE_OCC;
+ return T8_GEOMETRY_TYPE_CAD;
};
/**
@@ -128,123 +128,123 @@ struct t8_geometry_occ: public t8_geometry_with_vertices
virtual void
t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t gtreeid);
- /** Check if a occ_curve is a line.
- * \param [in] curve_index The index of the occ_curve.
+ /** 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.
*/
int
t8_geom_is_line (const int curve_index) const;
- /** Check if a occ_surface is a plane.
- * \param [in] surface_index The index of the occ_surface.
+ /** Check if a cad_surface is a plane.
+ * \param [in] surface_index The index of the cad_surface.
* \return 1 if surface is a plane linear, 0 if surface is not a plane.
*/
int
t8_geom_is_plane (const int surface_index) const;
- /** Get an occ point from the occ_shape.
- * \param [in] index The index of the point in the occ_shape.
- * \return The occ point.
+ /** Get an cad point from the cad_shape.
+ * \param [in] index The index of the point in the cad_shape.
+ * \return The cad point.
*/
const gp_Pnt
- t8_geom_get_occ_point (const int index) const;
+ t8_geom_get_cad_point (const int index) const;
- /** Get an occ curve from the occ_shape.
- * \param [in] index The index of the curve in the occ_shape.
- * \return The occ curve.
+ /** Get an cad curve from the cad_shape.
+ * \param [in] index The index of the curve in the cad_shape.
+ * \return The cad curve.
*/
const Handle_Geom_Curve
- t8_geom_get_occ_curve (const int index) const;
+ t8_geom_get_cad_curve (const int index) const;
- /** Get an occ surface from the occ_shape.
- * \param [in] index The index of the surface in the occ_shape.
- * \return The occ surface.
+ /** Get an cad surface from the cad_shape.
+ * \param [in] index The index of the surface in the cad_shape.
+ * \return The cad surface.
*/
const Handle_Geom_Surface
- t8_geom_get_occ_surface (const int index) const;
+ t8_geom_get_cad_surface (const int index) const;
- /** Get the occ_shape_vertex2edge_map.
- * \return The occ_shape_vertex_map.
+ /** Get the cad_shape_vertex2edge_map.
+ * \return The cad_shape_vertex_map.
*/
const TopTools_IndexedMapOfShape
- t8_geom_get_occ_shape_vertex_map () const;
+ t8_geom_get_cad_shape_vertex_map () const;
- /** Get the occ_shape_edge2face_map.
- * \return The occ_shape_edge_map.
+ /** Get the cad_shape_edge2face_map.
+ * \return The cad_shape_edge_map.
*/
const TopTools_IndexedMapOfShape
- t8_geom_get_occ_shape_edge_map () const;
+ t8_geom_get_cad_shape_edge_map () const;
- /** Get the occ_shape_face_map.
- * \return The occ_shape_face_map.
+ /** Get the cad_shape_face_map.
+ * \return The cad_shape_face_map.
*/
const TopTools_IndexedMapOfShape
- t8_geom_get_occ_shape_face_map () const;
+ t8_geom_get_cad_shape_face_map () const;
- /** Check if two occ points share a common occ edge.
- * \param [in] vertex1_index The index of the first occ point.
- * \param [in] vertex2_index The index of the second occ point.
+ /** Check if two cad points share a common cad edge.
+ * \param [in] vertex1_index The index of the first cad point.
+ * \param [in] vertex2_index The index of the second cad point.
* \return Index of the shared edge. 0 if there is no shared edge.
*/
int
t8_geom_get_common_edge (const int vertex1_index, const int vertex2_index) const;
- /** Check if two occ edges share a common occ face.
- * \param [in] edge1_index The index of the first occ edge.
- * \param [in] edge2_index The index of the second occ edge.
+ /** Check if two cad edges share a common cad face.
+ * \param [in] edge1_index The index of the first cad edge.
+ * \param [in] edge2_index The index of the second cad edge.
* \return Index of the shared face. 0 if there is no shared face.
*/
int
t8_geom_get_common_face (const int edge1_index, const int edge2_index) const;
- /** Check if a occ vertex lies on an occ edge.
- * \param [in] vertex_index The index of the occ vertex.
- * \param [in] edge_index The index of the occ edge.
+ /** Check if a cad vertex lies on an cad edge.
+ * \param [in] vertex_index The index of the cad vertex.
+ * \param [in] edge_index The index of the cad edge.
* \return 1 if vertex lies on edge, otherwise 0.
*/
int
t8_geom_is_vertex_on_edge (const int vertex_index, const int edge_index) const;
- /** Check if a occ vertex lies on an occ edge.
- * \param [in] edge_index The index of the occ vertex.
- * \param [in] face_index The index of the occ edge.
+ /** Check if a cad vertex lies on an cad edge.
+ * \param [in] edge_index The index of the cad vertex.
+ * \param [in] face_index The index of the cad edge.
* \return 1 if vertex lies on edge, otherwise 0.
*/
int
t8_geom_is_edge_on_face (const int edge_index, const int face_index) const;
- /** Check if a occ vertex lies on an occ face.
- * \param [in] vertex_index The index of the occ vertex.
- * \param [in] face_index The index of the occ face.
+ /** Check if a cad vertex lies on an cad face.
+ * \param [in] vertex_index The index of the cad vertex.
+ * \param [in] face_index The index of the cad face.
* \return 1 if vertex lies on face, otherwise 0.
*/
int
t8_geom_is_vertex_on_face (const int vertex_index, const int face_index) const;
- /** Retrieves the parameter of an occ vertex on an occ edge.
+ /** Retrieves the parameter of an cad vertex on an cad edge.
* The vertex has to lie on the edge.
- * \param [in] vertex_index The index of the occ vertex.
- * \param [in] edge_index The index of the occ edge.
+ * \param [in] vertex_index The index of the cad vertex.
+ * \param [in] edge_index The index of the cad edge.
* \param [out] edge_param The parameter of the vertex on the edge.
*/
void
t8_geom_get_parameter_of_vertex_on_edge (const int vertex_index, const int edge_index, double *edge_param) const;
- /** Retrieves the parameters of an occ vertex on a occ face.
+ /** Retrieves the parameters of an cad vertex on a cad face.
* The vertex has to lie on the face.
- * \param [in] vertex_index The index of the occ vertex.
- * \param [in] face_index The index of the occ face.
+ * \param [in] vertex_index The index of the cad vertex.
+ * \param [in] face_index The index of the cad face.
* \param [out] face_params The parameters of the vertex on the face.
*/
void
t8_geom_get_parameters_of_vertex_on_face (const int vertex_index, const int face_index, double *face_params) const;
- /** Converts the parameters of an occ edge to the corresponding parameters on an occ face.
+ /** Converts the parameters of an cad edge to the corresponding parameters on an cad face.
* The edge has to lie on the face.
* For the conversion of edge parameters of mesh elements to topological face parameters of a closed surface, it is additionally
* checked, whether the conversion was correct, to prevent disorted elements.
- * \param [in] edge_index The index of the occ edge, which parameters should be converted to face parameters.
- * \param [in] face_index The index of the occ face, on to which the edge parameters should be converted.
+ * \param [in] edge_index The index of the cad edge, which parameters should be converted to face parameters.
+ * \param [in] face_index The index of the cad face, on to which the edge parameters should be converted.
* \param [in] num_face_nodes The number of the face nodes of the evaluated element. Only needed for closed surface check, otherwise NULL.
* \param [in] edge_param The parameter on the edge.
* \param [in] surface_param The parameters of the surface nodes.
@@ -258,16 +258,16 @@ struct t8_geometry_occ: public t8_geometry_with_vertices
const double edge_param, const double *surface_params,
double *face_params) const;
- /** Finds the parametric bounds of an occ face.
- * \param [in] face_index The index of the occ face.
- * \param [out] bounds The parametric bounds of the occ face.
+ /** Finds the parametric bounds of an cad face.
+ * \param [in] face_index The index of the cad face.
+ * \param [out] bounds The parametric bounds of the cad face.
*/
void
t8_geom_get_face_parametric_bounds (const int surface_index, double *bounds) const;
- /** Finds the parametric bounds of an occ edge.
- * \param [in] edge_index The index of the occ edge.
- * \param [out] bounds The parametric bounds of the occ edge.
+ /** Finds the parametric bounds of an cad edge.
+ * \param [in] edge_index The index of the cad edge.
+ * \param [out] bounds The parametric bounds of the cad edge.
*/
void
t8_geom_get_edge_parametric_bounds (const int edge_index, double *bounds) const;
@@ -298,7 +298,7 @@ struct t8_geometry_occ: public t8_geometry_with_vertices
* \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3.
*/
void
- t8_geom_evaluate_occ_triangle (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
+ t8_geom_evaluate_cad_triangle (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords,
const size_t num_coords, double *out_coords) const;
/**
@@ -310,7 +310,7 @@ struct t8_geometry_occ: public t8_geometry_with_vertices
* \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3.
*/
void
- t8_geom_evaluate_occ_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
+ t8_geom_evaluate_cad_quad (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
double *out_coords) const;
/**
@@ -322,21 +322,21 @@ struct t8_geometry_occ: public t8_geometry_with_vertices
* \param [out] out_coords The mapped coordinates in physical space of \a ref_coords. The length is \a num_coords * 3.
*/
void
- t8_geom_evaluate_occ_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
+ t8_geom_evaluate_cad_hex (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
double *out_coords) const;
const int *edges; /**< The linked edges of the currently active tree. */
const int *faces; /**< The linked faces of the currently active tree. */
- TopoDS_Shape occ_shape; /**< Occ geometry */
- TopTools_IndexedMapOfShape occ_shape_vertex_map; /**< Map of all TopoDS_Vertex in shape. */
- TopTools_IndexedMapOfShape occ_shape_edge_map; /**< Map of all TopoDS_Edge in shape. */
- TopTools_IndexedMapOfShape occ_shape_face_map; /**< Map of all TopoDS_Face in shape. */
+ TopoDS_Shape cad_shape; /**< cad geometry */
+ TopTools_IndexedMapOfShape cad_shape_vertex_map; /**< Map of all TopoDS_Vertex in shape. */
+ TopTools_IndexedMapOfShape cad_shape_edge_map; /**< Map of all TopoDS_Edge in shape. */
+ TopTools_IndexedMapOfShape cad_shape_face_map; /**< Map of all TopoDS_Face in shape. */
TopTools_IndexedDataMapOfShapeListOfShape
- occ_shape_vertex2edge_map; /**< Maps all TopoDS_Vertex of shape to all its connected TopoDS_Edge */
+ cad_shape_vertex2edge_map; /**< Maps all TopoDS_Vertex of shape to all its connected TopoDS_Edge */
TopTools_IndexedDataMapOfShapeListOfShape
- occ_shape_edge2face_map; /**< Maps all TopoDS_Edge of shape to all its connected TopoDS_Face */
+ cad_shape_edge2face_map; /**< Maps all TopoDS_Edge of shape to all its connected TopoDS_Face */
};
#endif /* T8_WITH_OCC */
-#endif /* !T8_GEOMETRY_OCC_HXX! */
+#endif /* !T8_GEOMETRY_CAD_HXX! */
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 04bd567754..885c81877a 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.cxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.cxx
@@ -110,184 +110,169 @@ t8_geometry_squared_disk::t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreei
}
}
-/**
- * Map the faces of an oktaeder 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,
- double *out_coords) const
+/* Helper function for `t8_geom_evaluate_sphere_tri_prism`. */
+static inline void
+t8_map_triangle_to_sphere (const double *active_tree_vertices, const double sphere_radius, const int shift,
+ const double u_ref[3], const double v_ref[3], const double w_ref[3],
+ const double *ref_coords, const size_t num_coords, double *out_coords)
{
- /* We average over the three corners of the triangle. */
- const double avg_factor = 1.0 / 3.0;
-
- /* Radius of the sphere scaled by the average factor. */
- const double radius = t8_vec_norm (active_tree_vertices) * avg_factor;
-
- /* The next three code blocks straighten out the elements near the triangle
- * corners by averaging the rectification with all three corners. */
+ double u[3]; /* Position vector. */
+ double v[3]; /* First triangle side. */
+ double w[3]; /* Second triangle side. */
+
+ /* `(3 - shift + 0) % 3)*3` circular rotates array indices according to `shift`. */
+ for (size_t i = 0; i < 3; i++) {
+ u[i] = active_tree_vertices[((3 - shift + 0) % 3) * 3 + i];
+ v[i] = active_tree_vertices[((3 - shift + 1) % 3) * 3 + i] - u[i];
+ w[i] = active_tree_vertices[((3 - shift + 2) % 3) * 3 + i] - u[i];
+ }
- /* First triangle corner. */
- {
- double u[3]; /* Position vector. */
- double v[3]; /* First triangle side. */
- double w[3]; /* Second triangle side. */
+ for (size_t i_coord = 0; i_coord < num_coords; i_coord++) {
+ const size_t offset = 3 * i_coord;
- u[0] = active_tree_vertices[0];
- u[1] = active_tree_vertices[1];
- u[2] = active_tree_vertices[2];
+ /* Shorthand for code readability. */
+ const double x_ref = ref_coords[offset + 0];
+ const double y_ref = ref_coords[offset + 1];
- v[0] = active_tree_vertices[3 + 0] - u[0];
- v[1] = active_tree_vertices[3 + 1] - u[1];
- v[2] = active_tree_vertices[3 + 2] - u[2];
+ /* Compute local triangle coordinates in the new reference space. */
+ const double vv_ref = u_ref[0] + x_ref * v_ref[0] + y_ref * w_ref[0];
+ const double ww_ref = u_ref[1] + x_ref * v_ref[1] + y_ref * w_ref[1];
- w[0] = active_tree_vertices[6 + 0] - u[0];
- w[1] = active_tree_vertices[6 + 1] - u[1];
- w[2] = active_tree_vertices[6 + 2] - u[2];
+ /* tldr: Correction in order to rectify elements near the corners. This
+ * is necessary, since due to the transformation from the cmesh triangle to the
+ * sphere elements near the face centers expand while near the corners they
+ * shrink. Following correction alleviates this.
+ * TODO: This correction is not general and probably not optimal in all cases.
+ * But it works good enough. Find a better one. This is not a trivial task, though.
+ */
+ const double vv_corr = tan (0.5 * M_PI * (vv_ref - 0.5)) * 0.5 + 0.5;
+ const double ww_corr = tan (0.5 * M_PI * (ww_ref - 0.5)) * 0.5 + 0.5;
- /* Reference coordinates from this particular triangle corner. */
- const double u_ref[3] = { 0.0, 0.0, 0.0 };
- const double v_ref[3] = { 1.0, 0.0, 0.0 };
- const double w_ref[3] = { -1.0, 1.0, 0.0 };
+ /* Compute and apply the corrected mapping. The position vector `pos` pokes
+ * through the triangle plane. It then gets rescaled to the sphere's radius. */
+ double pos[3];
+ pos[0] = u[0] + vv_corr * v[0] + ww_corr * w[0];
+ pos[1] = u[1] + vv_corr * v[1] + ww_corr * w[1];
+ pos[2] = u[2] + vv_corr * v[2] + ww_corr * w[2];
- for (size_t i_coord = 0; i_coord < num_coords; i_coord++) {
- const size_t offset = 3 * i_coord;
+ t8_vec_rescale (pos, sphere_radius);
- const double x = ref_coords[offset + 0];
- const double y = ref_coords[offset + 1];
+ for (size_t i = 0; i < 3; i++) {
+ out_coords[offset + i] = out_coords[offset + i] + pos[i] * (1.0 / 3.0);
+ }
+ }
+}
- /* Compute local triangle coordinate. */
- const double vv = u_ref[0] + x * v_ref[0] + y * w_ref[0];
- const double ww = u_ref[1] + x * v_ref[1] + y * w_ref[1];
+static inline void
+t8_geom_evaluate_sphere_tri_prism (const double *active_tree_vertices, const t8_eclass_t eclass,
+ const double *ref_coords, const size_t num_coords, double *out_coords)
+{
+ /* The next three code blocks straighten out the elements near the triangle
+ * corners by averaging the rectification with all three corners. */
- /* Correction in order to rectify elements near the corners. */
- const double vv_corr = tan (0.5 * M_PI * (vv - 0.5)) * 0.5 + 0.5;
- const double ww_corr = tan (0.5 * M_PI * (ww - 0.5)) * 0.5 + 0.5;
+ /* Clear `out_coords`. */
+ for (size_t i = 0; i < 3 * num_coords; i++) {
+ out_coords[i] = 0.0;
+ }
- /* Compute and apply the corrected mapping. */
- double ray[3]; /* Ray vector pinning through the triangle at reference coordinates. */
- ray[0] = u[0] + vv_corr * v[0] + ww_corr * w[0];
- ray[1] = u[1] + vv_corr * v[1] + ww_corr * w[1];
- ray[2] = u[2] + vv_corr * v[2] + ww_corr * w[2];
+ /* We derive the sphere's radius from the first corner of the triangle/prism.
+ * The averaging factor `1/3` is already included here. */
+ const double sphere_radius = t8_vec_norm (active_tree_vertices);
- t8_vec_normalize (ray);
+ {
+ /* Reference coordinates from first triangle corner. */
+ const double u_ref[3] = { 0.0, 0.0, 0.0 };
+ const double v_ref[3] = { 1.0, 0.0, 0.0 };
+ const double w_ref[3] = { -1.0, 1.0, 0.0 };
- out_coords[offset + 0] = radius * ray[0];
- out_coords[offset + 1] = radius * ray[1];
- out_coords[offset + 2] = radius * ray[2];
- }
+ t8_map_triangle_to_sphere (active_tree_vertices, sphere_radius, 0, u_ref, v_ref, w_ref, ref_coords, num_coords,
+ out_coords);
}
- /* Second triangle corner. */
{
- double u[3]; /* Position vector. */
- double v[3]; /* First triangle side. */
- double w[3]; /* Second triangle side. */
-
- u[0] = active_tree_vertices[6 + 0];
- u[1] = active_tree_vertices[6 + 1];
- u[2] = active_tree_vertices[6 + 2];
-
- v[0] = active_tree_vertices[0 + 0] - u[0];
- v[1] = active_tree_vertices[0 + 1] - u[1];
- v[2] = active_tree_vertices[0 + 2] - u[2];
-
- w[0] = active_tree_vertices[3 + 0] - u[0];
- w[1] = active_tree_vertices[3 + 1] - u[1];
- w[2] = active_tree_vertices[3 + 2] - u[2];
-
- /* Reference coordinates from this particular triangle corner. */
+ /* Reference coordinates from second triangle corner. */
const double u_ref[3] = { 1.0, 0.0, 0.0 };
const double v_ref[3] = { -1.0, 1.0, 0.0 };
const double w_ref[3] = { 0.0, -1.0, 0.0 };
- for (size_t i_coord = 0; i_coord < num_coords; i_coord++) {
- const size_t offset = 3 * i_coord;
-
- const double x = ref_coords[offset + 0];
- const double y = ref_coords[offset + 1];
-
- /* Compute local triangle coordinate. */
- const double vv = u_ref[0] + x * v_ref[0] + y * w_ref[0];
- const double ww = u_ref[1] + x * v_ref[1] + y * w_ref[1];
-
- /* Correction in order to rectify elements near the corners. */
- const double vv_corr = tan (0.5 * M_PI * (vv - 0.5)) * 0.5 + 0.5;
- const double ww_corr = tan (0.5 * M_PI * (ww - 0.5)) * 0.5 + 0.5;
-
- /* Compute and apply the corrected mapping. */
- double ray[3]; /* Ray vector pinning through the triangle at reference coordinates. */
- ray[0] = u[0] + vv_corr * v[0] + ww_corr * w[0];
- ray[1] = u[1] + vv_corr * v[1] + ww_corr * w[1];
- ray[2] = u[2] + vv_corr * v[2] + ww_corr * w[2];
-
- t8_vec_normalize (ray);
-
- out_coords[offset + 0] = out_coords[offset + 0] + radius * ray[0];
- out_coords[offset + 1] = out_coords[offset + 1] + radius * ray[1];
- out_coords[offset + 2] = out_coords[offset + 2] + radius * ray[2];
- }
+ t8_map_triangle_to_sphere (active_tree_vertices, sphere_radius, 1, u_ref, v_ref, w_ref, ref_coords, num_coords,
+ out_coords);
}
- /* Third triangle corner. */
{
- double u[3]; /* Position vector. */
- double v[3]; /* First triangle side. */
- double w[3]; /* Second triangle side. */
-
- u[0] = active_tree_vertices[3 + 0];
- u[1] = active_tree_vertices[3 + 1];
- u[2] = active_tree_vertices[3 + 2];
-
- v[0] = active_tree_vertices[6 + 0] - u[0];
- v[1] = active_tree_vertices[6 + 1] - u[1];
- v[2] = active_tree_vertices[6 + 2] - u[2];
-
- w[0] = active_tree_vertices[0 + 0] - u[0];
- w[1] = active_tree_vertices[0 + 1] - u[1];
- w[2] = active_tree_vertices[0 + 2] - u[2];
-
- /* Reference coordinates from this particular triangle corner. */
+ /* Reference coordinates from third triangle corner. */
const double u_ref[3] = { 0.0, 1.0, 0.0 };
const double v_ref[3] = { 0.0, -1.0, 0.0 };
const double w_ref[3] = { 1.0, 0.0, 0.0 };
- for (size_t i_coord = 0; i_coord < num_coords; i_coord++) {
- const size_t offset = 3 * i_coord;
+ t8_map_triangle_to_sphere (active_tree_vertices, sphere_radius, 2, u_ref, v_ref, w_ref, ref_coords, num_coords,
+ out_coords);
+ }
- const double x = ref_coords[offset + 0];
- const double y = ref_coords[offset + 1];
+ /* For triangles we are done. */
+ if (eclass == T8_ECLASS_TRIANGLE)
+ return;
- /* Compute local triangle coordinate. */
- const double vv = u_ref[0] + x * v_ref[0] + y * w_ref[0];
- const double ww = u_ref[1] + x * v_ref[1] + y * w_ref[1];
+ /*
+ * For prisms we must rescale along the radial direction to pad the shell thickness.
+ */
- /* Correction in order to rectify elements near the corners. */
- const double vv_corr = tan (0.5 * M_PI * (vv - 0.5)) * 0.5 + 0.5;
- const double ww_corr = tan (0.5 * M_PI * (ww - 0.5)) * 0.5 + 0.5;
+ double n[3]; /* Normal vector of the prism's base triangle at the inner shell surface. */
+ t8_vec_tri_normal (active_tree_vertices, active_tree_vertices + 3, active_tree_vertices + 6, n);
+ t8_vec_normalize (n);
- /* Compute and apply the corrected mapping. */
- double ray[3]; /* Ray vector pinning through the triangle at reference coordinates. */
- ray[0] = u[0] + vv_corr * v[0] + ww_corr * w[0];
- ray[1] = u[1] + vv_corr * v[1] + ww_corr * w[1];
- ray[2] = u[2] + vv_corr * v[2] + ww_corr * w[2];
+ double r[3]; /* Radial vector through the first base triangle corners. */
+ r[0] = active_tree_vertices[0];
+ r[1] = active_tree_vertices[1];
+ r[2] = active_tree_vertices[2];
+ t8_vec_normalize (r);
- t8_vec_normalize (ray);
+ /* With this pre-computed denominator we determine the intersection of `r` and `p`. See below. */
+ const double denominator = 1.0 / t8_vec_dot (r, n);
- out_coords[offset + 0] = out_coords[offset + 0] + radius * ray[0];
- out_coords[offset + 1] = out_coords[offset + 1] + radius * ray[1];
- out_coords[offset + 2] = out_coords[offset + 2] + radius * ray[2];
- }
+ for (size_t i_coord = 0; i_coord < num_coords; i_coord++) {
+ const size_t offset = 3 * i_coord;
+
+ /* Position vector `p` pointing to the reference location in the prism. */
+ double p[3];
+ t8_geom_compute_linear_geometry (T8_ECLASS_PRISM, active_tree_vertices, ref_coords + offset, 1, p);
+ t8_vec_rescale (out_coords + offset, t8_vec_dot (p, n) * denominator);
}
}
+/**
+ * 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,
+ double *out_coords) const
+{
+ 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
+
+{
+ t8_geom_evaluate_sphere_tri_prism (active_tree_vertices, T8_ECLASS_PRISM, ref_coords, num_coords, out_coords);
+}
+
static inline void
-t8_geom_evaluate_sphere (const double *active_tree_vertices, const int ndims, const double *ref_coords,
- const size_t num_coords, double *out_coords)
+t8_geom_evaluate_sphere_quad_hex (const double *active_tree_vertices, const int ndims, const double *ref_coords,
+ const size_t num_coords, double *out_coords)
{
double n[3]; /* Normal vector. */
double r[3]; /* Radial vector. */
@@ -308,6 +293,7 @@ t8_geom_evaluate_sphere (const double *active_tree_vertices, const int ndims, co
{
double corr_ref_coords[3]; /* Corrected reference coordinates. */
+ /* Shorthand for code readability. */
const double x = ref_coords[offset + 0];
const double y = ref_coords[offset + 1];
const double z = ref_coords[offset + 2];
@@ -324,13 +310,13 @@ t8_geom_evaluate_sphere (const double *active_tree_vertices, const int ndims, co
t8_geom_linear_interpolation (corr_ref_coords, active_tree_vertices, 3, ndims, p);
}
- const double R = (p[0] * n[0] + p[1] * n[1] + p[2] * n[2]) / (r[0] * n[0] + r[1] * n[1] + r[2] * n[2]);
+ const double radius = t8_vec_dot (p, n) / t8_vec_dot (r, n);
t8_vec_normalize (p);
- out_coords[offset + 0] = R * p[0];
- out_coords[offset + 1] = R * p[1];
- out_coords[offset + 2] = R * p[2];
+ out_coords[offset + 0] = radius * p[0];
+ out_coords[offset + 1] = radius * p[1];
+ out_coords[offset + 2] = radius * p[2];
}
}
@@ -346,8 +332,7 @@ t8_geometry_quadrangulated_spherical_surface::t8_geom_evaluate (t8_cmesh_t cmesh
const double *ref_coords, const size_t num_coords,
double *out_coords) const
{
- /* This routine works just fine for the quadrangulated spherical surface, too. */
- t8_geom_evaluate_sphere (active_tree_vertices, 2, ref_coords, num_coords, out_coords);
+ t8_geom_evaluate_sphere_quad_hex (active_tree_vertices, 2, ref_coords, num_coords, out_coords);
}
/**
@@ -361,7 +346,7 @@ 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
{
- t8_geom_evaluate_sphere (active_tree_vertices, 3, ref_coords, num_coords, out_coords);
+ t8_geom_evaluate_sphere_quad_hex (active_tree_vertices, 3, ref_coords, num_coords, out_coords);
}
T8_EXTERN_C_BEGIN ();
@@ -390,6 +375,13 @@ t8_geometry_triangulated_spherical_surface_new ()
return (t8_geometry_c *) geom;
}
+t8_geometry_c *
+t8_geometry_prismed_spherical_shell_new ()
+{
+ t8_geometry_prismed_spherical_shell *geom = new t8_geometry_prismed_spherical_shell ();
+ return (t8_geometry_c *) geom;
+}
+
t8_geometry_c *
t8_geometry_quadrangulated_spherical_surface_new ()
{
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 1743d7c41b..d7933da542 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.h
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.h
@@ -62,6 +62,12 @@ t8_geometry_quadrangulated_spherical_surface_new ();
t8_geometry_c *
t8_geometry_cubed_spherical_shell_new ();
+/** Create a new spherical_shell geometry.
+ * \return A pointer to an allocated geometry struct.
+ */
+t8_geometry_c *
+t8_geometry_prismed_spherical_shell_new ();
+
T8_EXTERN_C_END ();
#endif /* T8_GEOMETRY_EXAMPLE_H */
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 eed4d423e5..0f979e3e09 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.hxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_examples.hxx
@@ -88,7 +88,7 @@ struct t8_geometry_squared_disk: public t8_geometry_with_vertices
/* Load tree data is inherited from t8_geometry_with_vertices. */
};
-/** This geometry maps the faces of an oktaeder to a spherical surface.
+/** This geometry maps the faces of an octahedron/icosahedron to a spherical surface.
*/
struct t8_geometry_triangulated_spherical_surface: public t8_geometry_with_vertices
{
@@ -99,17 +99,50 @@ struct t8_geometry_triangulated_spherical_surface: public t8_geometry_with_verti
}
/**
- * Map the faces of an oktaeder to a spherical surface.
+ * 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] 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.
*
- * This routine expects an input mesh of eight triangles arranged into an
- * oktaeder. That is two pyramids glued together at their quadratic bases.
- * The z-axis goes through the the pyramid's peak and the x- and y-axis
- * are aligned with the basis' diagonals.
+ * This routine expects an input mesh of triangles arranged into an
+ * octahedron/icosahedron.
+ *
+ */
+ void
+ t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
+ double out_coords[3]) const;
+
+ /* Jacobian, not implemented. */
+ 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
+ {
+ SC_ABORT_NOT_REACHED ();
+ }
+
+ /* Load tree data is inherited from t8_geometry_with_vertices. */
+};
+
+/** This geometry maps general 2D faces to a spherical surface.
+ */
+class t8_geometry_spherical_surface: public t8_geometry_with_vertices {
+ public:
+ /* Basic constructor that sets the dimension and the name. */
+ t8_geometry_spherical_surface (): t8_geometry_with_vertices (2, "t8_spherical_surface")
+ {
+ }
+
+ /**
+ * Maps general 2D faces 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] 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.
+ *
+ * This routine expects an input mesh of 2D elements with their vertices sitting on a sphere.
*
*/
void
@@ -197,4 +230,39 @@ class t8_geometry_cubed_spherical_shell: public t8_geometry_with_vertices {
/* Load tree data is inherited from t8_geometry_with_vertices. */
};
+/** This geometry maps prisms arranged as octahedron (or similar) to a spherical shell.
+ */
+class 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")
+ {
+ }
+
+ /**
+ * 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] 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.
+ *
+ * This routine expects an input mesh of prism arranged as octahedron or similar.
+ *
+ */
+ void
+ t8_geom_evaluate (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
+ double out_coords[3]) const;
+
+ /* Jacobian, not implemented. */
+ 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
+ {
+ SC_ABORT_NOT_REACHED ();
+ }
+
+ /* Load tree data is inherited from t8_geometry_with_vertices. */
+};
+
#endif /* T8_GEOMETRY_EXAMPLES_HXX */
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 f469a24707..242d3716d0 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.cxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.cxx
@@ -23,6 +23,8 @@
#include
#include
#include
+#include
+#include
t8_geometry_linear::t8_geometry_linear (int dim): t8_geometry_with_vertices (dim, "")
{
@@ -54,6 +56,196 @@ t8_geometry_linear::t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtr
SC_ABORT ("Not implemented.");
}
+#if T8_ENABLE_DEBUG
+/* Test whether four given points in 3D are coplanar up to a given tolerance.
+ */
+static int
+t8_four_points_coplanar (const double p_0[3], const double p_1[3], const double p_2[3], const double p_3[3],
+ const double tolerance)
+{
+ /* Let p0, p1, p2, p3 be the four points.
+ * The four points are coplanar if the normal vectors to the triangles
+ * p0, p1, p2 and p0, p2, p3 are pointing in the same direction.
+ *
+ * We build the vectors A = p1 - p0, B = p2 - p0 and C = p3 - p0.
+ * The normal vectors to the triangles are n1 = A x B and n2 = A x C.
+ * These are pointing in the same direction if their cross product is 0.
+ * Hence we check if || n1 x n2 || < tolerance. */
+
+ /* A = p1 - p0 */
+ double A[3];
+ t8_vec_axpyz (p_0, p_1, A, -1);
+
+ /* B = p2 - p0 */
+ double B[3];
+ t8_vec_axpyz (p_0, p_2, B, -1);
+
+ /* C = p3 - p0 */
+ double C[3];
+ t8_vec_axpyz (p_0, p_3, C, -1);
+
+ /* n1 = A x B */
+ double A_cross_B[3];
+ t8_vec_cross (A, B, A_cross_B);
+
+ /* n2 = A x C */
+ double A_cross_C[3];
+ t8_vec_cross (A, C, A_cross_C);
+
+ /* n1 x n2 */
+ double n1_cross_n2[3];
+ t8_vec_cross (A_cross_B, A_cross_C, n1_cross_n2);
+
+ /* || n1 x n2 || */
+ const double norm = t8_vec_norm (n1_cross_n2);
+ return norm < tolerance;
+}
+#endif
+
+void
+t8_geometry_linear::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
+{
+ const t8_eclass_t tree_class = t8_forest_get_tree_class (forest, ltreeid);
+ t8_eclass_scheme_c *ts = t8_forest_get_eclass_scheme (forest, tree_class);
+ const t8_element_shape_t element_shape = ts->t8_element_shape (element);
+ switch (element_shape) {
+ case T8_ECLASS_VERTEX: {
+ /* A point is 'inside' a vertex if they have the same coordinates */
+ double vertex_coords[3];
+ /* Get the vertex coordinates */
+ t8_forest_element_coordinate (forest, ltreeid, element, 0, vertex_coords);
+ /* Check whether the point and the vertex are within tolerance distance
+ * to each other */
+ for (int ipoint = 0; ipoint < num_points; ipoint++) {
+ is_inside[ipoint] = t8_vertex_point_inside (vertex_coords, &points[ipoint * 3], tolerance);
+ }
+ return;
+ }
+ case T8_ECLASS_LINE: {
+ /* A point p is inside a line that is defined by the edge nodes
+ * p_0 and p_1
+ * if and only if the linear system
+ * (p_1 - p_0)x = p - p_0
+ * has a solution x with 0 <= x <= 1
+ */
+ double p_0[3], v[3];
+
+ /* Compute the vertex coordinates of the line */
+ t8_forest_element_coordinate (forest, ltreeid, element, 0, p_0);
+ /* v = p_1 */
+ t8_forest_element_coordinate (forest, ltreeid, element, 1, v);
+ /* v = p_1 - p_0 */
+ t8_vec_axpy (p_0, v, -1);
+ for (int ipoint = 0; ipoint < num_points; ipoint++) {
+ is_inside[ipoint] = t8_line_point_inside (p_0, v, &points[ipoint * 3], tolerance);
+ }
+ return;
+ }
+ case T8_ECLASS_QUAD: {
+ /* We divide the quad in two triangles and use the triangle check. */
+ double p_0[3], p_1[3], p_2[3], p_3[3];
+ /* Compute the vertex coordinates of the quad */
+ t8_forest_element_coordinate (forest, ltreeid, element, 0, p_0);
+ t8_forest_element_coordinate (forest, ltreeid, element, 1, p_1);
+ t8_forest_element_coordinate (forest, ltreeid, element, 2, p_2);
+ t8_forest_element_coordinate (forest, ltreeid, element, 3, p_3);
+
+#if T8_ENABLE_DEBUG
+ /* Issue a warning if the points of the quad do not lie in the same plane */
+ if (!t8_four_points_coplanar (p_0, p_1, p_2, p_3, tolerance)) {
+ t8_debugf ("WARNING: Testing if point is inside a quad that is not coplanar. This test will be inaccurate.\n");
+ }
+#endif
+ double v[3];
+ double w[3];
+ /* v = v - p_0 = p_1 - p_0 */
+ t8_vec_axpyz (p_0, p_1, v, -1);
+ /* w = w - p_0 = p_2 - p_0 */
+ t8_vec_axpyz (p_0, p_2, w, -1);
+ /* Check whether the point is inside the first triangle. */
+ for (int ipoint = 0; ipoint < num_points; ipoint++) {
+ is_inside[ipoint] = t8_triangle_point_inside (p_0, v, w, &points[ipoint * 3], tolerance);
+ }
+ /* If not, check whether the point is inside the second triangle. */
+ /* v = v - p_0 = p_1 - p_0 */
+ t8_vec_axpyz (p_1, p_2, v, -1);
+ /* w = w - p_0 = p_2 - p_0 */
+ t8_vec_axpyz (p_1, p_3, w, -1);
+ for (int ipoint = 0; ipoint < num_points; ipoint++) {
+ if (!is_inside[ipoint]) {
+ /* point_inside is true if the point was inside the first or second triangle. Otherwise it is false. */
+ is_inside[ipoint] = t8_triangle_point_inside (p_1, v, w, &points[ipoint * 3], tolerance);
+ }
+ }
+ return;
+ }
+ case T8_ECLASS_TRIANGLE: {
+ double p_0[3], p_1[3], p_2[3];
+
+ /* Compute the vertex coordinates of the triangle */
+ t8_forest_element_coordinate (forest, ltreeid, element, 0, p_0);
+ t8_forest_element_coordinate (forest, ltreeid, element, 1, p_1);
+ t8_forest_element_coordinate (forest, ltreeid, element, 2, p_2);
+ double v[3];
+ double w[3];
+ /* v = v - p_0 = p_1 - p_0 */
+ t8_vec_axpyz (p_0, p_1, v, -1);
+ /* w = w - p_0 = p_2 - p_0 */
+ t8_vec_axpyz (p_0, p_2, w, -1);
+
+ for (int ipoint = 0; ipoint < num_points; ipoint++) {
+ is_inside[ipoint] = t8_triangle_point_inside (p_0, v, w, &points[ipoint * 3], tolerance);
+ }
+ return;
+ }
+ case T8_ECLASS_TET:
+ case T8_ECLASS_HEX:
+ case T8_ECLASS_PRISM:
+ case T8_ECLASS_PYRAMID: {
+ /* For bilinearly interpolated volume elements, a point is inside an element
+ * if and only if it lies on the inner side of each face.
+ * The inner side is defined as the side where the outside normal vector does not
+ * point to.
+ * The point is on this inner side if and only if the scalar product of
+ * a point on the plane minus the point with the outer normal of the face
+ * is >= 0.
+ *
+ * In other words, let p be the point to check, n the outer normal and x a point
+ * on the plane, then p is on the inner side if and only if
+ * >= 0
+ */
+
+ const int num_faces = ts->t8_element_num_faces (element);
+ /* Assume that every point is inside of the element */
+ for (int ipoint = 0; ipoint < num_points; ipoint++) {
+ is_inside[ipoint] = 1;
+ }
+ for (int iface = 0; iface < num_faces; ++iface) {
+ double face_normal[3];
+ /* Compute the outer normal n of the face */
+ t8_forest_element_face_normal (forest, ltreeid, element, iface, face_normal);
+ /* Compute a point x on the face */
+ const int afacecorner = ts->t8_element_get_face_corner (element, iface, 0);
+ double point_on_face[3];
+ t8_forest_element_coordinate (forest, ltreeid, element, afacecorner, point_on_face);
+ for (int ipoint = 0; ipoint < num_points; ipoint++) {
+ const int is_inside_iface = t8_plane_point_inside (point_on_face, face_normal, &points[ipoint * 3]);
+ if (is_inside_iface == 0) {
+ /* Point is on the outside of face iface. Update is_inside */
+ is_inside[ipoint] = 0;
+ }
+ }
+ }
+ return;
+ }
+ default:
+ SC_ABORT_NOT_REACHED ();
+ }
+}
+
T8_EXTERN_C_BEGIN ();
/* Satisfy the C interface from t8_geometry_linear.h.
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 b056dcd9eb..6840b9dc64 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx
@@ -90,6 +90,20 @@ struct t8_geometry_linear: public t8_geometry_with_vertices
t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
double *jacobian) const;
+ /**
+ * \param[in] forest The forest of the element.
+ * \param[in] ltreeid The local tree id of the element's tree
+ * \param[in] element The element
+ * \param[in] points points to check
+ * \param[in] num_points Number of points to check
+ * \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
+ 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;
+
/* 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 880d83362b..fc23664338 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
@@ -56,6 +56,32 @@ t8_geometry_linear_axis_aligned::t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8
SC_ABORT ("Not implemented.");
}
+void
+t8_geometry_linear_axis_aligned::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 v_min[3];
+ double v_max[3];
+
+ /*Geometry is fully described by v_min and v_max*/
+ t8_forest_element_coordinate (forest, ltreeid, element, 0, v_min);
+ t8_forest_element_coordinate (forest, ltreeid, element, 1, v_max);
+
+ for (int ipoint = 0; ipoint < num_points; ipoint++) {
+ /* A point is inside if it is inbetween the x/y/z-coordinates of v_min and v_max */
+ /* check x-coordinate */
+ /* check y-coordinate */
+ /* check z-coordinate */
+ is_inside[ipoint]
+ = v_min[0] - tolerance <= points[ipoint * 3] && points[ipoint * 3] <= v_max[0] + tolerance
+ && v_min[1] - tolerance <= points[ipoint * 3 + 1] && points[ipoint * 3 + 1] <= v_max[1] + tolerance
+ && v_min[2] - tolerance <= points[ipoint * 3 + 2] && points[ipoint * 3 + 2] <= v_max[2] + tolerance;
+ }
+ return;
+}
+
T8_EXTERN_C_BEGIN ();
/* Satisfy the C interface from t8_geometry_linear_axis_aligned.h.
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 edcc973e74..339e8b446a 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
@@ -92,6 +92,20 @@ struct t8_geometry_linear_axis_aligned: public t8_geometry_with_vertices
virtual 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;
+
+ /**
+ * \param[in] forest The forest of the element.
+ * \param[in] ltreeid The local tree id of the element's tree
+ * \param[in] element The element
+ * \param[in] points points to check
+ * \param[in] num_points Number of points to check
+ * \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
+ 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;
};
#endif /* !T8_GEOMETRY_LINEAR_AXIS_ALIGNED_HXX! */
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 f2e33d03ed..cfcd99cbba 100644
--- a/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.hxx
+++ b/src/t8_geometry/t8_geometry_implementations/t8_geometry_zero.hxx
@@ -31,6 +31,7 @@
#include
#include
+#include
struct t8_geometry_zero: public t8_geometry
{
@@ -86,6 +87,27 @@ struct t8_geometry_zero: public t8_geometry
t8_geom_evaluate_jacobian (t8_cmesh_t cmesh, t8_gloidx_t gtreeid, const double *ref_coords, const size_t num_coords,
double *jacobian) const;
+ /**
+ * \param[in] forest The forest of the element.
+ * \param[in] ltreeid The local tree id of the element's tree
+ * \param[in] element The element
+ * \param[in] points points to check
+ * \param[in] num_points Number of points to check
+ * \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
+ 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 zeros[3] = { 0 };
+ for (int i_point = 0; i_point < num_points; ++i_point) {
+ const int offset = i_point * T8_ECLASS_MAX_DIM;
+ is_inside[i_point] = t8_vertex_point_inside (zeros, points + offset, tolerance);
+ }
+ }
+
/** Update a possible internal data buffer for per tree data.
* This function is called before the first coordinates in a new tree are
* evaluated.
diff --git a/src/t8_geometry/t8_geometry_with_vertices.cxx b/src/t8_geometry/t8_geometry_with_vertices.cxx
index 16c3824d5b..1e91171a82 100644
--- a/src/t8_geometry/t8_geometry_with_vertices.cxx
+++ b/src/t8_geometry/t8_geometry_with_vertices.cxx
@@ -44,8 +44,6 @@ t8_geometry_with_vertices::t8_geom_load_tree_data (t8_cmesh_t cmesh, t8_gloidx_t
/* Load this trees vertices. */
active_tree_vertices = t8_cmesh_get_tree_vertices (cmesh, ltreeid);
- T8_ASSERT (t8_eclass_to_dimension[active_tree_class] == dimension);
-
/* 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
diff --git a/src/t8_geometry/t8_geometry_with_vertices.h b/src/t8_geometry/t8_geometry_with_vertices.h
index 48bf0e1702..4265a4df8e 100644
--- a/src/t8_geometry/t8_geometry_with_vertices.h
+++ b/src/t8_geometry/t8_geometry_with_vertices.h
@@ -44,7 +44,8 @@ T8_EXTERN_C_BEGIN ();
* match the number of corners of the tree.
*/
void
-t8_cmesh_set_tree_vertices (t8_cmesh_t cmesh, t8_gloidx_t gtree_id, double *vertices, int num_vertices);
+t8_cmesh_set_tree_vertices (t8_cmesh_t cmesh, const t8_gloidx_t gtree_id, const double *vertices,
+ const int num_vertices);
T8_EXTERN_C_END ();
diff --git a/src/t8_geometry/t8_geometry_with_vertices.hxx b/src/t8_geometry/t8_geometry_with_vertices.hxx
index 2f39b76ddb..8dd2d8b1a4 100644
--- a/src/t8_geometry/t8_geometry_with_vertices.hxx
+++ b/src/t8_geometry/t8_geometry_with_vertices.hxx
@@ -29,6 +29,7 @@
#define T8_GEOMETRY_WITH_VERTICES_HXX
#include
+#include
#include
#include
#include
diff --git a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx
index ecbca7a8fd..64c3df7c4b 100644
--- a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx
@@ -109,16 +109,16 @@ t8_default_scheme_common_c::t8_element_shape (const t8_element_t *elem) const
return eclass;
}
-/* Given an element's level and dimension, return the number of leafs it
+/* Given an element's level and dimension, return the number of leaves it
* produces at a given uniform refinement level */
static inline t8_gloidx_t
-count_leafs_from_level (int element_level, int refinement_level, int dimension)
+count_leaves_from_level (int element_level, int refinement_level, int dimension)
{
return element_level > refinement_level ? 0 : sc_intpow64 (2, dimension * (refinement_level - element_level));
}
t8_gloidx_t
-t8_default_scheme_common_c::t8_element_count_leafs (const t8_element_t *t, int level) const
+t8_default_scheme_common_c::t8_element_count_leaves (const t8_element_t *t, int level) const
{
int element_level = t8_element_level (t);
@@ -129,7 +129,7 @@ t8_default_scheme_common_c::t8_element_count_leafs (const t8_element_t *t, int l
int level_diff = level - element_level;
return element_level > level ? 0 : 2 * sc_intpow64 (8, level_diff) - sc_intpow64 (6, level_diff);
}
- return count_leafs_from_level (element_level, level, dim);
+ return count_leaves_from_level (element_level, level, dim);
}
/* Count the number of siblings.
@@ -144,13 +144,13 @@ t8_default_scheme_common_c::t8_element_num_siblings (const t8_element_t *elem) c
}
t8_gloidx_t
-t8_default_scheme_common_c::t8_element_count_leafs_from_root (int level) const
+t8_default_scheme_common_c::t8_element_count_leaves_from_root (int level) const
{
if (eclass == T8_ECLASS_PYRAMID) {
return 2 * sc_intpow64u (8, level) - sc_intpow64u (6, level);
}
int dim = t8_eclass_to_dimension[eclass];
- return count_leafs_from_level (0, level, dim);
+ return count_leaves_from_level (0, level, dim);
}
void
diff --git a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
index b1041946ee..eb9fda8d31 100644
--- a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
@@ -63,7 +63,7 @@ class t8_default_scheme_common_c: public t8_eclass_scheme_c {
* children.
*/
virtual t8_gloidx_t
- t8_element_count_leafs (const t8_element_t *t, int level) const;
+ t8_element_count_leaves (const t8_element_t *t, int level) const;
/** Compute the number of siblings of an element. That is the number of
* Children of its parent.
@@ -76,11 +76,11 @@ class t8_default_scheme_common_c: public t8_eclass_scheme_c {
/** 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_leafs if the input element
+ * \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_leafs_from_root (int level) const;
+ t8_element_count_leaves_from_root (int level) const;
/** The common implementation of the general function for the default scheme
* has no effect. This function literally does nothing.
diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.h b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.h
deleted file mode 100644
index a0d38b5aa2..0000000000
--- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.h
+++ /dev/null
@@ -1,46 +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_default_hex.h
- */
-
-#ifndef T8_DEFAULT_HEX_H
-#define T8_DEFAULT_HEX_H
-
-#include
-#include
-
-T8_EXTERN_C_BEGIN ();
-
-/** The structure holding a hexahedral element in the default scheme.
- * We make this definition public for interoperability of element classes.
- * We might want to put this into a private, scheme-specific header file.
- */
-typedef p8est_quadrant_t t8_phex_t;
-
-/** Provide an implementation for the hexahedral element class. */
-t8_eclass_scheme_t*
-t8_default_scheme_new_hex (void);
-
-T8_EXTERN_C_END ();
-
-#endif /* !T8_DEFAULT_HEX_H */
diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.hxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.hxx
index a8467e76b8..b93fd999a7 100644
--- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.hxx
@@ -468,7 +468,7 @@ struct t8_default_scheme_hex_c: public t8_default_scheme_common_c
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const;
diff --git a/src/t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.hxx b/src/t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.hxx
index 3bb49d3ef6..034bffb836 100644
--- a/src/t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.hxx
@@ -475,7 +475,7 @@ struct t8_default_scheme_line_c: public t8_default_scheme_common_c
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const;
diff --git a/src/t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.hxx b/src/t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.hxx
index 3bd5d68249..86f2b55b1e 100644
--- a/src/t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.hxx
@@ -455,7 +455,7 @@ struct t8_default_scheme_prism_c: public t8_default_scheme_common_c
* given linear id in a uniform refinement.
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
- * \param [in] id The linear id. id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * \param [in] id The linear id. id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const;
diff --git a/src/t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.hxx b/src/t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.hxx
index ebd1a7d389..3bcd0d3e8e 100644
--- a/src/t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.hxx
@@ -448,7 +448,7 @@ struct t8_default_scheme_pyramid_c: public t8_default_scheme_common_c
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const;
diff --git a/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_bits.c b/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_bits.c
index 5b543436ac..8e7ab7d24f 100644
--- a/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_bits.c
+++ b/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_bits.c
@@ -1401,7 +1401,7 @@ t8_dpyramid_get_face_corner (const t8_dpyramid_t *pyra, int face, int corner)
return t8_dtet_face_corner[face][corner];
}
else {
- int corner_number = t8_dpyramid_face_corner[face][corner];
+ const int corner_number = t8_dpyramid_face_corner[pyra->pyramid.type - T8_DPYRAMID_FIRST_TYPE][face][corner];
T8_ASSERT (0 <= corner_number && corner_number < T8_DPYRAMID_FACES);
return corner_number;
}
diff --git a/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.c b/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.c
index 233dd84673..1eeb1964e5 100644
--- a/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.c
+++ b/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.c
@@ -128,10 +128,19 @@ const int t8_dpyramid_tritype_rootface_to_face[2][4] = {
{ 2, 0, 2, 0 },
{ 1, 0, 1, 0 } };
-const int t8_dpyramid_face_corner[5][4] = {
+const int t8_dpyramid_face_corner[2][5][4] = {
+{
{ 0, 2, 4, -1 },
{ 1, 3, 4, -1 },
{ 0, 1, 4, -1 },
{ 2, 3, 4, -1 },
- { 0, 1, 2, 3 } };
+ { 0, 1, 2, 3 }
+},{
+ { 2, 3, 4, -1 },
+ { 0, 1, 4, -1 },
+ { 1, 3, 4, -1 },
+ { 0, 2, 4, -1 },
+ { 0, 1, 2, 3 }
+}
+};
/* clang-format on */
\ No newline at end of file
diff --git a/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.h b/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.h
index ef07d74d21..3360c7e137 100644
--- a/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.h
+++ b/src/t8_schemes/t8_default/t8_default_pyramid/t8_dpyramid_connectivity.h
@@ -111,8 +111,8 @@ extern const int t8_dpyramid_tritype_rootface_to_face[2][4];
extern const int t8_dtet_type_cid_to_pyramid_parenttype[6][8];
/** The corner numbers of the face of a pyramid
- * corner_number = A(face, corner_number_at_face)
+ * corner_number = A(pyramid_type, face, corner_number_at_face)
*/
-extern const int t8_dpyramid_face_corner[5][4];
+extern const int t8_dpyramid_face_corner[2][5][4];
#endif // T8_DPYRAMID_CONNECTIVITY_H
diff --git a/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad.h b/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad.h
deleted file mode 100644
index da00ddd958..0000000000
--- a/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad.h
+++ /dev/null
@@ -1,80 +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_default_quad.h
- * We use a p4est_quadrant_t object as storage for the T8 quadrant.
- * To record if and if yes, how this quadrant is part of a 3D octant, we use
- * the member pad8 for the surrounding toplevel dimension (2 or 3), pad16 for
- * the direction of its normal relative to a toplevel octant (0, 1, or 2), and
- * p.user_long for the p4est_qcoord_t coordinate in the normal direction.
- */
-
-#ifndef T8_DEFAULT_QUAD_H
-#define T8_DEFAULT_QUAD_H
-
-#include
-#include
-
-/** The structure holding a quadrilateral element in the default scheme.
- * We make this definition public for interoperability of element classes.
- * We might want to put this into a private, scheme-specific header file.
- */
-typedef p4est_quadrant_t t8_pquad_t;
-
-/** Return the toplevel dimension. */
-#define T8_QUAD_GET_TDIM(quad) ((int) (quad)->pad8)
-
-/** Return the direction of the third dimension.
- * This is only valid to call if the toplevel dimension is three.
- */
-#define T8_QUAD_GET_TNORMAL(quad) (T8_ASSERT (T8_QUAD_GET_TDIM (quad) == 3), ((int) (quad)->pad16))
-
-/** Return the coordinate in the third dimension.
- * This is only valid to call if the toplevel dimension is three.
- */
-#define T8_QUAD_GET_TCOORD(quad) (T8_ASSERT (T8_QUAD_GET_TDIM (quad) == 3), ((int) (quad)->p.user_long))
-
-/** Set the toplevel dimension of a quadrilateral. */
-#define T8_QUAD_SET_TDIM(quad, dim) \
- do { \
- T8_ASSERT ((dim) == 2 || (dim) == 3); \
- (quad)->pad8 = (int8_t) (dim); \
- } while (0)
-
-/** Set the direction of the third dimension. */
-#define T8_QUAD_SET_TNORMAL(quad, normal) \
- do { \
- T8_ASSERT ((normal) >= 0 && (normal) < 3); \
- (quad)->pad16 = (int16_t) (normal); \
- } while (0)
-
-/** Set the coordinate in the third dimension. */
-#define T8_QUAD_SET_TCOORD(quad, coord) \
- do { \
- (quad)->p.user_long = (long) (coord); \
- } while (0)
-
-/** Provide an implementation for the quadrilateral element class. */
-t8_eclass_scheme_t*
-t8_default_scheme_new_quad (void);
-
-#endif /* !T8_DEFAULT_QUAD_H */
diff --git a/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.hxx b/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.hxx
index ef149aa1a8..c4d6360fd9 100644
--- a/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.hxx
@@ -499,7 +499,7 @@ struct t8_default_scheme_quad_c: public t8_default_scheme_common_c
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const;
diff --git a/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet.c b/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet.c
deleted file mode 100644
index 38d5dc0410..0000000000
--- a/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet.c
+++ /dev/null
@@ -1,219 +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
-
-typedef t8_dtet_t t8_default_tet_t;
-
-/* This function is used by other element functions and we thus need to
- * declare it up here */
-static t8_linearidx_t
-t8_default_tet_get_linear_id (const t8_element_t *elem, int level);
-
-static size_t
-t8_default_tet_size (void)
-{
- return sizeof (t8_default_tet_t);
-}
-
-static int
-t8_default_tet_maxlevel (void)
-{
- return T8_DTET_MAXLEVEL;
-}
-
-static int
-t8_default_tet_level (const t8_element_t *elem)
-{
- return t8_dtet_get_level ((t8_dtet_t *) elem);
-}
-
-static void
-t8_default_tet_copy (const t8_element_t *source, t8_element_t *dest)
-{
- t8_dtet_copy ((const t8_dtet_t *) source, (t8_dtet_t *) dest);
-}
-
-static int
-t8_default_tet_compare (const t8_element_t *elem1, const t8_element_t *elem2)
-{
- int maxlvl;
- t8_linearidx_t id1, id2;
-
- /* Compute the bigger level of the two */
- maxlvl = SC_MAX (t8_default_tet_level (elem1), t8_default_tet_level (elem2));
- /* Compute the linear ids of the elements */
- id1 = t8_default_tet_get_linear_id (elem1, maxlvl);
- id2 = t8_default_tet_get_linear_id (elem2, maxlvl);
- /* return negative if id1 < id2, zero if id1 = id2, positive if id1 > id2 */
- return id1 < id2 ? -1 : id1 != id2;
-}
-
-static void
-t8_default_tet_parent (const t8_element_t *elem, t8_element_t *parent)
-{
- const t8_default_tet_t *t = (const t8_default_tet_t *) elem;
- t8_default_tet_t *p = (t8_default_tet_t *) parent;
-
- t8_dtet_parent (t, p);
-}
-
-static void
-t8_default_tet_sibling (const t8_element_t *elem, int sibid, t8_element_t *sibling)
-{
- const t8_default_tet_t *t = (const t8_default_tet_t *) elem;
- t8_default_tet_t *s = (t8_default_tet_t *) sibling;
-
- t8_dtet_sibling (t, sibid, s);
-}
-
-static void
-t8_default_tet_child (const t8_element_t *elem, int childid, t8_element_t *child)
-{
- const t8_default_tet_t *t = (const t8_default_tet_t *) elem;
- t8_default_tet_t *c = (t8_default_tet_t *) child;
-
- t8_dtet_child (t, childid, c);
-}
-
-static void
-t8_default_tet_children (const t8_element_t *elem, int length, t8_element_t *c[])
-{
- T8_ASSERT (length == T8_DTET_CHILDREN);
-
- t8_dtet_childrenpv ((const t8_dtet_t *) elem, (t8_dtet_t **) c);
-}
-
-static int
-t8_default_tet_child_id (const t8_element_t *elem)
-{
- return t8_dtet_child_id ((t8_dtet_t *) elem);
-}
-
-static int
-t8_default_tet_is_family (t8_element_t **fam)
-{
- return t8_dtet_is_familypv ((const t8_dtet_t **) fam);
-}
-
-static void
-t8_default_tet_nca (const t8_element_t *elem1, const t8_element_t *elem2, t8_element_t *nca)
-{
- const t8_default_tet_t *t1 = (const t8_default_tet_t *) elem1;
- const t8_default_tet_t *t2 = (const t8_default_tet_t *) elem2;
- t8_default_tet_t *c = (t8_default_tet_t *) nca;
-
- t8_dtet_nearest_common_ancestor (t1, t2, c);
-}
-
-static void
-t8_default_tet_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id)
-{
- T8_ASSERT (0 <= level && level <= T8_DTET_MAXLEVEL);
- T8_ASSERT (0 <= id && id < ((t8_linearidx_t) 1) << 3 * level);
-
- t8_dtet_init_linear_id ((t8_default_tet_t *) elem, id, level);
-}
-
-static t8_linearidx_t
-t8_default_tet_get_linear_id (const t8_element_t *elem, int level)
-{
- T8_ASSERT (0 <= level && level <= T8_DTET_MAXLEVEL);
-
- return t8_dtet_linear_id ((t8_default_tet_t *) elem, level);
-}
-
-static void
-t8_default_tet_successor (const t8_element_t *elem1, t8_element_t *elem2, int level)
-{
- T8_ASSERT (0 <= level && level <= T8_DTET_MAXLEVEL);
-
- t8_dtet_successor ((const t8_default_tet_t *) elem1, (t8_default_tet_t *) elem2, level);
-}
-
-static void
-t8_default_tet_first_descendant (const t8_element_t *elem, t8_element_t *desc)
-{
- t8_dtet_first_descendant ((t8_dtet_t *) elem, (t8_dtet_t *) desc);
-}
-
-static void
-t8_default_tet_last_descendant (const t8_element_t *elem, t8_element_t *desc)
-{
- t8_dtet_last_descendant ((t8_dtet_t *) elem, (t8_dtet_t *) desc);
-}
-
-static void
-t8_default_tet_anchor (const t8_element_t *elem, int anchor[3])
-{
- t8_dtet_t *tet = (t8_dtet_t *) elem;
-
- anchor[0] = tet->x;
- anchor[1] = tet->y;
- anchor[2] = tet->z;
-}
-
-static int
-t8_default_tet_root_len (const t8_element_t *elem)
-{
- return T8_DTET_ROOT_LEN;
-}
-
-t8_eclass_scheme_t *
-t8_default_scheme_new_tet (void)
-{
- t8_eclass_scheme_t *ts;
-
- ts = T8_ALLOC_ZERO (t8_eclass_scheme_t, 1);
- ts->eclass = T8_ECLASS_TET;
-
- ts->elem_size = t8_default_tet_size;
- ts->elem_maxlevel = t8_default_tet_maxlevel;
-
- ts->elem_level = t8_default_tet_level;
- ts->elem_copy = t8_default_tet_copy;
- ts->elem_compare = t8_default_tet_compare;
- ts->elem_parent = t8_default_tet_parent;
- ts->elem_sibling = t8_default_tet_sibling;
- ts->elem_child = t8_default_tet_child;
- ts->elem_children = t8_default_tet_children;
- ts->elem_child_id = t8_default_tet_child_id;
- ts->elem_is_family = t8_default_tet_is_family;
- ts->elem_nca = t8_default_tet_nca;
- ts->elem_set_linear_id = t8_default_tet_set_linear_id;
- ts->elem_get_linear_id = t8_default_tet_get_linear_id;
- ts->elem_successor = t8_default_tet_successor;
- ts->elem_first_desc = t8_default_tet_first_descendant;
- ts->elem_last_desc = t8_default_tet_last_descendant;
- ts->elem_anchor = t8_default_tet_anchor;
- ts->elem_root_len = t8_default_tet_root_len;
-
- ts->elem_new = t8_default_mempool_alloc;
- ts->elem_destroy = t8_default_mempool_free;
-
- ts->ts_destroy = t8_default_scheme_mempool_destroy;
- ts->ts_context = sc_mempool_new (sizeof (t8_default_tet_t));
-
- return ts;
-}
diff --git a/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet.h b/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet.h
deleted file mode 100644
index f7d66e9b10..0000000000
--- a/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet.h
+++ /dev/null
@@ -1,42 +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_default_tet.h
- * The default implementation for tetrahedra.
- */
-
-#ifndef T8_DEFAULT_TET_H
-#define T8_DEFAULT_TET_H
-
-#include
-
-T8_EXTERN_C_BEGIN ();
-
-/** Provide an implementation for the tetrahedral element class.
- * It is written as a self-contained library in the t8_dtet_* files.
- */
-t8_eclass_scheme_t*
-t8_default_scheme_new_tet (void);
-
-T8_EXTERN_C_END ();
-
-#endif /* !T8_DEFAULT_TET_H */
diff --git a/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.hxx b/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.hxx
index 5f1176fc30..cca15c893d 100644
--- a/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.hxx
@@ -419,7 +419,7 @@ struct t8_default_scheme_tet_c: public t8_default_scheme_common_c
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const;
diff --git a/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri.h b/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri.h
deleted file mode 100644
index f0e0e34db4..0000000000
--- a/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri.h
+++ /dev/null
@@ -1,42 +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_default_tri.h
- * The default implementation for triangles.
- */
-
-#ifndef T8_DEFAULT_TRI_H
-#define T8_DEFAULT_TRI_H
-
-#include
-
-T8_EXTERN_C_BEGIN ();
-
-/** Provide an implementation for the triangle element class. It is written as a self-contained library in the
- * t8_dtri_* files.
- */
-t8_eclass_scheme_t *
-t8_default_scheme_new_tri (void);
-
-T8_EXTERN_C_END ();
-
-#endif /* !T8_DEFAULT_TET_H */
diff --git a/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.hxx b/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.hxx
index e708e8f6fa..8dffa6eddc 100644
--- a/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.hxx
@@ -413,7 +413,7 @@ struct t8_default_scheme_tri_c: public t8_default_scheme_common_c
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const;
diff --git a/src/t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.hxx b/src/t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.hxx
index d3325ed2bc..3be333a22c 100644
--- a/src/t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.hxx
@@ -501,7 +501,7 @@ struct t8_default_scheme_vertex_c: public t8_default_scheme_common_c
* \param [in,out] elem The element whose entries will be set.
* \param [in] level The level of the uniform refinement to consider.
* \param [in] id The linear id.
- * id must fulfil 0 <= id < 'number of leafs in the uniform refinement'
+ * id must fulfil 0 <= id < 'number of leaves in the uniform refinement'
*/
virtual void
t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const;
diff --git a/src/t8_vec.h b/src/t8_vec.h
index a2e9824c0e..94010cfeb7 100644
--- a/src/t8_vec.h
+++ b/src/t8_vec.h
@@ -29,8 +29,6 @@
#include
-T8_EXTERN_C_BEGIN ();
-
/** Vector norm.
* \param [in] vec A 3D vector.
* \return The norm of \a vec.
@@ -197,9 +195,57 @@ t8_vec_diff (const double vec_x[3], const double vec_y[3], double diff[3])
static inline int
t8_vec_eq (const double vec_x[3], const double vec_y[3], const double eps)
{
- return fabs (vec_x[0] - vec_y[0]) < eps && fabs (vec_x[1] - vec_y[1]) < eps && fabs (vec_x[2] - vec_y[2]) < eps;
+ T8_ASSERT (eps > 0);
+ return fabs (vec_x[0] - vec_y[0]) <= eps && fabs (vec_x[1] - vec_y[1]) <= eps && fabs (vec_x[2] - vec_y[2]) <= eps;
}
-T8_EXTERN_C_END ();
+/** Rescale a vector to a new length.
+ * \param [in,out] vec A 3D vector.
+ * \param [in] new_length New length of the vector.
+ */
+static inline void
+t8_vec_rescale (double vec[3], const double new_length)
+{
+ t8_vec_normalize (vec);
+ t8_vec_ax (vec, new_length);
+}
+
+/** Compute the normal of a triangle given by its three vertices.
+ * \param [in] p1 A 3D vector.
+ * \param [in] p2 A 3D vector.
+ * \param [in] p3 A 3D vector.
+ * \param [out] Normal vector of the triangle. (Not necessarily of length 1!)
+ */
+static inline void
+t8_vec_tri_normal (const double p1[3], const double p2[3], const double p3[3], double normal[3])
+{
+ double a[3]; /* First triangle side. */
+ double b[3]; /* Second triangle side. */
+
+ a[0] = p2[0] - p1[0];
+ a[1] = p2[1] - p1[1];
+ a[2] = p2[2] - p1[2];
+
+ b[0] = p3[0] - p1[0];
+ b[1] = p3[1] - p1[1];
+ b[2] = p3[2] - p1[2];
+
+ t8_vec_cross (a, b, normal);
+}
+
+/** Swap the components of two vectors.
+ * \param [in,out] p1 A 3D vector.
+ * \param [in,out] p2 A 3D vector.
+ */
+static inline void
+t8_vec_swap (double p1[3], double p2[3])
+{
+ double tmp;
+ for (int i = 0; i < 3; i++) {
+ tmp = p1[i];
+ p1[i] = p2[i];
+ p2[i] = tmp;
+ }
+}
#endif /* !T8_VEC_H! */
diff --git a/src/t8_version.h b/src/t8_version.h
index 80b8c4b63e..fd9cea599f 100644
--- a/src/t8_version.h
+++ b/src/t8_version.h
@@ -47,7 +47,9 @@
#define T8_VERSION_H
#include
+#ifndef T8_CMAKE_BUILD
#include
+#endif
/* In order to convert a macro to a string, we
* need to pass it through these two helper macros. */
diff --git a/src/t8_vtk.h b/src/t8_vtk.h
index c16896064c..f96ddc18ce 100644
--- a/src/t8_vtk.h
+++ b/src/t8_vtk.h
@@ -47,12 +47,7 @@
#define T8_VTK_FLOAT_TYPE double
#endif
-#ifndef T8_VTK_BINARY
-#define T8_VTK_ASCII 1
#define T8_VTK_FORMAT_STRING "ascii"
-#else
-#define T8_VTK_FORMAT_STRING "binary"
-#endif
#if T8_WITH_VTK
#define t8_vtk_locidx_array_type_t vtkTypeInt32Array
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000000..cacb44c8d1
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,86 @@
+add_library( gtest ${CMAKE_CURRENT_LIST_DIR}/../thirdparty/googletest-mpi/gtest/gtest-all.cc )
+target_include_directories( gtest PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../thirdparty/googletest-mpi ${CMAKE_CURRENT_LIST_DIR}/.. )
+
+function( add_t8_test )
+ set( options "" )
+ set( oneValueArgs "NAME" )
+ set( multiValueArgs "SOURCES" )
+ cmake_parse_arguments( ADD_T8_TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ add_executable( ${ADD_T8_TEST_NAME} ${ADD_T8_TEST_SOURCES} )
+ target_link_libraries( ${ADD_T8_TEST_NAME} PRIVATE T8 gtest )
+ add_test( NAME ${ADD_T8_TEST_NAME} COMMAND ./${ADD_T8_TEST_NAME} )
+endfunction()
+
+# Copy test files to build folder so that the t8_test programs can find them.
+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_cad_linkage SOURCES t8_gtest_main.cxx t8_gtest_cad_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_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_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_element_general_function SOURCES t8_gtest_main.cxx t8_forest/t8_gtest_element_general_function.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_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 SOURCES t8_gtest_main.cxx t8_geometry/t8_gtest_geometry.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_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 )
+
+copy_test_file( test_cube_unstructured_1.inp )
+copy_test_file( test_cube_unstructured_2.inp )
+copy_test_file( test_vtk_tri.vtu )
+copy_test_file( test_vtk_cube.vtp )
+copy_test_file( test_parallel_file.pvtu )
+copy_test_file( test_polydata.pvtp )
diff --git a/test/Makefile.am b/test/Makefile.am
index 68179fa3c8..aaf6bb0161 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -20,19 +20,18 @@ t8code_googletest_programs = \
test/t8_schemes/t8_gtest_face_neigh \
test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear \
test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear_axis_aligned \
- test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_occ \
+ test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_cad \
test/t8_gtest_eclass \
test/t8_gtest_vec \
test/t8_gtest_mat \
test/t8_gtest_refcount \
- test/t8_gtest_occ_linkage \
+ test/t8_gtest_cad_linkage \
test/t8_gtest_version \
test/t8_schemes/t8_gtest_init_linear_id \
test/t8_gtest_basics \
test/t8_schemes/t8_gtest_ancestor \
test/t8_cmesh/t8_gtest_hypercube \
- test/t8_cmesh/t8_gtest_cmesh_copy \
- test/t8_schemes/t8_gtest_element_count_leafs \
+ test/t8_schemes/t8_gtest_element_count_leaves \
test/t8_schemes/t8_gtest_element_ref_coords \
test/t8_geometry/t8_gtest_geometry_handling \
test/t8_schemes/t8_gtest_descendant \
@@ -40,6 +39,7 @@ t8code_googletest_programs = \
test/t8_schemes/t8_gtest_equal \
test/t8_cmesh/t8_gtest_cmesh_face_is_boundary \
test/t8_cmesh/t8_gtest_cmesh_partition \
+ test/t8_cmesh/t8_gtest_cmesh_copy \
test/t8_cmesh/t8_gtest_cmesh_set_partition_offsets \
test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices \
test/t8_forest/t8_gtest_element_volume \
@@ -54,6 +54,7 @@ t8code_googletest_programs = \
test/t8_data/t8_gtest_shmem \
test/t8_forest/t8_gtest_half_neighbors \
test/t8_forest/t8_gtest_find_owner \
+ test/t8_forest/t8_gtest_forest_face_normal \
test/t8_schemes/t8_gtest_face_descendant \
test/t8_geometry/t8_gtest_point_inside \
test/t8_forest/t8_gtest_user_data \
@@ -67,8 +68,10 @@ t8code_googletest_programs = \
test/t8_forest_incomplete/t8_gtest_iterate_replace \
test/t8_forest_incomplete/t8_gtest_empty_local_tree \
test/t8_forest_incomplete/t8_gtest_empty_global_tree \
+ test/t8_cmesh/t8_gtest_cmesh_tree_vertices_negative_volume \
test/t8_schemes/t8_gtest_default \
- test/t8_schemes/t8_gtest_child_parent_face
+ test/t8_schemes/t8_gtest_child_parent_face \
+ test/t8_cmesh_generator/t8_gtest_cmesh_generator_test
test_t8_IO_t8_gtest_vtk_reader_SOURCES = \
test/t8_gtest_main.cxx \
@@ -98,9 +101,9 @@ test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_linear_axis_align
test/t8_gtest_main.cxx \
test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_linear_axis_aligned.cxx
-test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_occ_SOURCES = \
+test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_cad_SOURCES = \
test/t8_gtest_main.cxx \
- test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_occ.cxx
+ test/t8_geometry/t8_geometry_implementations/t8_gtest_geometry_cad.cxx
test_t8_gtest_eclass_SOURCES = \
test/t8_gtest_main.cxx \
@@ -118,9 +121,9 @@ test_t8_gtest_refcount_SOURCES = \
test/t8_gtest_main.cxx \
test/t8_gtest_refcount.cxx
-test_t8_gtest_occ_linkage_SOURCES = \
+test_t8_gtest_cad_linkage_SOURCES = \
test/t8_gtest_main.cxx \
- test/t8_gtest_occ_linkage.cxx
+ test/t8_gtest_cad_linkage.cxx
test_t8_gtest_version_SOURCES = \
test/t8_gtest_main.cxx \
@@ -142,17 +145,13 @@ test_t8_cmesh_t8_gtest_hypercube_SOURCES = \
test/t8_gtest_main.cxx \
test/t8_cmesh/t8_gtest_hypercube.cxx
-test_t8_cmesh_t8_gtest_cmesh_copy_SOURCES = \
- test/t8_gtest_main.cxx \
- test/t8_cmesh/t8_gtest_cmesh_copy.cxx
-
test_t8_cmesh_t8_gtest_cmesh_set_join_by_vertices_SOURCES = \
test/t8_gtest_main.cxx \
test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx
-test_t8_schemes_t8_gtest_element_count_leafs_SOURCES = \
+test_t8_schemes_t8_gtest_element_count_leaves_SOURCES = \
test/t8_gtest_main.cxx \
- test/t8_schemes/t8_gtest_element_count_leafs.cxx
+ test/t8_schemes/t8_gtest_element_count_leaves.cxx
test_t8_schemes_t8_gtest_element_ref_coords_SOURCES = \
test/t8_gtest_main.cxx \
@@ -234,6 +233,10 @@ test_t8_forest_t8_gtest_find_owner_SOURCES = \
test/t8_gtest_main.cxx \
test/t8_forest/t8_gtest_find_owner.cxx
+test_t8_forest_t8_gtest_forest_face_normal_SOURCES = \
+ test/t8_gtest_main.cxx \
+ test/t8_forest/t8_gtest_forest_face_normal.cxx
+
test_t8_schemes_t8_gtest_face_descendant_SOURCES = \
test/t8_gtest_main.cxx \
test/t8_schemes/t8_gtest_face_descendant.cxx
@@ -282,6 +285,10 @@ test_t8_forest_incomplete_t8_gtest_empty_global_tree_SOURCES = \
test/t8_gtest_main.cxx \
test/t8_forest_incomplete/t8_gtest_empty_global_tree.cxx
+test_t8_cmesh_t8_gtest_cmesh_tree_vertices_negative_volume_SOURCES = \
+ test/t8_gtest_main.cxx \
+ test/t8_cmesh/t8_gtest_cmesh_tree_vertices_negative_volume.cxx
+
test_t8_schemes_t8_gtest_default_SOURCES = \
test/t8_gtest_main.cxx \
test/t8_schemes/t8_gtest_default.cxx
@@ -290,6 +297,14 @@ test_t8_schemes_t8_gtest_child_parent_face_SOURCES = \
test/t8_gtest_main.cxx \
test/t8_schemes/t8_gtest_child_parent_face.cxx
+test_t8_cmesh_generator_t8_gtest_cmesh_generator_test_SOURCES = \
+ test/t8_gtest_main.cxx \
+ test/t8_cmesh_generator/t8_gtest_cmesh_generator_test.cxx
+
+test_t8_cmesh_t8_gtest_cmesh_copy_SOURCES = \
+ test/t8_gtest_main.cxx \
+ test/t8_cmesh/t8_gtest_cmesh_copy.cxx
+
#define ld and cpp flags for all targets
t8_gtest_target_ld_add = $(LDADD) test/libgtest.la
t8_gtest_target_ld_flags = $(AM_LDFLAGS) -pthread
@@ -322,9 +337,9 @@ test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_linear_axis_align
test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_linear_axis_aligned_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_linear_axis_aligned_CPPFLAGS = $(t8_gtest_target_cpp_flags)
-test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_occ_LDADD = $(t8_gtest_target_ld_add)
-test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_occ_LDFLAGS = $(t8_gtest_target_ld_flags)
-test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_occ_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_cad_LDADD = $(t8_gtest_target_ld_add)
+test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_cad_LDFLAGS = $(t8_gtest_target_ld_flags)
+test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_cad_CPPFLAGS = $(t8_gtest_target_cpp_flags)
test_t8_gtest_eclass_LDADD = $(t8_gtest_target_ld_add)
test_t8_gtest_eclass_LDFLAGS = $(t8_gtest_target_ld_flags)
@@ -342,9 +357,9 @@ test_t8_gtest_refcount_LDADD = $(t8_gtest_target_ld_add)
test_t8_gtest_refcount_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_gtest_refcount_CPPFLAGS = $(t8_gtest_target_cpp_flags)
-test_t8_gtest_occ_linkage_LDADD = $(t8_gtest_target_ld_add)
-test_t8_gtest_occ_linkage_LDFLAGS = $(t8_gtest_target_ld_flags)
-test_t8_gtest_occ_linkage_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+test_t8_gtest_cad_linkage_LDADD = $(t8_gtest_target_ld_add)
+test_t8_gtest_cad_linkage_LDFLAGS = $(t8_gtest_target_ld_flags)
+test_t8_gtest_cad_linkage_CPPFLAGS = $(t8_gtest_target_cpp_flags)
test_t8_gtest_version_LDADD = $(t8_gtest_target_ld_add)
test_t8_gtest_version_LDFLAGS = $(t8_gtest_target_ld_flags)
@@ -366,17 +381,13 @@ test_t8_cmesh_t8_gtest_hypercube_LDADD = $(t8_gtest_target_ld_add)
test_t8_cmesh_t8_gtest_hypercube_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_cmesh_t8_gtest_hypercube_CPPFLAGS = $(t8_gtest_target_cpp_flags)
-test_t8_cmesh_t8_gtest_cmesh_copy_LDADD = $(t8_gtest_target_ld_add)
-test_t8_cmesh_t8_gtest_cmesh_copy_LDFLAGS = $(t8_gtest_target_ld_flags)
-test_t8_cmesh_t8_gtest_cmesh_copy_CPPFLAGS = $(t8_gtest_target_cpp_flags)
-
test_t8_cmesh_t8_gtest_cmesh_set_join_by_vertices_LDADD = $(t8_gtest_target_ld_add)
test_t8_cmesh_t8_gtest_cmesh_set_join_by_vertices_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_cmesh_t8_gtest_cmesh_set_join_by_vertices_CPPFLAGS = $(t8_gtest_target_cpp_flags)
-test_t8_schemes_t8_gtest_element_count_leafs_LDADD = $(t8_gtest_target_ld_add)
-test_t8_schemes_t8_gtest_element_count_leafs_LDFLAGS = $(t8_gtest_target_ld_flags)
-test_t8_schemes_t8_gtest_element_count_leafs_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+test_t8_schemes_t8_gtest_element_count_leaves_LDADD = $(t8_gtest_target_ld_add)
+test_t8_schemes_t8_gtest_element_count_leaves_LDFLAGS = $(t8_gtest_target_ld_flags)
+test_t8_schemes_t8_gtest_element_count_leaves_CPPFLAGS = $(t8_gtest_target_cpp_flags)
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)
@@ -458,6 +469,10 @@ test_t8_forest_t8_gtest_find_owner_LDADD = $(t8_gtest_target_ld_add)
test_t8_forest_t8_gtest_find_owner_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_forest_t8_gtest_find_owner_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+test_t8_forest_t8_gtest_forest_face_normal_LDADD = $(t8_gtest_target_ld_add)
+test_t8_forest_t8_gtest_forest_face_normal_LDFLAGS = $(t8_gtest_target_ld_flags)
+test_t8_forest_t8_gtest_forest_face_normal_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+
test_t8_schemes_t8_gtest_face_descendant_LDADD = $(t8_gtest_target_ld_add)
test_t8_schemes_t8_gtest_face_descendant_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_schemes_t8_gtest_face_descendant_CPPFLAGS = $(t8_gtest_target_cpp_flags)
@@ -510,6 +525,10 @@ test_t8_forest_incomplete_t8_gtest_empty_global_tree_LDADD = $(t8_gtest_target_l
test_t8_forest_incomplete_t8_gtest_empty_global_tree_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_forest_incomplete_t8_gtest_empty_global_tree_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+test_t8_cmesh_t8_gtest_cmesh_tree_vertices_negative_volume_LDADD = $(t8_gtest_target_ld_add)
+test_t8_cmesh_t8_gtest_cmesh_tree_vertices_negative_volume_LDFLAGS = $(t8_gtest_target_ld_flags)
+test_t8_cmesh_t8_gtest_cmesh_tree_vertices_negative_volume_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+
test_t8_schemes_t8_gtest_default_LDADD = $(t8_gtest_target_ld_add)
test_t8_schemes_t8_gtest_default_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_schemes_t8_gtest_default_CPPFLAGS = $(t8_gtest_target_cpp_flags)
@@ -518,6 +537,14 @@ test_t8_schemes_t8_gtest_child_parent_face_LDADD = $(t8_gtest_target_ld_add)
test_t8_schemes_t8_gtest_child_parent_face_LDFLAGS = $(t8_gtest_target_ld_flags)
test_t8_schemes_t8_gtest_child_parent_face_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+test_t8_cmesh_generator_t8_gtest_cmesh_generator_test_LDADD = $(t8_gtest_target_ld_add)
+test_t8_cmesh_generator_t8_gtest_cmesh_generator_test_LDFLAGS = $(t8_gtest_target_ld_flags)
+test_t8_cmesh_generator_t8_gtest_cmesh_generator_test_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+
+test_t8_cmesh_t8_gtest_cmesh_copy_LDADD = $(t8_gtest_target_ld_add)
+test_t8_cmesh_t8_gtest_cmesh_copy_LDFLAGS = $(t8_gtest_target_ld_flags)
+test_t8_cmesh_t8_gtest_cmesh_copy_CPPFLAGS = $(t8_gtest_target_cpp_flags)
+
# If we did not configure t8code with MPI we need to build Googletest
# without MPI support.
if !T8_ENABLE_MPI
@@ -527,20 +554,19 @@ test_t8_schemes_t8_gtest_pyra_connectivity_CPPFLAGS += $(t8_gtest_target_mpi_cpp
test_t8_schemes_t8_gtest_face_neigh_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_linear_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_linear_axis_aligned_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
-test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_occ_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
+test_t8_geometry_t8_geometry_implementations_t8_gtest_geometry_cad_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_gtest_eclass_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_gtest_vec_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_gtest_mat_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_gtest_refcount_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
-test_t8_gtest_occ_linkage_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
+test_t8_gtest_cad_linkage_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_gtest_version_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_schemes_t8_gtest_init_linear_id_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_gtest_basics_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_schemes_t8_gtest_ancestor_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_cmesh_t8_gtest_hypercube_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
-test_t8_cmesh_t8_gtest_cmesh_copy_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_leafs_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_handling_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_schemes_t8_gtest_descendant_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
@@ -561,6 +587,7 @@ test_t8_gtest_vtk_linkage_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_data_t8_gtest_shmem_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_forest_t8_gtest_half_neighbors_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_forest_t8_gtest_find_owner_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
+test_t8_forest_t8_gtest_forest_face_normal_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_schemes_t8_gtest_face_descendant_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_geometry_t8_gtest_point_inside_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_forest_t8_gtest_user_data_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
@@ -574,8 +601,12 @@ test_t8_forest_incomplete_t8_gtest_recursive_CPPFLAGS += $(t8_gtest_target_mpi_c
test_t8_forest_incomplete_t8_gtest_iterate_replace_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_forest_incomplete_t8_gtest_empty_local_tree_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_forest_incomplete_t8_gtest_empty_global_tree_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
+test_t8_cmesh_t8_gtest_cmesh_tree_vertices_negative_volume_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_schemes_t8_gtest_default_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
test_t8_schemes_t8_gtest_child_parent_face_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
+test_t8_cmesh_generator_t8_gtest_cmesh_generator_test_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
+test_t8_cmesh_t8_gtest_cmesh_copy_CPPFLAGS += $(t8_gtest_target_mpi_cpp_flags)
+
endif
# Build Googletest library
diff --git a/test/t8_IO/t8_gtest_vtk_reader.cxx b/test/t8_IO/t8_gtest_vtk_reader.cxx
index 07ef84bc38..51c992e9e1 100644
--- a/test/t8_IO/t8_gtest_vtk_reader.cxx
+++ b/test/t8_IO/t8_gtest_vtk_reader.cxx
@@ -44,7 +44,9 @@ class vtk_reader: public testing::TestWithParam> {
SC_CHECK_MPI (mpiret);
mpiret = sc_MPI_Comm_rank (sc_MPI_COMM_WORLD, &mpirank);
SC_CHECK_MPI (mpiret);
- if (mpisize > T8_VTK_TEST_NUM_PROCS) {
+
+ /* `mpisize` must match with the number of files that are read in. */
+ if (mpisize != T8_VTK_TEST_NUM_PROCS) {
GTEST_SKIP ();
}
file = std::get<0> (GetParam ());
diff --git a/test/t8_cmesh/t8_gtest_cmesh_copy.cxx b/test/t8_cmesh/t8_gtest_cmesh_copy.cxx
index 11c54de28f..9c98806615 100644
--- a/test/t8_cmesh/t8_gtest_cmesh_copy.cxx
+++ b/test/t8_cmesh/t8_gtest_cmesh_copy.cxx
@@ -22,57 +22,64 @@
#include
#include
+#include
#include "t8_cmesh/t8_cmesh_trees.h"
#include "t8_cmesh/t8_cmesh_partition.h"
-#include
-#include
#include
-/* Test if a cmesh is committed properly and perform the face consistency check. */
+#include "test/t8_cmesh_generator/t8_cmesh_example_sets.hxx"
-class cmesh_copy_equality: public testing::TestWithParam {
+/* We create and commit a cmesh, then derive a new cmesh
+ * from it without any changes.
+ * We test whether the new and original cmesh are equal.
+ */
+
+/* Note: This test currently fails on many cmeshes and is thus deavtivated.
+ * See: https://github.com/DLR-AMR/t8code/issues/920
+ */
+
+class t8_cmesh_copy: public testing::TestWithParam {
protected:
void
SetUp () override
{
- cmesh_id = GetParam ();
-
- cmesh_original = t8_test_create_cmesh (cmesh_id);
- /* Set up the cmesh copy */
- t8_cmesh_init (&cmesh_copy);
- /* We need the original cmesh later, so we ref it */
- t8_cmesh_ref (cmesh_original);
- t8_cmesh_set_derive (cmesh_copy, cmesh_original);
- t8_cmesh_commit (cmesh_copy, sc_MPI_COMM_WORLD);
+ /* Skip test since cmesh copy is not yet working. See https://github.com/DLR-AMR/t8code/issues/920 */
+ GTEST_SKIP ();
+ cmesh_original = GetParam ()->cmesh_create ();
+
+ /* Initialized test cmesh that we derive in the test */
+ t8_cmesh_init (&cmesh);
}
+
void
TearDown () override
{
- t8_cmesh_unref (&cmesh_original);
- t8_cmesh_unref (&cmesh_copy);
+ /* Skip test since cmesh copy is not yet working. See https://github.com/DLR-AMR/t8code/issues/920 */
+ GTEST_SKIP ();
+ /* Unref both cmeshes */
+ t8_cmesh_unref (&cmesh);
}
+ t8_cmesh_t cmesh;
t8_cmesh_t cmesh_original;
- t8_cmesh_t cmesh_copy;
- int cmesh_id;
};
-/* Test wheater the original cmaeh and its copy are committed and face consistent. Test will fail, if one of these is false. */
-TEST_P (cmesh_copy_equality, check_cmeshes_and_their_trees)
+static void
+test_cmesh_committed (t8_cmesh_t cmesh)
{
-
- EXPECT_TRUE (t8_cmesh_is_committed (cmesh_original));
- EXPECT_TRUE (t8_cmesh_is_committed (cmesh_copy));
- EXPECT_TRUE (t8_cmesh_trees_is_face_consistent (cmesh_original, cmesh_original->trees));
- EXPECT_TRUE (t8_cmesh_trees_is_face_consistent (cmesh_copy, cmesh_copy->trees));
+ ASSERT_TRUE (t8_cmesh_is_committed (cmesh)) << "Cmesh commit failed.";
+ ASSERT_TRUE (t8_cmesh_trees_is_face_consistent (cmesh, cmesh->trees)) << "Cmesh face consistency failed.";
}
-/* Test the equality of the original and copied cmeshs*/
-TEST_P (cmesh_copy_equality, check_equality_of_copied_cmesh_with_original)
+TEST_P (t8_cmesh_copy, test_cmesh_copy)
{
+ t8_cmesh_set_derive (cmesh, cmesh_original);
+ t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD);
+
+ test_cmesh_committed (cmesh);
- EXPECT_TRUE (t8_cmesh_is_equal (cmesh_original, cmesh_copy));
+ EXPECT_TRUE (t8_cmesh_is_equal (cmesh, cmesh_original));
}
-/* Test all cmeshes over all different inputs we get through their id */
-INSTANTIATE_TEST_SUITE_P (t8_gtest_cmesh_copy, cmesh_copy_equality, AllCmeshs);
+/* Test all cmeshes over all different inputs*/
+INSTANTIATE_TEST_SUITE_P (t8_gtest_cmesh_copy, t8_cmesh_copy, AllCmeshsParam, pretty_print_base_example);
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 da2e1ec13e..c680949354 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
@@ -243,8 +243,8 @@ TEST (t8_cmesh_set_join_by_vertices, test_cmesh_set_join_by_vertices)
const double boundary_coords[24] = { 1, 0, 0, 4, 0, 0, 0, 6, 0, 5, 5, 0, -1, -2, 8, 9, 0, 10, 0, 8, 9, 10, 10, 10 };
t8_eclass_t eclass = T8_ECLASS_HEX;
- t8_geometry_c *geometry = new t8_geometry_linear (3);
- t8_cmesh_t cmesh = t8_cmesh_new_hypercube_pad (eclass, comm, boundary_coords, 2, 2, 2, geometry);
+ const int use_axis_aligned = 0;
+ t8_cmesh_t cmesh = t8_cmesh_new_hypercube_pad (eclass, comm, boundary_coords, 2, 2, 2, use_axis_aligned);
test_with_cmesh (cmesh);
t8_cmesh_destroy (&cmesh);
}
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
new file mode 100644
index 0000000000..af0e714bfd
--- /dev/null
+++ b/test/t8_cmesh/t8_gtest_cmesh_tree_vertices_negative_volume.cxx
@@ -0,0 +1,153 @@
+/*
+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
+
+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_gtest_cmesh_tree_vertices_negative_volume.cxx
+* Provide tests to check the functionality of the t8_cmesh_tree_vertices_negative_volume function
+* for every eclass.
+*/
+
+#include
+#include
+#include
+
+/**
+ * Given an eclass fill \a vertices_ids with the corner_ids of a cube [0,1]^3, such that
+ * the volume is positive
+ * \param[in] eclass The eclass to use
+ * \param[in, out] 8 ints on input, filled with the corner ids to use for i-th vertex of the element on output
+ */
+static void
+get_vertices_ids (const t8_eclass_t eclass, int vertices_ids[T8_ECLASS_MAX_CORNERS])
+{
+ /* For Hex, Quads and Lines we set the remaining vertices by
+ * not breaking at the end of the case.
+ * The same is done for Prisms and Triangles. */
+ switch (eclass) {
+ case T8_ECLASS_HEX:
+ vertices_ids[4] = 4;
+ vertices_ids[5] = 5;
+ vertices_ids[6] = 6;
+ vertices_ids[7] = 7;
+ case T8_ECLASS_QUAD:
+ vertices_ids[3] = 3;
+ vertices_ids[2] = 2;
+ case T8_ECLASS_LINE:
+ vertices_ids[1] = 1;
+ case T8_ECLASS_VERTEX:
+ vertices_ids[0] = 0;
+ break;
+ case T8_ECLASS_PRISM:
+ vertices_ids[3] = 4;
+ vertices_ids[4] = 5;
+ vertices_ids[5] = 7;
+ case T8_ECLASS_TRIANGLE:
+ vertices_ids[0] = 0;
+ vertices_ids[1] = 1;
+ vertices_ids[2] = 3;
+ break;
+ case T8_ECLASS_TET:
+ vertices_ids[0] = 0;
+ vertices_ids[1] = 1;
+ vertices_ids[2] = 5;
+ vertices_ids[3] = 7;
+ break;
+ case T8_ECLASS_PYRAMID:
+ vertices_ids[0] = 1;
+ vertices_ids[1] = 3;
+ vertices_ids[2] = 0;
+ vertices_ids[3] = 2;
+ vertices_ids[4] = 7;
+ break;
+ default:
+ break;
+ }
+}
+
+class tree_vertices_negative_volume: public testing::TestWithParam {
+ protected:
+ void
+ SetUp () override
+ {
+ eclass = GetParam ();
+ num_vertices = t8_eclass_num_vertices[eclass];
+ get_vertices_ids (eclass, vertices_ids);
+ }
+ void
+ TearDown () override
+ {
+ }
+ t8_eclass_t eclass;
+ int num_vertices;
+ int vertices_ids[T8_ECLASS_MAX_CORNERS];
+};
+
+/* Test if positive volume is detected correctly */
+TEST_P (tree_vertices_negative_volume, positive_volume)
+{
+ /* clang-format off */
+ const double vertices_coords[24] = {
+ 0, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1, 1
+ };
+ /* clang-format on */
+ double *elem_vertices = T8_ALLOC (double, 3 * num_vertices);
+ t8_cmesh_new_translate_vertices_to_attributes (vertices_ids, vertices_coords, elem_vertices, num_vertices);
+
+ EXPECT_FALSE (t8_cmesh_tree_vertices_negative_volume (eclass, elem_vertices, num_vertices));
+ T8_FREE (elem_vertices);
+}
+
+/* Test if negative volume is detected correctly */
+TEST_P (tree_vertices_negative_volume, negative_volume)
+{
+ /* clang-format off */
+ /* Same nodes as above, but inverted. All 3D elements will have negative volume*/
+ const double vertices_coords[24] = {
+ 0, 0, 1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1, 1,
+ 0, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0
+ };
+ /* clang-format on */
+ double *elem_vertices = T8_ALLOC (double, 3 * num_vertices);
+ t8_cmesh_new_translate_vertices_to_attributes (vertices_ids, vertices_coords, elem_vertices, num_vertices);
+ if (t8_eclass_to_dimension[eclass] <= 2) {
+ EXPECT_FALSE (t8_cmesh_tree_vertices_negative_volume (eclass, elem_vertices, num_vertices));
+ }
+ else {
+ EXPECT_TRUE (t8_cmesh_tree_vertices_negative_volume (eclass, elem_vertices, num_vertices));
+ }
+ T8_FREE (elem_vertices);
+}
+
+INSTANTIATE_TEST_SUITE_P (t8_gtest_cmesh_tree_vertices_negative_volume, tree_vertices_negative_volume,
+ testing::Range (T8_ECLASS_ZERO, T8_ECLASS_PYRAMID));
diff --git a/test/t8_cmesh_generator/t8_cmesh_example_sets.hxx b/test/t8_cmesh_generator/t8_cmesh_example_sets.hxx
new file mode 100644
index 0000000000..124ca3edc8
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_cmesh_example_sets.hxx
@@ -0,0 +1,65 @@
+/*
+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_GTEST_CMESH_COMM_CREATOR_HXX
+#define T8_GTEST_CMESH_COMM_CREATOR_HXX
+
+#include
+
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_prism_cake_param.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_from_class_param.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_bigmesh_param.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_comm.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_pad.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx"
+#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+#include "test/t8_cmesh_generator/t8_gtest_cmesh_sum_of_sets.hxx"
+
+T8_EXTERN_C_BEGIN ();
+
+/**
+ * lambda to pass to an INSTANTIATE_TEST_SUITE_P to print the current cmesh_example_base
+ *
+ */
+auto pretty_print_base_example = [] (const testing::TestParamInfo &info) {
+ std::string name;
+ info.param->param_to_string (name);
+ return name;
+};
+
+namespace cmesh_list
+{
+std::vector cart_prod_vec
+ = { new_from_class::cmesh_example, new_prism_cake::cmesh_example, new_bigmesh::cmesh_example,
+ new_cmesh_comm::cmesh_example, new_hypercube_pad::cmesh_example, new_hypercube_cmesh::cmesh_example,
+ new_hypercube_cmesh::cmesh_example_pyra };
+
+cmesh_sum_of_sets cmesh_sums (cart_prod_vec);
+
+} // namespace cmesh_list
+
+#define AllCmeshsParam \
+ ::testing::ValuesIn (cmesh_list::cmesh_sums.cmesh_examples.begin (), cmesh_list::cmesh_sums.cmesh_examples.end ())
+
+T8_EXTERN_C_END ();
+
+#endif /* T8_GTEST_CMESH_COMM_CREATOR_HXX */
\ No newline at end of file
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
new file mode 100644
index 0000000000..060933cc06
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_bigmesh_param.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_CMESH_NEW_BIGMESH_PARAM_HXX
+#define T8_CMESH_NEW_BIGMESH_PARAM_HXX
+
+#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx"
+#include "t8_cmesh/t8_cmesh_examples.h"
+#include
+
+namespace new_bigmesh
+{
+std::function bigmesh = t8_cmesh_new_bigmesh;
+
+std::string
+make_param_string (const t8_eclass_t eclass, const int num_trees, const sc_MPI_Comm comm)
+{
+ std::string delimiter = std::string ("_");
+ std::string params = delimiter + t8_eclass_to_string[eclass] + delimiter + std::to_string (num_trees) + delimiter
+ + cmesh_params::comm_to_string (comm);
+ return params;
+}
+
+std::function make_param_string_wrapper
+ = make_param_string;
+
+example_set *cmesh_example
+ = (example_set *) new cmesh_cartesian_product_params (
+ std::make_pair (cmesh_params::eclasses.begin (), cmesh_params::eclasses.end ()),
+ std::make_pair (cmesh_params::large_mesh.begin (), cmesh_params::large_mesh.end ()),
+ std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()), bigmesh, make_param_string_wrapper,
+ "t8_cmesh_new_bigmesh_");
+} // namespace new_bigmesh
+
+#endif /* T8_CMESH_NEW_BIGMESH_PARAM_HXX */
\ No newline at end of file
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
new file mode 100644
index 0000000000..01a20f709f
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_comm.hxx
@@ -0,0 +1,74 @@
+/*
+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_CMESH_NEW_COMM
+#define T8_CMESH_NEW_COMM
+
+#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx"
+#include
+
+namespace new_cmesh_comm
+{
+std::string
+make_param_string (const sc_MPI_Comm &comm)
+{
+ std::string delimiter = std::string ("_");
+ std::string params = delimiter + cmesh_params::comm_to_string (comm);
+ return params;
+}
+
+std::function print_function = make_param_string;
+
+std::vector> cmesh_functions = { t8_cmesh_new_periodic_tri,
+ t8_cmesh_new_periodic_hybrid,
+ t8_cmesh_new_periodic_line_more_trees,
+ t8_cmesh_new_line_zigzag,
+ t8_cmesh_new_prism_deformed,
+ t8_cmesh_new_pyramid_deformed,
+ t8_cmesh_new_prism_cake_funny_oriented,
+ t8_cmesh_new_prism_geometry,
+ t8_cmesh_new_tet_orientation_test,
+ t8_cmesh_new_hybrid_gate,
+ t8_cmesh_new_hybrid_gate_deformed,
+ t8_cmesh_new_full_hybrid };
+
+std::vector names = { "t8_cmesh_new_periodic_tri_",
+ "t8_cmesh_new_periodic_hybrid_",
+ "t8_cmesh_new_periodic_line_more_trees_",
+ "t8_cmesh_new_line_zigzag_",
+ "t8_cmesh_new_prism_deformed_",
+ "t8_cmesh_new_pyramid_deformed_",
+ "t8_cmesh_new_prism_cake_funny_oriented_",
+ "t8_cmesh_new_prism_geometry_",
+ "t8_cmesh_new_tet_orientation_test_",
+ "t8_cmesh_new_hybrid_gate_",
+ "t8_cmesh_new_hybrid_gate_deformed_",
+ "t8_cmesh_new_full_hybrid_" };
+
+example_set *cmesh_example
+ = (example_set *) new cmesh_cartesian_product_params (
+ std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()), cmesh_functions, print_function,
+ names);
+} // namespace new_cmesh_comm
+
+#endif /* T8_CMESH_NEW_COMM */
\ No newline at end of file
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
new file mode 100644
index 0000000000..4b03c07f1e
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_from_class_param.hxx
@@ -0,0 +1,56 @@
+/*
+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 "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx"
+#include
+#include
+
+#ifndef T8_CMESH_NEW_FROM_CLASS_PARAM
+#define T8_CMESH_NEW_FROM_CLASS_PARAM
+
+namespace new_from_class
+{
+
+std::string
+make_param_string (const t8_eclass_t &eclass, const sc_MPI_Comm &comm)
+{
+ std::string delimiter = std::string ("_");
+ std::string params
+ = delimiter + std::string (t8_eclass_to_string[eclass]) + delimiter + cmesh_params::comm_to_string (comm);
+ return params;
+}
+
+std::function print_function = make_param_string;
+
+std::function new_from_class_wrapper = t8_cmesh_new_from_class;
+
+example_set *cmesh_example
+ = (example_set *) new cmesh_cartesian_product_params (
+ std::make_pair (cmesh_params::eclasses.begin (), cmesh_params::eclasses.end ()),
+ std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()), new_from_class_wrapper,
+ print_function, "t8_cmesh_new_from_class_");
+
+} // namespace new_from_class
+
+#endif /* T8_CMESH_NEW_FROM_CLASS_PARAM */
\ No newline at end of file
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
new file mode 100644
index 0000000000..231cb05d6b
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_pad.hxx
@@ -0,0 +1,90 @@
+/*
+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_CMESH_NEW_HYPERCUBE_PAD
+#define T8_CMESH_NEW_HYPERCUBE_PAD
+
+#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx"
+#include
+
+namespace new_hypercube_pad
+{
+std::function
+ hyper_pad = t8_cmesh_new_hypercube_pad;
+
+std::string
+make_param_string (const t8_eclass_t eclass, sc_MPI_Comm comm, const double *boundary, t8_locidx_t polygons_x,
+ t8_locidx_t polygons_y, t8_locidx_t polygons_z, const int use_axis_aligned)
+{
+ std::string delimiter = std::string ("_");
+ std::string geometry = use_axis_aligned ? std::string ("AxisAligned") : std::string ("LinearGeom");
+
+ std::string params = delimiter + t8_eclass_to_string[eclass] + delimiter + cmesh_params::comm_to_string (comm)
+ + delimiter + std::string ("BoundsNotPrinted") + delimiter + std::to_string (polygons_x)
+ + delimiter + std::to_string (polygons_y) + delimiter + std::to_string (polygons_z) + delimiter
+ + geometry;
+
+ return params;
+}
+std::function
+ make_param_string_wrapper = make_param_string;
+
+inline bool
+rule (const t8_eclass_t eclass, sc_MPI_Comm comm, const double *boundary, t8_locidx_t polygons_x,
+ t8_locidx_t polygons_y, t8_locidx_t polygons_z, const int use_axis_aligned)
+{
+ const int dim = t8_eclass_to_dimension[eclass];
+ if (dim == 0 && (polygons_x > 1 || polygons_y > 1 || polygons_z > 1))
+ return false;
+ if (dim == 1 && (polygons_y > 1 || polygons_z > 1))
+ return false;
+ if (dim == 2 && polygons_z > 1)
+ return false;
+ if ((eclass != T8_ECLASS_HEX && use_axis_aligned) || (eclass != T8_ECLASS_QUAD && use_axis_aligned))
+ return false;
+ if (eclass == T8_ECLASS_PYRAMID)
+ return false;
+ return true;
+}
+
+std::function
+ rule_wrapper = rule;
+
+example_set *cmesh_example = (example_set *) new cmesh_cartesian_product_with_rules<
+ decltype (cmesh_params::all_eclasses.begin ()), decltype (cmesh_params::my_comms.begin ()),
+ decltype (cmesh_params::boundaries.begin ()), decltype (cmesh_params::elems_per_dim.begin ()),
+ decltype (cmesh_params::elems_per_dim.begin ()), decltype (cmesh_params::elems_per_dim.begin ()),
+ decltype (cmesh_params::use_axis_aligned.begin ())> (
+ std::make_pair (cmesh_params::eclasses.begin (), cmesh_params::eclasses.end ()),
+ std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()),
+ std::make_pair (cmesh_params::boundaries.begin (), cmesh_params::boundaries.end ()),
+ std::make_pair (cmesh_params::elems_per_dim.begin (), cmesh_params::elems_per_dim.end ()),
+ std::make_pair (cmesh_params::elems_per_dim.begin (), cmesh_params::elems_per_dim.end ()),
+ std::make_pair (cmesh_params::elems_per_dim.begin (), cmesh_params::elems_per_dim.end ()),
+ std::make_pair (cmesh_params::use_axis_aligned.begin (), cmesh_params::use_axis_aligned.end ()), hyper_pad,
+ make_param_string_wrapper, rule_wrapper, "t8_cmesh_new_hypercube_pad_");
+} // namespace new_hypercube_pad
+
+#endif /* T8_CMESH_NEW_HYPERCUBE_PAD */
\ No newline at end of file
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
new file mode 100644
index 0000000000..a7a6b94afe
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx
@@ -0,0 +1,80 @@
+/*
+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_CMESH_NEW_HYPERCUBE_PARAM_HXX
+#define T8_CMESH_NEW_HYPERCUBE_PARAM_HXX
+
+#include
+#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx"
+#include
+
+namespace new_hypercube_cmesh
+{
+std::string
+make_param_string (const t8_eclass_t eclass, const sc_MPI_Comm comm, const int do_bcast, const int do_partition,
+ const int periodic)
+{
+ std::string delimiter = std::string ("_");
+ std::string bcast = do_bcast ? std::string ("bcast") : std::string ("noBcast");
+ std::string partition = do_partition ? std::string ("partition") : std::string ("noPartition");
+ std::string periodic_string = periodic ? std::string ("periodic") : std::string ("noPeriodic");
+ std::string params
+ = delimiter + t8_eclass_to_string[eclass] + delimiter + bcast + delimiter + partition + delimiter + periodic_string;
+
+ return params;
+}
+
+std::function param_to_string
+ = make_param_string;
+
+std::vector periodic_eclasses = { T8_ECLASS_VERTEX, T8_ECLASS_LINE, T8_ECLASS_QUAD, T8_ECLASS_TRIANGLE,
+ T8_ECLASS_HEX, T8_ECLASS_TET, T8_ECLASS_PRISM };
+
+std::function cmesh_wrapper = t8_cmesh_new_hypercube;
+
+std::vector nonperiodic_eclasses = { T8_ECLASS_PYRAMID };
+
+example_set *cmesh_example = (example_set *) new cmesh_cartesian_product_params<
+ decltype (periodic_eclasses.begin ()), decltype (cmesh_params::my_comms.begin ()),
+ decltype (cmesh_params::do_bcast.begin ()), decltype (cmesh_params::partition.begin ()),
+ decltype (cmesh_params::periodic.begin ())> (
+ 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::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_");
+
+example_set *cmesh_example_pyra = (example_set *) new cmesh_cartesian_product_params<
+ decltype (periodic_eclasses.begin ()), decltype (cmesh_params::my_comms.begin ()),
+ decltype (cmesh_params::do_bcast.begin ()), decltype (cmesh_params::partition.begin ()),
+ decltype (cmesh_params::no_periodic.begin ())> (
+ 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::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
+
+#endif /* T8_CMESH_NEW_HYPERCUBE_PARAM_HXX */
\ No newline at end of file
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
new file mode 100644
index 0000000000..f4df7366ca
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_prism_cake_param.hxx
@@ -0,0 +1,52 @@
+/*
+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 "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx"
+#include
+
+#ifndef T8_CMESH_NEW_PRISM_CAKE_PARAM_HXX
+#define T8_CMESH_NEW_PRISM_CAKE_PARAM_HXX
+
+namespace new_prism_cake
+{
+std::function prism_cake = t8_cmesh_new_prism_cake;
+
+std::string
+make_param_string (const sc_MPI_Comm &comm, const int &num_prisms)
+{
+ std::string delimiter = std::string ("_");
+ std::string params = delimiter + cmesh_params::comm_to_string (comm) + delimiter + std::to_string (num_prisms);
+ return params;
+}
+
+std::function make_param_string_wrapper = make_param_string;
+
+example_set *cmesh_example
+ = (example_set *) new cmesh_cartesian_product_params (
+ std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()),
+ std::make_pair (cmesh_params::num_prisms.begin (), cmesh_params::num_prisms.end ()), prism_cake,
+ make_param_string_wrapper, "t8_cmesh_new_prism_cake_");
+} // namespace new_prism_cake
+
+#endif /* T8_CMESH_NEW_PRISM_CAKE_PARAM_HXX */
\ No newline at end of file
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
new file mode 100644
index 0000000000..51975a8fa8
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx
@@ -0,0 +1,88 @@
+/*
+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.
+*/
+
+/**
+ * File to store the parameters that are used for our parameterized cmesh-tests
+ */
+
+#ifndef T8_CMESH_PARAMS_HXX
+#define T8_CMESH_PARAMS_HXX
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace cmesh_params
+{
+std::string
+comm_to_string (const sc_MPI_Comm &comm)
+{
+ int mpi_ret;
+ sc_MPI_Comm_compare (comm, sc_MPI_COMM_WORLD, &mpi_ret);
+ if (mpi_ret == sc_MPI_SUCCESS) {
+ return std::string ("sc_MPI_COMM_WORLD");
+ }
+ return std::string ("No_String_for_this_communicator");
+}
+
+std::vector
+filled_vector (const size_t size, int start)
+{
+ std::vector tmp (size);
+ std::iota (tmp.begin (), tmp.end (), start);
+ return tmp;
+}
+
+const double cube_bounds[24] = { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1 };
+
+std::vector boundaries = { cube_bounds };
+
+std::vector use_axis_aligned = { 0, 1 };
+
+std::vector large_mesh = filled_vector (20, 500);
+
+std::vector elems_per_dim = filled_vector (5, 1);
+
+std::vector my_comms = { sc_MPI_COMM_WORLD };
+std::vector eclasses = { T8_ECLASS_VERTEX, T8_ECLASS_LINE, T8_ECLASS_QUAD, T8_ECLASS_TRIANGLE,
+ T8_ECLASS_HEX, T8_ECLASS_TET, T8_ECLASS_PRISM, T8_ECLASS_PYRAMID };
+
+std::vector all_eclasses
+ = { T8_ECLASS_ZERO, T8_ECLASS_VERTEX, T8_ECLASS_LINE, T8_ECLASS_QUAD, T8_ECLASS_TRIANGLE, T8_ECLASS_HEX,
+ T8_ECLASS_TET, T8_ECLASS_PRISM, T8_ECLASS_PYRAMID, T8_ECLASS_COUNT, T8_ECLASS_INVALID };
+
+std::vector do_bcast = { 0, 1 };
+std::vector partition = { 0, 1 };
+/* Currently a dummy vector for examples that have partition argument but not fully support it yet */
+std::vector no_partition = { 0 };
+
+std::vector periodic = { 0, 1 };
+/* Currently a dummy vector for examples that have periodic argument but not fully support it yet */
+std::vector no_periodic = { 0 };
+
+std::vector num_prisms = filled_vector (50, 3);
+} // namespace cmesh_params
+
+#endif /* T8_CMESH_PARAMS_HXX */
\ No newline at end of file
diff --git a/test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx b/test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx
new file mode 100644
index 0000000000..4c3dbe0e0d
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx
@@ -0,0 +1,285 @@
+/*
+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_GTEST_CMESH_CREATOR_BASE_HXX
+#define T8_GTEST_CMESH_CREATOR_BASE_HXX
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * A base class for cmesh examples.
+ *
+ * For pretty debug output a function to translate the parameters of the example to a string should be provided.
+ *
+ * The
+ *
+ */
+class cmesh_example_base {
+ public:
+ /**
+ * Construct a new base example. An example must have at least have a name.
+ *
+ * \param name
+ */
+ cmesh_example_base (std::string name): name (name) {};
+
+ /**
+ * A function to create a cmesh. The class should not own the cmesh.
+ *
+ * \return t8_cmesh_t
+ */
+ virtual t8_cmesh_t
+ cmesh_create () const
+ = 0;
+
+ /**
+ * Copy the name and the parameters of this example into a string
+ *
+ * \param out
+ */
+ virtual void
+ param_to_string (std::string& out) const
+ = 0;
+
+ std::string name;
+};
+
+/**
+ * Class to hold cmesh example created by function with parameters as input
+ *
+ * @tparam Args
+ */
+template
+class cmesh_example_with_parameter: cmesh_example_base {
+ public:
+ cmesh_example_with_parameter (std::function function, std::tuple parameter,
+ std::function parameter_to_string, std::string name)
+ : cmesh_example_base (name), cmesh_function (function), parameter (parameter),
+ parameter_to_string (parameter_to_string) {};
+
+ virtual t8_cmesh_t
+ cmesh_create () const
+ {
+ return std::apply (cmesh_function, parameter);
+ }
+
+ virtual void
+ param_to_string (std::string& out) const
+ {
+ out = name + std::apply (parameter_to_string, parameter);
+ }
+
+ std::function cmesh_function;
+ std::tuple parameter;
+ std::function parameter_to_string;
+};
+
+/**
+ * A base class to hold sets of examples that can be created in various ways.
+ *
+ */
+class example_set {
+ public:
+ /**
+ * Generate a cmesh according to a function
+ *
+ * \return t8_cmesh_t
+ */
+ std::vector example_all_combination;
+};
+
+/**
+ * A helper functions that creates a pair of begin and end iterators from a vector.
+ *
+ * \tparam Args The type of elements in the vector
+ * \param[in] vec A vector
+ * \return A pair of begin and end of the vector.
+ */
+template
+auto
+vector_to_iter_pair (const std::vector& vec)
+{
+ return std::make_pair (vec.begin (), vec.end ());
+}
+
+/**
+ * A helper function to recursively create the next tuple of parameters in a cartesion product way
+ *
+ * @tparam Args
+ * @tparam B
+ * \param begins A tuple of begin-iterators
+ * \param r A pair of iterators, used to create the next parameter in a tuple.
+ * \return true
+ * \return false
+ */
+template
+bool
+increment (const B& begins, std::pair& r)
+{
+ ++r.first;
+ if (r.first == r.second) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * A helper function to recursively create the next tuple of parameters in a cartesion product way
+ *
+ * @tparam T
+ * @tparam TT
+ * @tparam B
+ * \param begins A tuple of begin-iterators
+ * \param r A pair of iterators, where first will be increased
+ * \param rr Remaining iterators to create the tuple.
+ * \return true
+ * \return false
+ */
+template
+bool
+increment (const B& begins, std::pair& r, std::pair&... rr)
+{
+ ++r.first;
+ if (r.first == r.second) {
+ r.first = std::get::value - sizeof...(rr) - 1> (begins);
+ return increment (begins, rr...);
+ }
+
+ return false;
+}
+
+template
+inline bool
+no_rule (Args... params)
+{
+ return true;
+}
+
+/**
+ * Fill a vector with tuples, based on pairs of iterators. The iterators are used
+ * to create the tuples according to the cartesian product.
+ *
+ * @tparam OutputIterator
+ * @tparam Iter
+ * \param[in, out] out An OutputIterator that will be filled
+ * \param[in] rule A function that returns true if a parameter combination is permissible, false otherwise
+ * \param[in] ranges Pairs of ranges
+ */
+template
+void
+cartesian_product (OutputIterator out, std::function rule,
+ std::pair... ranges)
+{
+ const auto begins = std::make_tuple (ranges.first...);
+ if (rule (*ranges.first...)) {
+ out = { *ranges.first... };
+ }
+ while (!increment (begins, ranges...)) {
+ if (rule (*ranges.first...)) {
+ out = { *ranges.first... };
+ }
+ }
+}
+
+/**
+ * Variadic template class that creates \ref base_example based on the cartesian product
+ * of the input parameters.
+ *
+ * @tparam Iter
+ */
+template
+class cmesh_cartesian_product_params: example_set {
+ public:
+ cmesh_cartesian_product_params () {};
+
+ cmesh_cartesian_product_params (std::pair... ranges,
+ std::function cmesh_function,
+ std::function param_to_string,
+ std::string name)
+ {
+ std::function no_rule_wrapper = no_rule;
+ std::vector> cart_prod;
+ cartesian_product (std::back_inserter (cart_prod), no_rule_wrapper, ranges...);
+ for (int iparam_set = 0; (long unsigned int) iparam_set < cart_prod.size (); iparam_set++) {
+ std::tuple param = cart_prod[iparam_set];
+ cmesh_example_base* next_example
+ = (cmesh_example_base*) new cmesh_example_with_parameter (cmesh_function, param,
+ param_to_string, name);
+ example_all_combination.push_back (next_example);
+ }
+ }
+
+ cmesh_cartesian_product_params (std::pair... ranges,
+ std::vector> cmesh_functions,
+ std::function param_to_string,
+ std::vector names)
+ {
+ std::function no_rule_wrapper = no_rule;
+ std::vector> cart_prod;
+ cartesian_product (std::back_inserter (cart_prod), no_rule_wrapper, ranges...);
+ T8_ASSERT (cmesh_functions.size () == names.size ());
+ for (int ifunction = 0; (long unsigned int) ifunction < cmesh_functions.size (); ifunction++) {
+ for (int iparam_set = 0; (long unsigned int) iparam_set < cart_prod.size (); iparam_set++) {
+ std::tuple param = cart_prod[iparam_set];
+ cmesh_example_base* next_example
+ = (cmesh_example_base*) new cmesh_example_with_parameter (
+ cmesh_functions[ifunction], param, param_to_string, names[ifunction]);
+ example_all_combination.push_back (next_example);
+ }
+ }
+ }
+};
+
+/**
+ * Variadic template class that creates \ref base_example based on the cartesian product
+ * of the input parameters.
+ *
+ * @tparam Iter
+ */
+template
+class cmesh_cartesian_product_with_rules: example_set {
+ public:
+ cmesh_cartesian_product_with_rules () {};
+
+ cmesh_cartesian_product_with_rules (std::pair... ranges,
+ std::function cmesh_function,
+ std::function param_to_string,
+ std::function rule, std::string name)
+ {
+ std::vector> cart_prod;
+ cartesian_product (std::back_inserter (cart_prod), rule, ranges...);
+ for (int iparam_set = 0; (long unsigned int) iparam_set < cart_prod.size (); iparam_set++) {
+ std::tuple param = cart_prod[iparam_set];
+ cmesh_example_base* next_example
+ = (cmesh_example_base*) new cmesh_example_with_parameter (cmesh_function, param,
+ param_to_string, name);
+ example_all_combination.push_back (next_example);
+ }
+ }
+};
+
+#endif /* T8_GTEST_CMESH_CREATOR_BASE_HXX */
\ No newline at end of file
diff --git a/test/t8_cmesh_generator/t8_gtest_cmesh_generator_test.cxx b/test/t8_cmesh_generator/t8_gtest_cmesh_generator_test.cxx
new file mode 100644
index 0000000000..1a439f0f58
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_gtest_cmesh_generator_test.cxx
@@ -0,0 +1,68 @@
+/*
+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 "test/t8_cmesh_generator/t8_cmesh_example_sets.hxx"
+#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_bigmesh_param.hxx"
+#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+
+class t8_cmesh_iter: public testing::TestWithParam {
+ protected:
+ void
+ SetUp () override
+ {
+ cmesh_creator = GetParam ();
+ cmesh = cmesh_creator->cmesh_create ();
+ cmesh_creator->param_to_string (cmesh_param_string);
+ }
+
+ void
+ TearDown () override
+ {
+ /* Unref both cmeshes */
+ t8_cmesh_unref (&cmesh);
+ }
+ t8_cmesh_t cmesh;
+ cmesh_example_base *cmesh_creator;
+ std::string cmesh_param_string;
+};
+
+TEST_P (t8_cmesh_iter, cmesh_created)
+{
+ EXPECT_NE (cmesh, nullptr);
+}
+
+TEST_P (t8_cmesh_iter, print_string)
+{
+ EXPECT_FALSE (cmesh_param_string.empty ());
+}
+
+TEST (param_generator, check_num_parameters_combination)
+{
+ const size_t num_combs_generated = new_bigmesh::cmesh_example->example_all_combination.size ();
+ const size_t num_expected
+ = cmesh_params::large_mesh.size () * cmesh_params::my_comms.size () * cmesh_params::eclasses.size ();
+ EXPECT_EQ (num_combs_generated, num_expected);
+}
+
+INSTANTIATE_TEST_SUITE_P (t8_gtest_create_cmeshes, t8_cmesh_iter, AllCmeshsParam, pretty_print_base_example);
\ No newline at end of file
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
new file mode 100644
index 0000000000..d9ffc28675
--- /dev/null
+++ b/test/t8_cmesh_generator/t8_gtest_cmesh_sum_of_sets.hxx
@@ -0,0 +1,63 @@
+/*
+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_GTEST_cmesh_sum_of_sets_HXX
+#define T8_GTEST_cmesh_sum_of_sets_HXX
+
+#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
+
+T8_EXTERN_C_BEGIN ();
+
+/**
+ * A class that holds multiple ways to create a cmesh.
+ *
+ */
+class cmesh_sum_of_sets {
+ public:
+ cmesh_sum_of_sets () {};
+ /**
+ * Construct a new cmesh sum of sets object, that will generate cmeshes given by \ref cmesh_set
+ *
+ * \param[in] cmesh_set A vector of \ref parameter_cartesian_product
+ */
+ cmesh_sum_of_sets (std::vector cmesh_set)
+ {
+ for (size_t icreator = 0; icreator < cmesh_set.size (); icreator++) {
+ cmesh_examples.insert (cmesh_examples.end (), cmesh_set[icreator]->example_all_combination.begin (),
+ cmesh_set[icreator]->example_all_combination.end ());
+ }
+ }
+
+ /**
+ * Destroy the cmesh generator cxx object
+ *
+ */
+ ~cmesh_sum_of_sets ()
+ {
+ }
+
+ public:
+ std::vector cmesh_examples;
+};
+
+T8_EXTERN_C_END ();
+#endif /* T8_GTEST_cmesh_sum_of_sets_HXX */
\ No newline at end of file
diff --git a/test/t8_forest/t8_gtest_forest_commit.cxx b/test/t8_forest/t8_gtest_forest_commit.cxx
index cffb78305f..2ce79d23ea 100644
--- a/test/t8_forest/t8_gtest_forest_commit.cxx
+++ b/test/t8_forest/t8_gtest_forest_commit.cxx
@@ -134,7 +134,7 @@ TEST_P (forest_commit, test_forest_commit)
t8_forest_t forest_ada_bal_part;
t8_forest_t forest_abp_3part;
-#ifdef T8_ENABLE_DEBUG
+#ifdef T8_ENABLE_LESS_TESTS
int level_step = 2;
#else
int level_step = 3;
diff --git a/test/t8_forest/t8_gtest_forest_face_normal.cxx b/test/t8_forest/t8_gtest_forest_face_normal.cxx
new file mode 100644
index 0000000000..d97bfa99e3
--- /dev/null
+++ b/test/t8_forest/t8_gtest_forest_face_normal.cxx
@@ -0,0 +1,115 @@
+/*
+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
+
+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