Skip to content
Open
Show file tree
Hide file tree
Changes from 9 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
1 change: 1 addition & 0 deletions doc/author_schmitt.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
I place my contributions to t8code under the FreeBSD license. Vincent Schmitt (vinz@vincent-schmitt.de)
Comment thread
lenaploetzke marked this conversation as resolved.
39 changes: 39 additions & 0 deletions mesh_handle/element.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,45 @@ class element: public TCompetences<element<TMeshClass, TCompetences...>>... {
return m_is_ghost_element;
}

// get_reference_coordinates
Comment thread
Vyp3er marked this conversation as resolved.
Outdated
/** Function to convert points in reference space of an element to points of the
Comment thread
Vyp3er marked this conversation as resolved.
Outdated
* reference space of the tree.
* \param [in] ref_coords Pointer to the reference coordinates of the element.
* \param [in] num_coords Number of reference coordinates to convert.
* \param [out] tree_ref_coords Pointer to the reference coordinates of the tree.
*/
void
get_reference_coordinates (const double* ref_coords, std::size_t num_coords, double* tree_ref_coords) const
Comment thread
Vyp3er marked this conversation as resolved.
Outdated
{
t8_forest_get_scheme (m_mesh->m_forest)
->element_get_reference_coords (get_tree_class (), m_element, ref_coords, num_coords, tree_ref_coords);
}

// element_is_equal
/** Check if two elements are equal.
Comment thread
Vyp3er marked this conversation as resolved.
* \param [in] elem1 The first element.
* \param [in] elem2 The second element.
* \return true if the elements are equal, false if they are not equal.
*/
bool
is_equal (const SelfType& elem1, const SelfType& elem2) const
{
return t8_forest_get_scheme (m_mesh->m_forest)
->element_is_equal (get_tree_class (), elem1.get_forest_element (), elem2.get_forest_element ());
}

//t8_forest_leaf_face_orientation
/** Compute the orientation of a face of an element with respect to its neighbor.
* \param [in] face The index of the face for which the orientation should be computed.
* \return The orientation of the face with respect to its neighbor. Returns 0 if the face has no neighbor.
*/
Comment thread
Vyp3er marked this conversation as resolved.
Outdated
int
get_face_orientation (int face) const

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.

Very cool function, could you maybe use this one in dg_competences.hxx?

{
return t8_forest_leaf_face_orientation (m_mesh->m_forest, m_tree_id, t8_forest_get_scheme (m_mesh->m_forest),
m_element, face);
}

private:
// --- Private member variables. ---
TMeshClass* m_mesh; /**< Pointer to the mesh the element is defined for. */
Expand Down
8 changes: 8 additions & 0 deletions src/t8_forest/t8_forest.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1578,6 +1578,14 @@ t8_forest_element_half_face_neighbors (t8_forest_t forest, t8_locidx_t ltreeid,
return neighbor_tree;
}

/** Compute the orientation of a leaf face with respect to its neighbor tree.
* \param forest The forest to which the leaf belongs.
* \param ltreeid The local tree id of the leaf.
* \param scheme The scheme of the forest.
* \param leaf The leaf element.
* \param face The face of the leaf element.
* \return The orientation of the leaf face with respect to its neighbor tree. Returns 0 if the leaf face is not a boundary face.
*/
Comment thread
Vyp3er marked this conversation as resolved.
Outdated
int
t8_forest_leaf_face_orientation (t8_forest_t forest, const t8_locidx_t ltreeid, const t8_scheme *scheme,
const t8_element_t *leaf, int face)
Expand Down
10 changes: 10 additions & 0 deletions test/mesh_handle/t8_gtest_compare_handle_to_forest.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ TEST (t8_gtest_compare_handle_to_forest, compare_handle_to_forest)
// --- Compare elements. ---
EXPECT_EQ (mesh_iterator->get_local_tree_id (), itree);
EXPECT_EQ (mesh_iterator->get_local_element_id (), ielem);
EXPECT_EQ (mesh_iterator->is_equal (*mesh_iterator, *mesh_iterator),
Comment thread
Vyp3er marked this conversation as resolved.
Outdated
Comment thread
Vyp3er marked this conversation as resolved.
Outdated
scheme->element_is_equal (tree_class, elem, elem));

t8_3D_vec ref = { 0.2, 0.3, 1 };
t8_3D_vec a, b;
mesh_iterator->get_reference_coordinates (ref.data (), 1, a.data ());
scheme->element_get_reference_coords (tree_class, elem, ref.data (), 1, b.data ());
EXPECT_EQ (a, b);
// --- Compare functionality. ---
EXPECT_EQ (mesh_iterator->get_level (), scheme->element_get_level (tree_class, elem));
EXPECT_EQ (mesh_iterator->get_num_faces (), scheme->element_get_num_faces (tree_class, elem));
Expand Down Expand Up @@ -94,6 +102,8 @@ TEST (t8_gtest_compare_handle_to_forest, compare_handle_to_forest)
EXPECT_EQ (mesh_iterator->face_vertex_to_element_vertex (iface, ivertex),
scheme->element_get_face_corner (tree_class, elem, iface, ivertex));
}
EXPECT_EQ (mesh_iterator->get_face_orientation (iface),
t8_forest_leaf_face_orientation (forest, itree, scheme, elem, iface));
}
// --- Evolve mesh iterator. ---
mesh_iterator++;
Expand Down
9 changes: 9 additions & 0 deletions tutorials/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,12 @@ 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 )
endif()

