Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion mesh_handle/constructor_wrappers.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <T8MeshType TMeshClass>
std::unique_ptr<TMeshClass>
Expand Down
10 changes: 10 additions & 0 deletions mesh_handle/mesh.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ class mesh: public TMeshCompetencePack::template apply<mesh<TElementCompetencePa
return t8_forest_get_local_num_leaf_elements (m_forest);
}

/**
* Getter for the number of global elements in the mesh.
* \return Number of global elements in the mesh.
*/
t8_gloidx_t
get_num_global_elements () const
{
return t8_forest_get_global_num_leaf_elements (m_forest);
}

Comment thread
Vyp3er marked this conversation as resolved.
/**
* Getter for the number of ghost elements.
* \return Number of ghost elements in the mesh.
Expand Down
1 change: 1 addition & 0 deletions test/mesh_handle/t8_gtest_compare_handle_to_forest.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
1 change: 1 addition & 0 deletions tutorials/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,5 @@ copy_tutorial_file (features/t8_features_curved_meshes_generate_cmesh_tri.geo)

if( T8CODE_BUILD_MESH_HANDLE )
add_mesh_handle_tutorial( NAME t8_mesh_element_data SOURCES mesh_handle/t8_mesh_element_data.cxx )
add_mesh_handle_tutorial( NAME t8_mesh_step2_uniform_mesh SOURCES mesh_handle/t8_mesh_step2_uniform_mesh.cxx )
endif()
2 changes: 1 addition & 1 deletion tutorials/general/t8_step1_coarsemesh.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions tutorials/general/t8_step2_uniform_forest.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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");
Expand Down
147 changes: 147 additions & 0 deletions tutorials/mesh_handle/t8_mesh_step2_uniform_mesh.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
This file is part of t8code.
t8code is a C library to manage a collection (a forest) of multiple
connected adaptive space-trees of general element types in parallel.

Copyright (C) 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
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_mesh_step2_uniform_mesh.cxx
* This is step 2 of the t8code mesh handle tutorials.
* 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
* element count, and output it into .vtu files.
*
* When we create a mesh from a coarse mesh using the mesh handle interface, the mesh will always be
* 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 neighbors
* are etc.
* The default scheme in t8_schemes/t8_default/t8_default.hxx provides an implementation for
* all element shapes that t8code supports.
*/
#include <t8.h> /** General t8code header, always include this. */
#include <mesh_handle/mesh.hxx> /** General Mesh Header, always needed for mesh_handle code. */
#include <t8_cmesh/t8_cmesh.h> /** cmesh definition and basic interface. */
#include <mesh_handle/constructor_wrappers.hxx> /** Wrapper for basic Cmesh to mesh_handle conversions. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include <mesh_handle/constructor_wrappers.hxx> /** Wrapper for basic Cmesh to mesh_handle conversions. */
#include <mesh_handle/constructor_wrappers.hxx> /** Wrapper for basic cmesh to mesh_handle conversions. */

#include <mesh_handle/mesh_io.hxx> /** Used to export mesh to vtk files. */
#include <t8_schemes/t8_default/t8_default.hxx> /** default refinement scheme. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include <t8_schemes/t8_default/t8_default.hxx> /** default refinement scheme. */
#include <t8_schemes/t8_default/t8_default.hxx> /** Default refinement scheme. */

#include <memory>

/** Builds cmesh of 2 prisms that build up a unit cube.
* See step1 for a detailed description.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* See step1 for a detailed description.
* See \ref tutorials/general/t8_step1_coarsemesh.cxx 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.
*/
Comment thread
Vyp3er marked this conversation as resolved.
template <typename MeshType>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, we start template parameters with T. I used TMeshClass throughout the code.
Please also add a doxygen doc for this. You could also use the concept t8_mesh_handle::T8MeshType here (and include the concepts header.). I think its maybe cool to learn about the concept here. (also add a comment about the concept then.)

static std::unique_ptr<MeshType>
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. */
std::unique_ptr<MeshType> mesh = t8_mesh_handle::handle_new_uniform<MeshType> (cmesh, scheme, level, comm);

t8_global_productionf (" [t8_step2] Constructed uniform mesh with refinement level %d.\n", level);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do like t8_step2 better but maybe mesh_step2 is even better? Then it is clear that we are not in the general folder? Sorry for the inconvenience. And you missed one in l. 61


return mesh;
}

int
main (int argc, char **argv)
{
/** File prefix for our vtk files. */
const char *prefix = "t8_step2_uniform_mesh";
/** Uniform refinement level of the mesh. */
const int level = 3;

/** Initialize MPI. This has to happen before we initialize sc or t8code. */
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_PRODUCTION);

/** Print a message on the root process. */
t8_global_productionf (" [t8_step2] \n");
t8_global_productionf (" [t8_step2] Hello, this is the step2 example of t8code using the mesh handle.\n");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
t8_global_productionf (" [t8_step2] Hello, this is the step2 example of t8code using the mesh handle.\n");
t8_global_productionf (" [t8_step2] Hello, this is step 2 of t8code's mesh handle tutorials.\n");

t8_global_productionf (" [t8_step2] In this example we build our first uniform mesh and output it to vtu files.\n");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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] In this tutorial 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;

/** Create the cmesh. */
t8_cmesh_t cmesh = t8_step2_build_prismcube_coarse_mesh (comm);
/**
* We will put the Mesh in a separate scope here,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* We will put the Mesh in a separate scope here,
* 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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* because it will destroy itself completely on its own when reaching the end of this scope.
* because it will be destroyed automatically at the end of this scope. This is only needed because SC_CHECK_MPI checks for leftover references. Otherwise, it would be destroyed at the end of the main function.

I think we need a line break here, sorry

*/
{
/** Build the uniform mesh. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would even be cleaner if we write using mesh_class= .... here and add the explanation:
The mesh class is templated so that further competences/features that are not needed by default can be added to it. This is explained in more detail in the further tutorials. In our case, the default mesh class is sufficient.

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 (" [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 (" [t8_step2] Wrote mesh to vtu files:\t%s*\n", prefix);

} /** End of Mesh scope. */
t8_global_productionf (" [t8_step2] Mesh scope ended.\n");

sc_finalize ();

mpiret = sc_MPI_Finalize ();
SC_CHECK_MPI (mpiret);

return 0;
}
Loading