From 54f48b6d0e12d28cc59c519041ace078eeedacf0 Mon Sep 17 00:00:00 2001 From: Schmitt Date: Mon, 20 Jul 2026 15:46:19 +0200 Subject: [PATCH 1/4] Added tutorial Step 2 and getter function get_num_global_elements to mesh.hxx. --- mesh_handle/mesh.hxx | 10 ++ tutorials/CMakeLists.txt | 1 + .../t8_mesh_step2_uniform_mesh.cxx | 148 ++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx diff --git a/mesh_handle/mesh.hxx b/mesh_handle/mesh.hxx index b08fba5e78..6dacfc2419 100644 --- a/mesh_handle/mesh.hxx +++ b/mesh_handle/mesh.hxx @@ -141,6 +141,16 @@ class mesh: public TMeshCompetencePack::template apply /** General t8code header, always include this. */ +#include /** General Mesh Header, always needed for mesh_handle code. */ +#include /** cmesh definition and basic interface. */ +#include /** Wrapper for basic Cmesh to mesh_handle conversions. */ +#include /** Used to export mesh to vtk files. */ +#include /** default refinement scheme. */ +#include + +/** Builds cmesh of 2 prisms that build up a unit cube. + * See step1 for a detailed description. + * \param [in] comm MPI Communicator to use. + * \return The coarse mesh. + */ +static t8_cmesh_t +t8_step2_build_prismcube_coarse_mesh (sc_MPI_Comm comm) +{ + t8_cmesh_t cmesh; + + /* Build a coarse mesh of 2 prisms that form a cube. */ + t8_cmesh_init (&cmesh); + t8_cmesh_new_hypercube (&cmesh, T8_ECLASS_PRISM, comm, 0, 0, 0); + t8_global_productionf (" [tutorial] Constructed coarse mesh with 2 prisms.\n"); + + return cmesh; +} + +/** Build a uniform mesh on a cmesh using the default refinement scheme. + * \param [in] comm MPI Communicator to use. + * \param [in] cmesh The coarse mesh to build the uniform mesh on. + * \param [in] level The initial uniform refinement level. + * \return A uniform mesh with the given refinement level that is + * partitioned across the processes in \a comm. + */ +static std::unique_ptr> +t8_step2_build_uniform_mesh (sc_MPI_Comm comm, t8_cmesh_t cmesh, int level) +{ + const t8_scheme *scheme = t8_scheme_new_default (); /** Default refinement scheme. */ + + /* Build the uniform mesh, it is automatically partitioned among the processes. */ + auto mesh = t8_mesh_handle::handle_new_uniform> ( + cmesh, scheme, level, comm, false); + + t8_global_productionf (" [tutorial] Constructed uniform mesh with %d elements per tree.\n", 1 << (3 * level)); + + return mesh; +} + +int +main (int argc, char **argv) +{ + int mpiret; + sc_MPI_Comm comm; + + /** File prefix for our vtk files. */ + const char *prefix = "t8_step2_uniform_mesh"; + /** Uniform refinement level of the mesh. */ + const int level = 3; + t8_locidx_t local_num_elements; + t8_gloidx_t global_num_elements; + + /** Initialize MPI. This has to happen before we initialize sc or t8code. */ + mpiret = sc_MPI_Init (&argc, &argv); + /** Error check the MPI return value. */ + SC_CHECK_MPI (mpiret); + + /** Initialize the sc library, has to happen before we initialize t8code. */ + sc_init (sc_MPI_COMM_WORLD, 1, 1, NULL, SC_LP_ESSENTIAL); + /** Initialize t8code with log level SC_LP_PRODUCTION. See sc.h for more info on the log levels. */ + t8_init (SC_LP_DEBUG); + + /** Print a message on the root process. */ + t8_global_productionf (" [tutorial] \n"); + t8_global_productionf (" [tutorial] Hello, this is the step2 example of t8code using the mesh handle.\n"); + t8_global_productionf (" [tutorial] In this example we build our first uniform mesh and output it to vtu files.\n"); + t8_global_productionf (" [tutorial] \n"); + + /** We will use MPI_COMM_WORLD as a communicator. */ + comm = sc_MPI_COMM_WORLD; + /** Create the cmesh. */ + t8_cmesh_t cmesh = t8_step2_build_prismcube_coarse_mesh (comm); + + /** Build the uniform mesh. */ + auto mesh = t8_step2_build_uniform_mesh (comm, cmesh, level); + /** Get the number of local elements. */ + local_num_elements = mesh->get_num_local_elements (); + /** Get the number of global elements. */ + global_num_elements = mesh->get_num_global_elements (); + + /** Print information on the mesh. */ + t8_global_productionf (" [tutorial] Created uniform mesh.\n"); + t8_global_productionf (" [tutorial] Refinement level:\t\t\t%i\n", level); + t8_global_productionf (" [tutorial] Local number of elements:\t\t%i\n", local_num_elements); + t8_global_productionf (" [tutorial] Global number of elements:\t%" T8_GLOIDX_FORMAT "\n", global_num_elements); + + /** Write mesh to vtu files. */ + t8_mesh_handle::write_mesh_to_vtk (*mesh, prefix); + t8_global_productionf (" [tutorial] Wrote mesh to vtu files:\t%s*\n", prefix); + + /** Destroy the mesh. */ + mesh.reset (); + t8_global_productionf (" [tutorial] Destroyed mesh.\n"); + + sc_finalize (); + + mpiret = sc_MPI_Finalize (); + SC_CHECK_MPI (mpiret); + + return 0; +} From 81f193d7b7823d7a3af624cb80a3e794d387924d Mon Sep 17 00:00:00 2001 From: Schmitt Date: Mon, 3 Aug 2026 14:02:50 +0200 Subject: [PATCH 2/4] Fixed several Spelling issues and Documentation. --- mesh_handle/constructor_wrappers.hxx | 3 +- .../t8_gtest_compare_handle_to_forest.cxx | 1 + tutorials/general/t8_step1_coarsemesh.cxx | 2 +- tutorials/general/t8_step2_uniform_forest.cxx | 4 +- .../t8_mesh_step2_uniform_mesh.cxx | 75 +++++++++---------- 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/mesh_handle/constructor_wrappers.hxx b/mesh_handle/constructor_wrappers.hxx index 28a0c09907..bd85e6977b 100644 --- a/mesh_handle/constructor_wrappers.hxx +++ b/mesh_handle/constructor_wrappers.hxx @@ -47,7 +47,8 @@ namespace t8_mesh_handle * \param [in] comm MPI communicator to use. * \param [in] do_face_ghost If true, a layer of ghost elements is created. * \tparam TMeshClass The mesh handle class. - * \return Unique pointer to a uniformly refined mesh handle with coarse mesh \a cmesh and refinement level \a level. + * \return Unique pointer to a uniformly refined mesh handle with coarse mesh \a cmesh and refinement level \a level, + * partitioned across the processes in \a comm. */ template std::unique_ptr diff --git a/test/mesh_handle/t8_gtest_compare_handle_to_forest.cxx b/test/mesh_handle/t8_gtest_compare_handle_to_forest.cxx index 1243f0bc3d..fe7287b0b6 100644 --- a/test/mesh_handle/t8_gtest_compare_handle_to_forest.cxx +++ b/test/mesh_handle/t8_gtest_compare_handle_to_forest.cxx @@ -50,6 +50,7 @@ TEST (t8_gtest_compare_handle_to_forest, compare_handle_to_forest) const t8_mesh_handle::mesh<> mesh = t8_mesh_handle::mesh<> (forest); EXPECT_EQ (mesh.get_num_local_elements (), t8_forest_get_local_num_leaf_elements (forest)); + EXPECT_EQ (mesh.get_num_global_elements (), t8_forest_get_global_num_leaf_elements (forest)); EXPECT_EQ (mesh.get_num_ghosts (), t8_forest_get_num_ghosts (forest)); EXPECT_EQ (mesh.get_dimension (), t8_forest_get_dimension (forest)); diff --git a/tutorials/general/t8_step1_coarsemesh.cxx b/tutorials/general/t8_step1_coarsemesh.cxx index 4cc9074d5f..5b88faa0ac 100644 --- a/tutorials/general/t8_step1_coarsemesh.cxx +++ b/tutorials/general/t8_step1_coarsemesh.cxx @@ -110,7 +110,7 @@ main (int argc, char **argv) /* Initialize the sc library, has to happen before we initialize t8code. */ sc_init (sc_MPI_COMM_WORLD, 1, 1, NULL, SC_LP_ESSENTIAL); /* Initialize t8code with log level SC_LP_PRODUCTION. See sc.h for more info on the log levels. */ - t8_init (SC_LP_DEBUG); + t8_init (SC_LP_PRODUCTION); /* Print a message on the root process. */ t8_global_productionf (" [step1] \n"); diff --git a/tutorials/general/t8_step2_uniform_forest.cxx b/tutorials/general/t8_step2_uniform_forest.cxx index 5e6f432a6d..3b37e17b12 100644 --- a/tutorials/general/t8_step2_uniform_forest.cxx +++ b/tutorials/general/t8_step2_uniform_forest.cxx @@ -33,7 +33,7 @@ * forest how elements of each shape (t8_eclass_t) are refined, what their neighbor * are etc. * The default scheme in t8_schemes/t8_default/t8_default.hxx provides an implementation for - * all element shapes that t8code supports (with pyramids currently under construction). + * all element shapes that t8code supports. * * How you can experiment here: * - Use Paraview to visualize the output files. @@ -138,7 +138,7 @@ main (int argc, char **argv) /* Initialize the sc library, has to happen before we initialize t8code. */ sc_init (sc_MPI_COMM_WORLD, 1, 1, NULL, SC_LP_ESSENTIAL); /* Initialize t8code with log level SC_LP_PRODUCTION. See sc.h for more info on the log levels. */ - t8_init (SC_LP_DEBUG); + t8_init (SC_LP_PRODUCTION); /* Print a message on the root process. */ t8_global_productionf (" [step2] \n"); diff --git a/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx b/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx index f9ea9c3fdb..34d2e73ffc 100644 --- a/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx +++ b/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx @@ -3,7 +3,7 @@ t8code is a C library to manage a collection (a forest) of multiple connected adaptive space-trees of general element types in parallel. - Copyright (C) 2015 the developers + Copyright (C) 2026 the developers t8code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ /** \file t8_mesh_step2_uniform_mesh.cxx * This is step 2 of the t8code mesh handle tutorials. - * Therefor, this is the same as general/t8_step2_uniform_forest.cxx but using the mesh handle interface instead of the forest + * Therefore, this is the same as general/t8_step2_uniform_forest.cxx but using the mesh handle interface instead of the forest * interface. * After we learned how to create a cmesh in step1, we will * now build our first partitioned mesh, get its local and global @@ -32,10 +32,10 @@ * uniform (every element has the same refinement level) and can then be adapted * later (see the following steps). * Together with the cmesh, we also need a refinement scheme. This scheme tells the - * mesh how elements of each shape (t8_eclass_t) are refined, what their neighbor + * mesh how elements of each shape (t8_eclass_t) are refined, what their neighbors * are etc. * The default scheme in t8_schemes/t8_default/t8_default.hxx provides an implementation for - * all element shapes that t8code supports (with pyramids currently under construction). + * all element shapes that t8code supports. */ #include /** General t8code header, always include this. */ #include /** General Mesh Header, always needed for mesh_handle code. */ @@ -43,7 +43,7 @@ #include /** Wrapper for basic Cmesh to mesh_handle conversions. */ #include /** Used to export mesh to vtk files. */ #include /** default refinement scheme. */ -#include +#include /** Builds cmesh of 2 prisms that build up a unit cube. * See step1 for a detailed description. @@ -70,16 +70,16 @@ t8_step2_build_prismcube_coarse_mesh (sc_MPI_Comm comm) * \return A uniform mesh with the given refinement level that is * partitioned across the processes in \a comm. */ -static std::unique_ptr> +template +static std::unique_ptr t8_step2_build_uniform_mesh (sc_MPI_Comm comm, t8_cmesh_t cmesh, int level) { const t8_scheme *scheme = t8_scheme_new_default (); /** Default refinement scheme. */ /* Build the uniform mesh, it is automatically partitioned among the processes. */ - auto mesh = t8_mesh_handle::handle_new_uniform> ( - cmesh, scheme, level, comm, false); + std::unique_ptr mesh = t8_mesh_handle::handle_new_uniform (cmesh, scheme, level, comm); - t8_global_productionf (" [tutorial] Constructed uniform mesh with %d elements per tree.\n", 1 << (3 * level)); + t8_global_productionf (" [t8_step2] Constructed uniform mesh with refinement level %d.\n", level); return mesh; } @@ -87,25 +87,20 @@ t8_step2_build_uniform_mesh (sc_MPI_Comm comm, t8_cmesh_t cmesh, int level) int main (int argc, char **argv) { - int mpiret; - sc_MPI_Comm comm; - /** File prefix for our vtk files. */ const char *prefix = "t8_step2_uniform_mesh"; /** Uniform refinement level of the mesh. */ const int level = 3; - t8_locidx_t local_num_elements; - t8_gloidx_t global_num_elements; /** Initialize MPI. This has to happen before we initialize sc or t8code. */ - mpiret = sc_MPI_Init (&argc, &argv); + int mpiret = sc_MPI_Init (&argc, &argv); /** Error check the MPI return value. */ SC_CHECK_MPI (mpiret); /** Initialize the sc library, has to happen before we initialize t8code. */ sc_init (sc_MPI_COMM_WORLD, 1, 1, NULL, SC_LP_ESSENTIAL); /** Initialize t8code with log level SC_LP_PRODUCTION. See sc.h for more info on the log levels. */ - t8_init (SC_LP_DEBUG); + t8_init (SC_LP_PRODUCTION); /** Print a message on the root process. */ t8_global_productionf (" [tutorial] \n"); @@ -114,30 +109,34 @@ main (int argc, char **argv) t8_global_productionf (" [tutorial] \n"); /** We will use MPI_COMM_WORLD as a communicator. */ - comm = sc_MPI_COMM_WORLD; + sc_MPI_Comm comm = sc_MPI_COMM_WORLD; + /** Create the cmesh. */ t8_cmesh_t cmesh = t8_step2_build_prismcube_coarse_mesh (comm); - - /** Build the uniform mesh. */ - auto mesh = t8_step2_build_uniform_mesh (comm, cmesh, level); - /** Get the number of local elements. */ - local_num_elements = mesh->get_num_local_elements (); - /** Get the number of global elements. */ - global_num_elements = mesh->get_num_global_elements (); - - /** Print information on the mesh. */ - t8_global_productionf (" [tutorial] Created uniform mesh.\n"); - t8_global_productionf (" [tutorial] Refinement level:\t\t\t%i\n", level); - t8_global_productionf (" [tutorial] Local number of elements:\t\t%i\n", local_num_elements); - t8_global_productionf (" [tutorial] Global number of elements:\t%" T8_GLOIDX_FORMAT "\n", global_num_elements); - - /** Write mesh to vtu files. */ - t8_mesh_handle::write_mesh_to_vtk (*mesh, prefix); - t8_global_productionf (" [tutorial] Wrote mesh to vtu files:\t%s*\n", prefix); - - /** Destroy the mesh. */ - mesh.reset (); - t8_global_productionf (" [tutorial] Destroyed mesh.\n"); + /** + * We will put the Mesh in a separate scope here, + * because it will destroy itself completely on its own when reaching the end of this scope. + */ + { + /** Build the uniform mesh. */ + auto mesh = t8_step2_build_uniform_mesh < t8_mesh_handle::mesh<> (comm, cmesh, level); + /** Get the number of local elements. */ + const t8_locidx_t local_num_elements = mesh->get_num_local_elements (); + /** Get the number of global elements. */ + const t8_gloidx_t global_num_elements = mesh->get_num_global_elements (); + + /** Print information on the mesh. */ + t8_global_productionf (" [tutorial] Created uniform mesh.\n"); + t8_global_productionf (" [tutorial] Refinement level:\t\t\t%i\n", level); + t8_global_productionf (" [tutorial] Local number of elements:\t\t%i\n", local_num_elements); + t8_global_productionf (" [tutorial] Global number of elements:\t%" T8_GLOIDX_FORMAT "\n", global_num_elements); + + /** Write mesh to vtu files. */ + t8_mesh_handle::write_mesh_to_vtk (*mesh, prefix); + t8_global_productionf (" [tutorial] Wrote mesh to vtu files:\t%s*\n", prefix); + + } /** End of Mesh scope. */ + t8_global_productionf (" [tutorial] Mesh scope ended.\n"); sc_finalize (); From 0a4455e499b9e89278bf076ed8f6bcb65c4a77d9 Mon Sep 17 00:00:00 2001 From: Schmitt Date: Mon, 3 Aug 2026 14:41:39 +0200 Subject: [PATCH 3/4] Changed print messages --- .../t8_mesh_step2_uniform_mesh.cxx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx b/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx index 34d2e73ffc..dca24c38c0 100644 --- a/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx +++ b/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx @@ -103,10 +103,10 @@ main (int argc, char **argv) t8_init (SC_LP_PRODUCTION); /** Print a message on the root process. */ - t8_global_productionf (" [tutorial] \n"); - t8_global_productionf (" [tutorial] Hello, this is the step2 example of t8code using the mesh handle.\n"); - t8_global_productionf (" [tutorial] In this example we build our first uniform mesh and output it to vtu files.\n"); - t8_global_productionf (" [tutorial] \n"); + t8_global_productionf (" [t8_step2] \n"); + t8_global_productionf (" [t8_step2] Hello, this is the step2 example of t8code using the mesh handle.\n"); + t8_global_productionf (" [t8_step2] In this example we build our first uniform mesh and output it to vtu files.\n"); + t8_global_productionf (" [t8_step2] \n"); /** We will use MPI_COMM_WORLD as a communicator. */ sc_MPI_Comm comm = sc_MPI_COMM_WORLD; @@ -126,17 +126,17 @@ main (int argc, char **argv) const t8_gloidx_t global_num_elements = mesh->get_num_global_elements (); /** Print information on the mesh. */ - t8_global_productionf (" [tutorial] Created uniform mesh.\n"); - t8_global_productionf (" [tutorial] Refinement level:\t\t\t%i\n", level); - t8_global_productionf (" [tutorial] Local number of elements:\t\t%i\n", local_num_elements); - t8_global_productionf (" [tutorial] Global number of elements:\t%" T8_GLOIDX_FORMAT "\n", global_num_elements); + t8_global_productionf (" [t8_step2] Created uniform mesh.\n"); + t8_global_productionf (" [t8_step2] Refinement level:\t\t\t%i\n", level); + t8_global_productionf (" [t8_step2] Local number of elements:\t\t%i\n", local_num_elements); + t8_global_productionf (" [t8_step2] Global number of elements:\t%" T8_GLOIDX_FORMAT "\n", global_num_elements); /** Write mesh to vtu files. */ t8_mesh_handle::write_mesh_to_vtk (*mesh, prefix); - t8_global_productionf (" [tutorial] Wrote mesh to vtu files:\t%s*\n", prefix); + t8_global_productionf (" [t8_step2] Wrote mesh to vtu files:\t%s*\n", prefix); } /** End of Mesh scope. */ - t8_global_productionf (" [tutorial] Mesh scope ended.\n"); + t8_global_productionf (" [t8_step2] Mesh scope ended.\n"); sc_finalize (); From 34b8c2aad49b37db3beea2d7096ee75935c51044 Mon Sep 17 00:00:00 2001 From: Schmitt Date: Tue, 4 Aug 2026 11:52:19 +0200 Subject: [PATCH 4/4] Fixed syntax error. --- tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx b/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx index dca24c38c0..cfccc0dcf4 100644 --- a/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx +++ b/tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx @@ -119,7 +119,7 @@ main (int argc, char **argv) */ { /** Build the uniform mesh. */ - auto mesh = t8_step2_build_uniform_mesh < t8_mesh_handle::mesh<> (comm, cmesh, level); + auto mesh = t8_step2_build_uniform_mesh> (comm, cmesh, level); /** Get the number of local elements. */ const t8_locidx_t local_num_elements = mesh->get_num_local_elements (); /** Get the number of global elements. */