if( T8CODE_BUILD_MESH_HANDLE )
add_mesh_handle_tutorial( NAME t8_mesh_step3_adapt_forest SOURCES mesh_handle/t8_mesh_step3_adapt_forest.cxx )
endif()

if( T8CODE_BUILD_MESH_HANDLE )
add_mesh_handle_tutorial( NAME t8_mesh_step4_partition_balance_ghost SOURCES mesh_handle/t8_mesh_step4_partition_balance_ghost.cxx )
endif()

138 changes: 138 additions & 0 deletions tutorials/mesh_handle/t8_mesh_step3_adapt_forest.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
This file is part of t8code.
t8code is a C library to manage a collection (a forest) of multiple
connected adaptive space-trees of general element types in parallel.

Copyright (C) 2015 the developers

t8code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

t8code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with t8code; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/** \file t8_mesh_step3_adapt_forest.cxx
* This is the same as general/t8_step3_adapt_forest.cxx but using the mesh handle interface instead of the forest
* interface.
*/

#include <t8.h>
#include <mesh_handle/mesh.hxx>
#include <mesh_handle/competence_pack.hxx>
#include <mesh_handle/constructor_wrappers.hxx>
#include <mesh_handle/mesh_io.hxx>
#include <mesh_handle/concepts.hxx>
#include <t8_types/t8_vec.hxx>
#include <memory>
#include <span>

/* The data that determines the adaptation characteristics of our algorithm.
* In this example we want to adapt in a spherical shape around a given point. */
struct adapt_data
{
std::array<double, 3> midpoint; /**< midpoint of our sphere. */
double refine_radius; /**< We refine inside this radius of our sphere.*/
double coarsen_radius; /**< We coarsen outside this radius of our sphere. */
};

/** The adaption callback function. This will refine elements inside of a given sphere and coarsen the elements
* outside of a given sphere.
* \tparam TMeshClass The mesh handle class.
* \param [in] mesh The mesh that should be adapted.
* \param [in] elements One element or a family of elements to consider for adaptation.
* \param [in] adapt_data The user data to be used during the adaptation process.
* \returns 1 if the first entry in \a elements should be refined,
* -1 if the family of elements should be coarsened,
* 0 else.
*/
template <t8_mesh_handle::T8MeshType TMeshClass>
int
adapt_callback ([[maybe_unused]] const TMeshClass &mesh, std::span<const typename TMeshClass::element_class> elements,
const adapt_data &adapt_data)
{
auto element_centroid = elements[0].get_centroid ();
double dist = t8_dist<t8_3D_vec, t8_3D_vec> (element_centroid, adapt_data.midpoint);
if (dist < adapt_data.refine_radius) {
return 1; // refine
} //first check if there is a family, and only if yes check if we should coarsen.
else if ((elements.size () > 1) && (dist > adapt_data.coarsen_radius)) {
return -1; // coarsen
}
return 0; // do nothing
}

/** Build our adapted mesh by transferring the adaption parameters and adapting once with our adapt_callback function.
* \tparam TMeshClass The mesh handle class.
* \param sc_MPI_Comm The MPI Communicator.
* \param level The initial uniform refinement level.
* \returns Unique pointer to the adapted mesh.
*/
template <t8_mesh_handle::T8MeshType TMeshClass>
std::unique_ptr<TMeshClass>
build_mesh (sc_MPI_Comm comm, int level)
{
/*Generate a hybrid hypercube, made out of cubes, prisms etc. */
auto mesh = t8_mesh_handle::handle_hypercube_hybrid_uniform_default<TMeshClass> (level, comm);
/*Defining the adaption parameters. */
struct adapt_data adapt_params = { { 0.5, 0.5, 1.0 }, 0.2, 0.4 };
mesh->set_balance ();
mesh->set_partition ();
/*Adapting once with our adapt_callback function. */
mesh->set_adapt (
TMeshClass::template mesh_adapt_callback_wrapper<adapt_data> (adapt_callback<TMeshClass>, adapt_params));
mesh->set_ghost ();
mesh->commit ();
return mesh;
}

/** Entry point of the program. */
int
main (int argc, char **argv)
{
/*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);
/* We will use MPI_COMM_WORLD as a communicator. */
sc_MPI_Comm comm = sc_MPI_COMM_WORLD;

/* Print a starting message. */
t8_global_productionf (" [tutorial] \n");
t8_global_productionf (" [tutorial] Hello, this is the mesh adaptation example of t8code using the mesh handle.\n");
t8_global_productionf (" [tutorial] In this example we will adapt a mesh in a spherical shape around a given point "
"and write the adapted mesh to a vtu file.\n");
t8_global_productionf (" [tutorial] \n");

using mesh_type = t8_mesh_handle::mesh<>;

t8_global_productionf (" [tutorial] \n");
t8_global_productionf (" [tutorial] Creating an adapted mesh.\n");
t8_global_productionf (" [tutorial] \n");
/* The initial uniform refinement level. */
int uniform_level = 3;
/* Building the Mesh*/
auto mesh = build_mesh<mesh_type> (comm, uniform_level);
/* Write the mesh to a vtu file. */
t8_global_productionf (" [tutorial] \n");
t8_global_productionf (" [tutorial] Writing adapted mesh to vtu file: adapted_mesh.vtu\n");
t8_global_productionf (" [tutorial] \n");
t8_mesh_handle::write_mesh_to_vtk (*mesh, "adapted_mesh.vtu");

sc_finalize ();
mpiret = sc_MPI_Finalize ();
SC_CHECK_MPI (mpiret);
return 0;
}
Loading
Loading