Program Listing for File t8_scheme.hxx
↰ Return to documentation for file (src/t8_schemes/t8_scheme.hxx)
/*
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_SCHEME_HXX
#define T8_SCHEME_HXX
#include <variant>
#include <vector>
#include <t8_refcount.h>
#include <t8_eclass.h>
#include <t8_schemes/t8_default/t8_default.hxx>
#include <t8_schemes/t8_default/t8_default_vertex/t8_default_vertex.hxx>
#include <t8_schemes/t8_default/t8_default_line/t8_default_line.hxx>
#include <t8_schemes/t8_default/t8_default_quad/t8_default_quad.hxx>
#include <t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx>
#include <t8_schemes/t8_default/t8_default_tri/t8_default_tri.hxx>
#include <t8_schemes/t8_default/t8_default_tet/t8_default_tet.hxx>
#include <t8_schemes/t8_default/t8_default_prism/t8_default_prism.hxx>
#include <t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid.hxx>
#include <t8_schemes/t8_standalone/t8_standalone.hxx>
#include <t8_schemes/t8_standalone/t8_standalone_implementation.hxx>
#include <string>
#if T8_ENABLE_DEBUG
// Only needed for t8_debug_print_type
#include <typeinfo>
template <typename TType>
inline std::string &
t8_debug_print_type ()
{
static std::string type_name = typeid (TType).name ();
return type_name;
}
#endif // T8_ENABLE_DEBUG
class t8_scheme {
friend class t8_scheme_builder;
public:
t8_scheme ()
{
t8_refcount_init (&rc);
};
~t8_scheme ()
{
if (sc_refcount_is_active (&rc)) {
T8_ASSERT (t8_refcount_is_last (&rc));
t8_refcount_unref (&rc);
}
t8_debugf ("Deleted the scheme.\n");
};
/* clang-format off */
using scheme_var = std::variant<
/* Default schemes */
t8_default_scheme_vertex,
t8_default_scheme_line,
t8_default_scheme_quad,
t8_default_scheme_tri,
t8_default_scheme_hex,
t8_default_scheme_tet,
t8_default_scheme_prism,
t8_default_scheme_pyramid,
t8_standalone_scheme<T8_ECLASS_VERTEX>,
t8_standalone_scheme<T8_ECLASS_LINE>,
t8_standalone_scheme<T8_ECLASS_QUAD>,
t8_standalone_scheme<T8_ECLASS_HEX>
>;
/* clang-format on */
using scheme_container = std::vector<scheme_var>;
private:
scheme_container eclass_schemes;
mutable t8_refcount_t
rc;
public:
inline void
ref () const
{
t8_refcount_ref (&rc);
}
inline int
unref () const
{
const int remaining = rc.refcount - 1;
if (t8_refcount_unref (&rc)) {
t8_debugf ("Deleting the scheme.\n");
delete this;
}
return remaining;
}
inline size_t
get_num_eclass_schemes () const
{
return eclass_schemes.size ();
}
template <class TEclassScheme>
inline bool
check_eclass_scheme_type (const t8_eclass_t tree_class) const
{
return std::holds_alternative<TEclassScheme> (eclass_schemes[tree_class]);
}
inline t8_eclass_t
get_eclass_scheme_eclass (const t8_eclass_t tree_class) const
{
return std::visit ([&] (auto &&scheme) { return scheme.get_eclass (); }, eclass_schemes[tree_class]);
}
inline size_t
get_eclass_scheme_dimension (const t8_eclass_t tree_class) const
{
return std::visit ([&] (auto &&scheme) { return scheme.get_dimension (); }, eclass_schemes[tree_class]);
}
inline size_t
get_element_size (const t8_eclass_t tree_class) const
{
return std::visit ([&] (auto &&scheme) { return scheme.get_element_size (); }, eclass_schemes[tree_class]);
};
inline bool
refines_irregular (const t8_eclass_t tree_class) const
{
return std::visit ([&] (auto &&scheme) { return scheme.refines_irregular (); }, eclass_schemes[tree_class]);
};
inline int
get_maxlevel (const t8_eclass_t tree_class) const
{
return std::visit ([&] (auto &&scheme) { return scheme.get_maxlevel (); }, eclass_schemes[tree_class]);
};
inline int
element_get_level (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_level (element); }, eclass_schemes[tree_class]);
};
inline void
element_copy (const t8_eclass_t tree_class, const t8_element_t *source, t8_element_t *dest) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_copy (source, dest); }, eclass_schemes[tree_class]);
};
inline int
element_compare (const t8_eclass_t tree_class, const t8_element_t *elem1, const t8_element_t *elem2) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_compare (elem1, elem2); },
eclass_schemes[tree_class]);
};
inline bool
element_is_equal (const t8_eclass_t tree_class, const t8_element_t *elem1, const t8_element_t *elem2) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_is_equal (elem1, elem2); },
eclass_schemes[tree_class]);
};
inline bool
element_is_refinable (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_is_refinable (element); },
eclass_schemes[tree_class]);
};
inline void
element_get_parent (const t8_eclass_t tree_class, const t8_element_t *element, t8_element_t *parent) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_parent (element, parent); },
eclass_schemes[tree_class]);
};
inline int
element_get_num_siblings (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_num_siblings (element); },
eclass_schemes[tree_class]);
};
inline void
element_get_sibling (const t8_eclass_t tree_class, const t8_element_t *element, const int sibid,
t8_element_t *sibling) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_sibling (element, sibid, sibling); },
eclass_schemes[tree_class]);
};
inline int
element_get_num_corners (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_num_corners (element); },
eclass_schemes[tree_class]);
};
inline int
element_get_num_faces (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_num_faces (element); },
eclass_schemes[tree_class]);
};
inline int
element_get_max_num_faces (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_max_num_faces (element); },
eclass_schemes[tree_class]);
};
inline int
element_get_num_children (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_num_children (element); },
eclass_schemes[tree_class]);
};
inline int
get_max_num_children (const t8_eclass_t tree_class) const
{
return std::visit ([&] (auto &&scheme) { return scheme.get_max_num_children (); }, eclass_schemes[tree_class]);
};
inline int
element_get_num_face_children (const t8_eclass_t tree_class, const t8_element_t *element, const int face) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_num_face_children (element, face); },
eclass_schemes[tree_class]);
};
inline int
element_get_face_corner (const t8_eclass_t tree_class, const t8_element_t *element, const int face,
const int corner) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_face_corner (element, face, corner); },
eclass_schemes[tree_class]);
};
inline int
element_get_corner_face (const t8_eclass_t tree_class, const t8_element_t *element, const int corner,
const int face) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_corner_face (element, corner, face); },
eclass_schemes[tree_class]);
};
inline void
element_get_child (const t8_eclass_t tree_class, const t8_element_t *element, const int childid,
t8_element_t *child) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_child (element, childid, child); },
eclass_schemes[tree_class]);
};
inline void
element_get_children (const t8_eclass_t tree_class, const t8_element_t *element, const int length,
t8_element_t *c[]) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_children (element, length, c); },
eclass_schemes[tree_class]);
};
inline int
element_get_child_id (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_child_id (element); },
eclass_schemes[tree_class]);
};
inline int
element_get_ancestor_id (const t8_eclass_t tree_class, const t8_element_t *element, const int level) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_ancestor_id (element, level); },
eclass_schemes[tree_class]);
};
inline bool
elements_are_family (const t8_eclass_t tree_class, t8_element_t *const *fam) const
{
return std::visit ([&] (auto &&scheme) { return scheme.elements_are_family (fam); }, eclass_schemes[tree_class]);
};
inline void
element_get_nca (const t8_eclass_t tree_class, const t8_element_t *elem1, const t8_element_t *elem2,
t8_element_t *const nca) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_nca (elem1, elem2, nca); },
eclass_schemes[tree_class]);
};
inline t8_element_shape_t
element_get_face_shape (const t8_eclass_t tree_class, const t8_element_t *element, const int face) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_face_shape (element, face); },
eclass_schemes[tree_class]);
};
inline void
element_get_children_at_face (const t8_eclass_t tree_class, const t8_element_t *element, const int face,
t8_element_t *children[], int num_children, int *child_indices) const
{
return std::visit (
[&] (auto &&scheme) {
return scheme.element_get_children_at_face (element, face, children, num_children, child_indices);
},
eclass_schemes[tree_class]);
};
inline int
element_face_get_child_face (const t8_eclass_t tree_class, const t8_element_t *element, const int face,
const int face_child) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_face_get_child_face (element, face, face_child); },
eclass_schemes[tree_class]);
};
inline int
element_face_get_parent_face (const t8_eclass_t tree_class, const t8_element_t *element, const int face) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_face_get_parent_face (element, face); },
eclass_schemes[tree_class]);
};
inline int
element_get_tree_face (const t8_eclass_t tree_class, const t8_element_t *element, const int face) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_tree_face (element, face); },
eclass_schemes[tree_class]);
};
inline void
element_transform_face (const t8_eclass_t tree_class, const t8_element_t *elem1, t8_element_t *elem2,
const int orientation, const int sign, const int is_smaller_face) const
{
return std::visit (
[&] (auto &&scheme) { return scheme.element_transform_face (elem1, elem2, orientation, sign, is_smaller_face); },
eclass_schemes[tree_class]);
};
inline int
element_extrude_face (const t8_eclass_t tree_class, const t8_element_t *face, t8_element_t *element,
const int root_face) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_extrude_face (face, element, root_face, this); },
eclass_schemes[tree_class]);
};
inline void
element_get_boundary_face (const t8_eclass_t tree_class, const t8_element_t *element, const int face,
t8_element_t *boundary) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_boundary_face (element, face, boundary, this); },
eclass_schemes[tree_class]);
};
inline void
element_get_first_descendant_face (const t8_eclass_t tree_class, const t8_element_t *element, const int face,
t8_element_t *first_desc, const int level) const
{
return std::visit (
[&] (auto &&scheme) { return scheme.element_get_first_descendant_face (element, face, first_desc, level); },
eclass_schemes[tree_class]);
};
inline void
element_get_last_descendant_face (const t8_eclass_t tree_class, const t8_element_t *element, const int face,
t8_element_t *last_desc, const int level) const
{
return std::visit (
[&] (auto &&scheme) { return scheme.element_get_last_descendant_face (element, face, last_desc, level); },
eclass_schemes[tree_class]);
};
inline bool
element_is_root_boundary (const t8_eclass_t tree_class, const t8_element_t *element, const int face) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_is_root_boundary (element, face); },
eclass_schemes[tree_class]);
};
inline int
element_get_face_neighbor_inside (const t8_eclass_t tree_class, const t8_element_t *element, t8_element_t *neigh,
const int face, int *neigh_face) const
{
return std::visit (
[&] (auto &&scheme) { return scheme.element_get_face_neighbor_inside (element, neigh, face, neigh_face); },
eclass_schemes[tree_class]);
};
inline t8_element_shape_t
element_get_shape (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_shape (element); }, eclass_schemes[tree_class]);
};
inline void
element_set_linear_id (const t8_eclass_t tree_class, t8_element_t *element, const int level,
const t8_linearidx_t id) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_set_linear_id (element, level, id); },
eclass_schemes[tree_class]);
};
inline t8_linearidx_t
element_get_linear_id (const t8_eclass_t tree_class, const t8_element_t *element, const int level) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_linear_id (element, level); },
eclass_schemes[tree_class]);
};
inline void
element_get_first_descendant (const t8_eclass_t tree_class, const t8_element_t *element, t8_element_t *desc,
const int level) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_first_descendant (element, desc, level); },
eclass_schemes[tree_class]);
};
inline void
element_get_last_descendant (const t8_eclass_t tree_class, const t8_element_t *element, t8_element_t *desc,
const int level) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_get_last_descendant (element, desc, level); },
eclass_schemes[tree_class]);
};
inline void
element_construct_successor (const t8_eclass_t tree_class, const t8_element_t *element, t8_element_t *successor) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_construct_successor (element, successor); },
eclass_schemes[tree_class]);
};
inline void
element_get_vertex_reference_coords (const t8_eclass_t tree_class, const t8_element_t *element, const int vertex,
double coords[]) const
{
return std::visit (
[&] (auto &&scheme) { return scheme.element_get_vertex_reference_coords (element, vertex, coords); },
eclass_schemes[tree_class]);
};
inline void
element_get_reference_coords (const t8_eclass_t tree_class, const t8_element_t *element, const double *ref_coords,
const size_t num_coords, double *out_coords) const
{
return std::visit (
[&] (auto &&scheme) { return scheme.element_get_reference_coords (element, ref_coords, num_coords, out_coords); },
eclass_schemes[tree_class]);
};
inline t8_gloidx_t
element_count_leaves (const t8_eclass_t tree_class, const t8_element_t *t, const int level) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_count_leaves (t, level); },
eclass_schemes[tree_class]);
};
inline t8_gloidx_t
count_leaves_from_root (const t8_eclass_t tree_class, const int level) const
{
return std::visit ([&] (auto &&scheme) { return scheme.count_leaves_from_root (level); },
eclass_schemes[tree_class]);
};
#if T8_ENABLE_DEBUG
inline int
element_is_valid (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_is_valid (element); }, eclass_schemes[tree_class]);
};
inline void
element_debug_print (const t8_eclass_t tree_class, const t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_debug_print (element); },
eclass_schemes[tree_class]);
};
inline void
element_to_string (const t8_eclass_t tree_class, const t8_element_t *element, char *debug_string,
const int string_size) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_to_string (element, debug_string, string_size); },
eclass_schemes[tree_class]);
};
#endif
inline void
element_new (const t8_eclass_t tree_class, const int length, t8_element_t **elements) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_new (length, elements); },
eclass_schemes[tree_class]);
};
inline void
element_init (const t8_eclass_t tree_class, const int length, t8_element_t *elements) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_init (length, elements); },
eclass_schemes[tree_class]);
};
inline void
element_deinit (const t8_eclass_t tree_class, const int length, t8_element_t *elements) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_deinit (length, elements); },
eclass_schemes[tree_class]);
};
inline void
element_destroy (const t8_eclass_t tree_class, const int length, t8_element_t **elements) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_destroy (length, elements); },
eclass_schemes[tree_class]);
};
inline void
set_to_root (const t8_eclass_t tree_class, t8_element_t *element) const
{
return std::visit ([&] (auto &&scheme) { return scheme.set_to_root (element); }, eclass_schemes[tree_class]);
};
inline void
element_MPI_Pack (const t8_eclass_t tree_class, t8_element_t **const elements, const unsigned int count,
void *send_buffer, int buffer_size, int *position, sc_MPI_Comm comm) const
{
return std::visit (
[&] (auto &&scheme) {
return scheme.element_MPI_Pack (elements, count, send_buffer, buffer_size, position, comm);
},
eclass_schemes[tree_class]);
};
inline void
element_MPI_Pack_size (const t8_eclass_t tree_class, const unsigned int count, sc_MPI_Comm comm, int *pack_size) const
{
return std::visit ([&] (auto &&scheme) { return scheme.element_MPI_Pack_size (count, comm, pack_size); },
eclass_schemes[tree_class]);
};
inline void
element_MPI_Unpack (t8_eclass_t tree_class, void *recvbuf, const int buffer_size, int *position,
t8_element_t **elements, const unsigned int count, sc_MPI_Comm comm) const
{
return std::visit (
[&] (auto &&scheme) { return scheme.element_MPI_Unpack (recvbuf, buffer_size, position, elements, count, comm); },
eclass_schemes[tree_class]);
};
};
#endif /* !T8_SCHEME_HXX */