diff --git a/src/Makefile.am b/src/Makefile.am index 1720cb17dd..f65f11eb29 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,7 @@ defaulthexincludedir = $(schemesdefaultincludedir)/t8_default_hex defaulttetincludedir = $(schemesdefaultincludedir)/t8_default_tet defaultprismincludedir = $(schemesdefaultincludedir)/t8_default_prism defaultpyramidincludedir = $(schemesdefaultincludedir)/t8_default_pyramid +schemessubelementsincludedir = $(includedir)/t8_schemes/t8_subelements libt8_generated_headers = src/t8_config.h libt8_installed_headers = \ @@ -55,7 +56,8 @@ libt8_installed_headers_forest = \ src/t8_forest/t8_forest_adapt.h \ src/t8_forest/t8_forest_vtk.h \ src/t8_forest/t8_forest_to_vtkUnstructured.hxx \ - src/t8_forest/t8_forest_iterate.h src/t8_forest/t8_forest_partition.h + src/t8_forest/t8_forest_iterate.h src/t8_forest/t8_forest_partition.h \ + src/t8_forest/t8_forest_subpatch.hxx libt8_installed_headers_geometry = \ src/t8_geometry/t8_geometry.h \ src/t8_geometry/t8_geometry_handler.hxx \ @@ -92,6 +94,9 @@ libt8_installed_headers_default_hex = libt8_installed_headers_default_tet = libt8_installed_headers_default_prism = libt8_installed_headers_default_pyramid = +libt8_installed_headers_schemes_subelements = \ + src/t8_schemes/t8_subelements/t8_subelements_cxx.hxx \ + src/t8_schemes/t8_subelements/t8_subelements.hxx libt8_internal_headers = \ src/t8_cmesh/t8_cmesh_trees.h src/t8_cmesh/t8_cmesh_partition.h \ src/t8_cmesh/t8_cmesh_copy.h \ @@ -139,6 +144,7 @@ libt8_compiled_sources = \ src/t8_forest/t8_forest_partition.cxx src/t8_forest/t8_forest_cxx.cxx \ src/t8_forest/t8_forest_private.c src/t8_forest/t8_forest_vtk.cxx \ src/t8_forest/t8_forest_ghost.cxx src/t8_forest/t8_forest_iterate.cxx \ + src/t8_forest/t8_forest_subpatch.cxx \ src/t8_version.c \ src/t8_vtk.c src/t8_forest/t8_forest_balance.cxx \ src/t8_forest/t8_forest_netcdf.cxx \ @@ -147,7 +153,8 @@ libt8_compiled_sources = \ src/t8_vtk/t8_vtk_polydata.cxx \ src/t8_vtk/t8_vtk_unstructured.cxx \ src/t8_vtk/t8_vtk_parallel.cxx \ - src/t8_vtk/t8_vtk_reader.cxx + src/t8_vtk/t8_vtk_reader.cxx \ + src/t8_schemes/t8_subelements/t8_subelements_cxx.cxx # this variable is used for headers that are not publicly installed @@ -188,5 +195,6 @@ dist_defaulthexinclude_HEADERS = $(libt8_installed_headers_default_hex) dist_defaulttetinclude_HEADERS = $(libt8_installed_headers_default_tet) dist_defaultprisminclude_HEADERS = $(libt8_installed_headers_default_prism) dist_defaultpyramidinclude_HEADERS = $(libt8_installed_headers_default_pyramid) +dist_schemessubelementsinclude_HEADERS = $(libt8_installed_headers_schemes_subelements) AM_CPPFLAGS += -I@top_srcdir@/src @T8_SC_CPPFLAGS@ @T8_P4EST_CPPFLAGS@ diff --git a/src/t8_schemes/t8_subelements/t8_subelements_cxx.hxx b/src/t8_schemes/t8_subelements/t8_subelements_cxx.hxx new file mode 100644 index 0000000000..6efa2fbb86 --- /dev/null +++ b/src/t8_schemes/t8_subelements/t8_subelements_cxx.hxx @@ -0,0 +1,848 @@ +/* + 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_SUBELEMENT_CXX_HXX +#define T8_SUBELEMENT_CXX_HXX + +#include +#include +#include +#include + +typedef struct +{ + t8_element_t *elem; + /* stores transition cell information (default for non-subelements is 0 and for subelements it is != 0 - is therefore used as a is_subelement check) + what type of subelement is stored here? Removing hanging nodes, subpatches, which parent cell type? */ + int subelement_type; // TODO: enum? + /* For subelements number of type, for subpatches dimension (default for non-subelements is 0) */ //TODO: make pair out of cell_type and transition_type? + int transition_type; + /* stores subelement information (default for non-subelements is 0) */ + int subelement_id; +} t8_element_with_subelements; + +struct t8_subelement_scheme_c: public t8_eclass_scheme_c +{ + public: + t8_eclass_scheme_c *scheme; + /** The table for a particular implementation of an element class. */ + + /** Constructor. */ + t8_subelement_scheme_c (t8_eclass_scheme_c *scheme); + + ~t8_subelement_scheme_c (); + + /** Returns true, if there is one element in the tree, that does not refine into 2^dim children. + * Returns false otherwise. + * \return non-zero if there is one element in the tree that does not refine into 2^dim children. + */ + virtual int + t8_element_refines_irregular (void) const; + + /** Return the maximum allowed level for any element of a given class. + * \return The maximum allowed level for elements of class \b ts. + */ + virtual int + t8_element_maxlevel (void) const; + + /** Return the level of a particular element. + * \param [in] elem The element whose level should be returned. + * \return The level of \b elem. + */ + virtual int + t8_element_level (const t8_element_t *elem) const; + + /** Copy all entries of \b source to \b dest. \b dest must be an existing + * element. No memory is allocated by this function. + * \param [in] source The element whose entries will be copied to \b dest. + * \param [in,out] dest This element's entries will be overwrite with the + * entries of \b source. + * \note \a source and \a dest may point to the same element. + */ + virtual void + t8_element_copy (const t8_element_t *source, t8_element_t *dest) const; + + /** Compare two elements. + * \param [in] elem1 The first element. + * \param [in] elem2 The second element. + * \return negative if elem1 < elem2, zero if elem1 equals elem2 + * and positive if elem1 > elem2. + * If elem2 is a copy of elem1 then the elements are equal. + */ + virtual int + t8_element_compare (const t8_element_t *elem1, const t8_element_t *elem2) const; + + /** Check if two elements are equal. + * \param [in] ts Implementation of a class scheme. + * \param [in] elem1 The first element. + * \param [in] elem2 The second element. + * \return 1 if the elements are equal, 0 if they are not equal + */ + virtual int + t8_element_equal (const t8_element_t *elem1, const t8_element_t *elem2) const; + + /** Compute the parent of a given element \b elem and store it in \b parent. + * \b parent needs to be an existing element. No memory is allocated by this function. + * \b elem and \b parent can point to the same element, then the entries of + * \b elem are overwritten by the ones of its parent. + * \param [in] elem The element whose parent will be computed. + * \param [in,out] parent This element's entries will be overwritten by those + * of \b elem's parent. + * The storage for this element must exist + * and match the element class of the parent. + * For a pyramid, for example, it may be either a + * tetrahedron or a pyramid depending on \b elem's childid. + */ + virtual void + t8_element_parent (const t8_element_t *elem, t8_element_t *parent) const; + + /** Compute the number of siblings of an element. That is the number of + * Children of its parent. + * \param [in] elem The element. + * \return The number of siblings of \a element. + * Note that this number is >= 1, since we count the element itself as a sibling. + */ + virtual int + t8_element_num_siblings (const t8_element_t *elem) const; + + /** Compute a specific sibling of a given element \b elem and store it in \b sibling. + * \b sibling needs to be an existing element. No memory is allocated by this function. + * \b elem and \b sibling can point to the same element, then the entries of + * \b elem are overwritten by the ones of its sibid-th sibling. + * \param [in] elem The element whose sibling will be computed. + * \param [in] sibid The id of the sibling computed. + * \param [in,out] sibling This element's entries will be overwritten by those + * of \b elem's sibid-th sibling. + * The storage for this element must exist + * and match the element class of the sibling. + */ + virtual void + t8_element_sibling (const t8_element_t *elem, int sibid, t8_element_t *sibling) const; + + /** Compute the number of corners of a given element. + * \param [in] elem The element. + * \return The number of corners of \a elem. + */ + virtual int + t8_element_num_corners (const t8_element_t *elem) const; + + /** Compute the number of faces of a given element. + * \param [in] elem The element. + * \return The number of faces of \a elem. + */ + virtual int + t8_element_num_faces (const t8_element_t *elem) const; + + /** Compute the maximum number of faces of a given element and all of its + * descendants. + * \param [in] elem The element. + * \return The maximum number of faces of \a elem and its descendants. + */ + virtual int + t8_element_max_num_faces (const t8_element_t *elem) const; + + /** Return the number of children of an element when it is refined. + * \param [in] elem The element whose number of children is returned. + * \return The number of children of \a elem if it is to be refined. + */ + virtual int + t8_element_num_children (const t8_element_t *elem) const; + + /** Return the number of children of an element's face when the element is refined. + * \param [in] elem The element whose face is considered. + * \param [in] face A face of \a elem. + * \return The number of children of \a face if \a elem is to be refined. + */ + virtual int + t8_element_num_face_children (const t8_element_t *elem, int face) const; + + /** Return the corner number of an element's face corner. + * Example quad: 2 x --- x 3 + * | | + * | | face 1 + * 0 x --- x 1 + * Thus for face = 1 the output is: corner=0 : 1, corner=1: 3 + * + * \param [in] element The element. + * \param [in] face A face index for \a element. + * \param [in] corner A corner index for the face 0 <= \a corner < num_face_corners. + * \return The corner number of the \a corner-th vertex of \a face. + * + * The order in which the corners must be given is determined by the eclass of \a element: + * LINE/QUAD/TRIANGLE: No specific order. + * HEX : In Z-order of the face starting with the lowest corner number. + * TET : Starting with the lowest corner number counterclockwise as seen from + * 'outside' of the element. + */ + virtual int + t8_element_get_face_corner (const t8_element_t *element, int face, int corner) const; + + /** Return the face numbers of the faces sharing an element's corner. + * Example quad: 2 x --- x 3 + * | | + * | | face 1 + * 0 x --- x 1 + * face 2 + * Thus for corner = 1 the output is: face=0 : 2, face=1: 1 + * \param [in] element The element. + * \param [in] corner A corner index for the face. + * \param [in] face A face index for \a corner. + * \return The face number of the \a face-th face at \a corner. + */ + virtual int + t8_element_get_corner_face (const t8_element_t *element, int corner, int face) const; + + /** Construct the child element of a given number. + * \param [in] elem This must be a valid element, bigger than maxlevel. + * \param [in] childid The number of the child to construct. + * \param [in,out] child The storage for this element must exist + * and match the element class of the child. + * For a pyramid, for example, it may be either a + * tetrahedron or a pyramid depending on \a childid. + * This can be checked by \a t8_element_child_eclass. + * On output, a valid element. + * It is valid to call this function with elem = child. + * \see t8_element_child_eclass + */ + virtual void + t8_element_child (const t8_element_t *elem, int childid, t8_element_t *child) const; + + /** Construct all children of a given element. + * \param [in] elem This must be a valid element, bigger than maxlevel. + * \param [in] length The length of the output array \a c must match + * the number of children. + * \param [in,out] c The storage for these \a length elements must exist + * and match the element class in the children's ordering. + * On output, all children are valid. + * It is valid to call this function with elem = c[0]. + * \see t8_element_num_children + * \see t8_element_child_eclass + */ + virtual void + t8_element_children (const t8_element_t *elem, int length, t8_element_t *c[]) const; + + /** Compute the child id of an element. + * \param [in] elem This must be a valid element. + * \return The child id of elem. + */ + virtual int + t8_element_child_id (const t8_element_t *elem) const; + + /** Compute the ancestor id of an element, that is the child id + * at a given level. + * \param [in] elem This must be a valid element. + * \param [in] level A refinement level. Must satisfy \a level < elem.level + * \return The child_id of \a elem in regard to its \a level ancestor. + */ + virtual int + t8_element_ancestor_id (const t8_element_t *elem, int level) const; + + /** Query whether a given set of elements is a family or not. + * \param [in] fam An array of as many elements as an element of class + * \b ts has siblings. + * \return Zero if \b fam is not a family, nonzero if it is. + * \note level 0 elements do not form a family. + */ + virtual int + t8_element_is_family (t8_element_t *const *fam) const; + + /** Compute the nearest common ancestor of two elements. That is, + * the element with highest level that still has both given elements as + * descendants. + * \param [in] elem1 The first of the two input elements. + * \param [in] elem2 The second of the two input elements. + * \param [in,out] nca The storage for this element must exist + * and match the element class of the child. + * On output the unique nearest common ancestor of + * \b elem1 and \b elem2. + */ + virtual void + t8_element_nca (const t8_element_t *elem1, const t8_element_t *elem2, t8_element_t *nca) const; + + /** Compute the shape of the face of an element. + * \param [in] elem The element. + * \param [in] face A face of \a elem. + * \return The element shape of the face. + * I.e. T8_ECLASS_LINE for quads, T8_ECLASS_TRIANGLE for tets + * and depending on the face number either T8_ECLASS_QUAD or + * T8_ECLASS_TRIANGLE for prisms. + */ + virtual t8_element_shape_t + t8_element_face_shape (const t8_element_t *elem, int face) const; + + /** Given an element and a face of the element, compute all children of + * the element that touch the face. + * \param [in] elem The element. + * \param [in] face A face of \a elem. + * \param [in,out] children Allocated elements, in which the children of \a elem + * that share a face with \a face are stored. + * They will be stored in order of their linear id. + * \param [in] num_children The number of elements in \a children. Must match + * the number of children that touch \a face. + * \ref t8_element_num_face_children + * \param [in,out] child_indices If not NULL, an array of num_children integers must be given, + * on output its i-th entry is the child_id of the i-th face_child. + * It is valid to call this function with elem = children[0]. + */ + virtual void + t8_element_children_at_face (const t8_element_t *elem, int face, t8_element_t *children[], int num_children, + int *child_indices) const; + + /** Given a face of an element and a child number of a child of that face, return the face number + * of the child of the element that matches the child face. + * \verbatim + x ---- x x x x ---- x + | | | | | | | <-- f + | | | x | x--x + | | | | | + x ---- x x x ---- x + elem face face_child Returns the face number f + \endverbatim + + * \param [in] elem The element. + * \param [in] face Then number of the face. + * \param [in] face_child A number 0 <= \a face_child < num_face_children, + * specifying a child of \a elem that shares a face with \a face. + * These children are counted in linear order. This coincides with + * the order of children from a call to \ref t8_element_children_at_face. + * \return The face number of the face of a child of \a elem + * that coincides with \a face_child. + */ + virtual int + t8_element_face_child_face (const t8_element_t *elem, int face, int face_child) const; + + /** Given a face of an element return the face number + * of the parent of the element that matches the element's face. Or return -1 if + * no face of the parent matches the face. + + * \param [in] elem The element. + * \param [in] face Then number of the face. + * \return If \a face of \a elem is also a face of \a elem's parent, + * the face number of this face. Otherwise -1. + * \note For the root element this function always returns \a face. + */ + virtual int + t8_element_face_parent_face (const t8_element_t *elem, int face) const; + + /** Given an element and a face of this element. If the face lies on the + * tree boundary, return the face number of the tree face. + * If not the return value is arbitrary. + * You can call \ref t8_element_is_root_boundary to query whether the face is + * at the tree boundary. + * \param [in] elem The element. + * \param [in] face The index of a face of \a elem. + * \return The index of the tree face that \a face is a subface of, if + * \a face is on a tree boundary. + * Any arbitrary integer if \a is not at a tree boundary. + * \warning The return value may look like a valid face of the tree even if + * the element does not lie on the root boundary. + */ + virtual int + t8_element_tree_face (const t8_element_t *elem, int face) const; + + /** Suppose we have two trees that share a common face f. + * Given an element e that is a subface of f in one of the trees + * and given the orientation of the tree connection, construct the face + * element of the respective tree neighbor that logically coincides with e + * but lies in the coordinate system of the neighbor tree. + * \param [in] elem1 The face element. + * \param [in,out] elem2 On return the face element \a elem1 with respective + * to the coordinate system of the other tree. + * \param [in] orientation The orientation of the tree-tree connection. + * \see t8_cmesh_set_join + * \param [in] sign Depending on the topological orientation of the two tree faces, + * either 0 (both faces have opposite orientation) + * or 1 (both faces have the same top. orientattion). + * \ref t8_eclass_face_orientation + * \param [in] is_smaller_face Flag to declare whether \a elem1 belongs to + * the smaller face. A face f of tree T is smaller than + * f' of T' if either the eclass of T is smaller or if + * the classes are equal and f