From 9b30f8b9fcbc80967a4d0ecc424263a4eb7c4f98 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 28 Feb 2025 11:33:34 +0100 Subject: [PATCH 01/37] add lookup tables --- .../t8_standalone/t8_standalone_elements.hxx | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx index e7caf5f45e..3b4e1f1cfe 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx @@ -39,6 +39,78 @@ constexpr uint8_t T8_ELEMENT_MAX_NUM_FACECHILDREN[T8_ECLASS_COUNT] = { 0, 1, 2, constexpr uint8_t T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_COUNT] = { 0, 0, 0, 1, 0, 3, 1, 2 }; +/**PARENT CHILD BIJECTION*/ +template +constexpr int8_t t8_element_type_Iloc_to_childtype[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_CHILDREN[eclass_T]]; +template +constexpr int8_t t8_element_type_Iloc_to_childcubeid[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_CHILDREN[eclass_T]]; +template +constexpr int8_t t8_element_type_cubeid_to_parenttype[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [1 << T8_ELEMENT_DIM[eclass_T]]; +template +constexpr int8_t t8_element_type_cubeid_to_Iloc[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]][1 << T8_ELEMENT_DIM[eclass_T]]; + +/**TYPE EQUATIONS*/ +template +constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[eclass_T]][2]; + +/**VERTEX*/ +template +constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]][T8_ELEMENT_NUM_CORNERS[eclass_T]] + [T8_ELEMENT_DIM[eclass_T]]; + +/**FACE*/ +template +constexpr int8_t t8_sele_lut_face_internal[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]][T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_face_to_typebit[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_face_to_sign[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]][T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_face_to_facenormal_dim[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_face_to_neighface[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_cubeid_face_to_parentface[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [1 << T8_ELEMENT_DIM[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_face_to_is_1_boundary[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_face_to_last_facechilds_cubeid[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_face_facechildid_to_childid[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]] + [T8_ELEMENT_MAX_NUM_FACECHILDREN[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_childid_face_to_childface[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_CHILDREN[eclass_T]] + [T8_ELEMENT_MAX_NUM_FACECHILDREN[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_face_to_tree_face[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr int8_t t8_sele_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[eclass_T]][T8_ELEMENT_DIM[eclass_T]]; +template +constexpr int8_t t8_sele_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[eclass_T]][T8_ELEMENT_NUM_EQUATIONS[eclass_T]]; +template +constexpr int8_t t8_sele_lut_type_rootface_to_face[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] + [T8_ELEMENT_NUM_FACES[eclass_T]]; +template +constexpr t8_eclass_t t8_sele_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[eclass_T]]; + +// #include "t8_sele_lut_triangle_cxx.hxx" +// #include "t8_sele_lut_prism_cxx.hxx" +// #include "t8_sele_lut_pyra_cxx.hxx" +// #include "t8_sele_lut_tet_cxx.hxx" + typedef int32_t t8_element_coord; typedef uint8_t t8_element_level; typedef uint8_t t8_cube_id; @@ -56,6 +128,8 @@ struct t8_standalone_element t8_element_coords coords; /** The refinement level of the element relative to the root at level 0. */ t8_element_level level; + /** Bit array: which inequality is fulfilled at which level. */ + t8_element_type_t type; }; #endif /* T8_STANDALONE_ELEMENTS_HXX */ From efff7e31014acc75f2296780e061d54625602149 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Thu, 10 Apr 2025 17:05:08 +0200 Subject: [PATCH 02/37] start impelemting types --- .../t8_standalone_implementation.hxx | 236 ++++++++++++++---- 1 file changed, 188 insertions(+), 48 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index 4b36b97529..71d5c98eb9 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -151,7 +151,12 @@ struct t8_standalone_scheme element_get_num_corners (const t8_element_t *elem) noexcept { T8_ASSERT (element_is_valid (elem)); - + if constexpr (TEclass == T8_ECLASS_PYRAMID) { + if (element_get_shape (elem) == T8_ECLASS_PYRAMID) { + return 5; + } + return 4; + } return T8_ELEMENT_NUM_CORNERS[TEclass]; } @@ -163,10 +168,12 @@ struct t8_standalone_scheme element_get_num_faces (const t8_element_t *elem) noexcept { T8_ASSERT (element_is_valid (elem)); -#if T8_ENABLE_DEBUG - const t8_standalone_element *el = (const t8_standalone_element *) elem; - T8_ASSERT (0 <= el->level && el->level <= T8_ELEMENT_MAXLEVEL[TEclass]); -#endif + if constexpr (TEclass == T8_ECLASS_PYRAMID) { + if (t8_sele_shape (elem) == T8_ECLASS_PYRAMID) { + return 5; + } + return 4; + } return T8_ELEMENT_NUM_FACES[TEclass]; } @@ -179,10 +186,6 @@ struct t8_standalone_scheme element_get_max_num_faces (const t8_element_t *elem) noexcept { T8_ASSERT (element_is_valid (elem)); -#if T8_ENABLE_DEBUG - const t8_standalone_element *el = (const t8_standalone_element *) elem; - T8_ASSERT (0 <= el->level && el->level <= T8_ELEMENT_MAXLEVEL[TEclass]); -#endif return T8_ELEMENT_NUM_FACES[TEclass]; } @@ -196,6 +199,15 @@ struct t8_standalone_scheme element_get_shape (const t8_element_t *elem) noexcept { T8_ASSERT (element_is_valid (elem)); + const t8_standalone_element *el = (const t8_standalone_element *) elem; + if constexpr (TEclass == T8_ECLASS_PYRAMID) { + if (el->type == T8_DPYRAMID_FIRST_PYRA_TYPE || el->type == T8_DPYRAMID_SECOND_PYRA_TYPE) { + return T8_ECLASS_PYRAMID; + } + else { + return T8_ECLASS_TET; + } + } return TEclass; } @@ -309,9 +321,7 @@ struct t8_standalone_scheme if (el1->coords[idim] != el2->coords[idim]) return 0; } - /* return el1->type == el2->type; - ToDo-Type */ - return 1; + return el1->type == el2->type; } // ################################################____ACCESSOR____################################################ @@ -340,9 +350,7 @@ struct t8_standalone_scheme for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { el->coords[idim] = 0; } - /* el->type = 0; - ToDo-Type */ - return; + el->type = 0; } /** Compute the parent of a given element \b elem and store it in \b parent. @@ -368,7 +376,8 @@ struct t8_standalone_scheme T8_ASSERT (el->level > 0); if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + const t8_cube_id cube_id = t8_sele_compute_cubeid (el, el->level); + parent->type = t8_element_type_cubeid_to_parenttype[el->type.to_ulong ()][cube_id]; } const t8_element_coord length = element_get_len ((el->level)); @@ -450,7 +459,7 @@ struct t8_standalone_scheme /* Compute the cube id and shift the coordinates accordingly */ t8_cube_id cube_id; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + child_id = t8_element_type_cubeid_to_Iloc[el->type.to_ulong ()][cube_id]; } else { cube_id = childid; @@ -473,7 +482,12 @@ struct t8_standalone_scheme element_get_num_children (const t8_element_t *elem) noexcept { T8_ASSERT (element_is_valid (elem)); - + if constexpr (TEclass == T8_ECLASS_PYRAMID) { + if (element_get_shape (el) == T8_ECLASS_PYRAMID) { + return 10; + } + return 6; + } return T8_ELEMENT_NUM_CHILDREN[TEclass]; } @@ -522,7 +536,7 @@ struct t8_standalone_scheme const t8_cube_id cube_id = compute_cubeid (el, el->level); t8_child_id child_id; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + child_id = t8_element_type_cubeid_to_Iloc[el->type.to_ulong ()][cube_id]; } else { child_id = cube_id; @@ -608,13 +622,17 @@ struct t8_standalone_scheme const t8_standalone_element *el2 = (const t8_standalone_element *) elem2; /* get the first possible level of the nca*/ int cube_ancestor_level = element_get_cube_nca_level (el1, el2); - int real_level; + int real_level = cube_ancestor_level; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); - } - else { - real_level = cube_ancestor_level; + t8_element_type anc_type, anc2_type; + do { + anc_type = element_compute_type_at_level (el1, real_level); + anc2_type = element_compute_type_at_level (el2, real_level); + real_level--; + } while (anc_type != anc2_type); + real_level++; /* we subtracted once too much*/ } + /* get the ancestor at the calculated level*/ element_get_ancestor (el1, real_level, (t8_standalone_element *) nca); T8_ASSERT (element_is_valid (nca)); @@ -671,7 +689,7 @@ struct t8_standalone_scheme d->coords[idim] |= coord_offset; } - T8_ASSERT (element_is_valid (desc)); + T8_ASSERT (element_is_valid ((t8_element_t *) d)); } // ################################################____FACE REFINEMENT____################################################ @@ -715,10 +733,19 @@ struct t8_standalone_scheme if (child_indices == NULL) { child_indices = local_indices; } - const int face_sign = face % 2; - const int face_dim = face / 2; - for (int ifacechild = 0; ifacechild < num_children; ifacechild++) { - child_indices[ifacechild] = get_hypercube_face_corner_index (face_dim, face_sign, ifacechild); + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + const int face_sign = face % 2; + const int face_dim = face / 2; + for (int ifacechild = 0; ifacechild < num_children; ifacechild++) { + child_indices[ifacechild] = get_hypercube_face_corner_index (face_dim, face_sign, ifacechild); + } + } + else { + for (int ifacechild = 0; ifacechild < num_children; ifacechild++) { + child_indices[ifacechild] + = t8_sele_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][ifacechild]; + // t8_debugf("looked up child index %i for type %i, face %i, ifacechild %i\n", child_indices[ifacechild], elem->type.to_ulong(), face, ifacechild); + } } for (int ifacechild = num_children - 1; ifacechild >= 0; ifacechild--) { t8_standalone_scheme::element_get_child ((const t8_element_t *) el, child_indices[ifacechild], @@ -749,7 +776,14 @@ struct t8_standalone_scheme static constexpr int element_face_get_child_face (const t8_element_t *elem, const int face, const int face_child) noexcept { - return face; + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + return face; + } + else { + t8_standalone_element *el = (t8_standalone_element *) elem; + int child_id = t8_sele_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][face_child]; + return t8_sele_lut_type_childid_face_to_childface[el->type.to_ulong ()][child_id][face]; + } } /** Given a face of an element return the face number @@ -779,8 +813,8 @@ struct t8_standalone_scheme return face; } else { - SC_ABORT ("Only implemented for hypercubes.\n"); - return 0; + t8_cube_id cube_id = t8_sele_compute_cubeid (el, el->level); + return t8_sele_lut_type_cubeid_face_to_parentface[el->type.to_ulong ()][cube_id][face]; } } @@ -802,7 +836,7 @@ struct t8_standalone_scheme first_descendant->level = level; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + first_descendant->type = el->type; } for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { first_descendant->coords[idim] = el->coords[idim]; @@ -811,10 +845,14 @@ struct t8_standalone_scheme if (face_is_1_boundary) { //the face is a xi=1 boundary int facenormal_dim; - facenormal_dim = face / 2; - - t8_element_coord coord_offset = t8_standalone_scheme::element_get_len (el->level) - - t8_standalone_scheme::element_get_len (level); + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[eclass_T]) { + facenormal_dim = face / 2; + } + else { + facenormal_dim = t8_sele_lut_type_face_to_facenormal_dim[el->type.to_ulong ()][face]; + T8_ASSERT (facenormal_dim != -1); + } + t8_element_coord coord_offset = element_get_len (el->level) - element_get_len (level); first_descendant->coords[facenormal_dim] += coord_offset; } @@ -841,11 +879,18 @@ struct t8_standalone_scheme - t8_standalone_scheme::element_get_len (level); if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + last_descendant->type = el->type; /**TODO: Check if this is always true! */ } for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { - const int multiplier = (idim == face / 2) ? face % 2 : 1; + int multiplier = 1; + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + multiplier = (idim == face / 2) ? face % 2 : 1; + } + else { + t8_cube_id_t cube_id = t8_sele_lut_type_face_to_last_facechilds_cubeid[el->type.to_ulong ()][face]; + multiplier = (cube_id & (1 << idim)) >> idim; // = cubeid[idim]; + } last_descendant->coords[idim] = el->coords[idim] + multiplier * coord_offset; } } @@ -874,7 +919,18 @@ struct t8_standalone_scheme } // all edges containing dimid must be fulfilled with x_d-a_d >= x_j-a_j or x_j-a_j <= x_d-a_d if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { + if (t8_type_edge_equations[ieq][0] == dimid) { + if (el->type[ieq]) { + return 0; + } + } + else if (t8_type_edge_equations[ieq][1] == dimid) { + if (!el->type[ieq]) { + return 0; + } + } + } } } else { @@ -885,7 +941,18 @@ struct t8_standalone_scheme } // all edges containing dimid must be fulfilled with x_d-a_d <= x_j-a_j or x_j-a_j >= x_d-a_d if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { + if (t8_type_edge_equations[ieq][0] == dimid) { + if (!el->type[ieq]) { + return 0; + } + } + else if (t8_type_edge_equations[ieq][1] == dimid) { + if (el->type[ieq]) { + return 0; + } + } + } } } } @@ -894,8 +961,13 @@ struct t8_standalone_scheme // get graph edge e (or ieq) = (xi,xj) // ai = aj is necessary and sufficient if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + int ieq = t8_sele_lut_type_face_to_typebit[el->type.to_ulong ()][face]; + if (el->coords[t8_type_edge_equations[ieq][0]] + != el->coords[t8_type_edge_equations[ieq][1]]) { + return 0; + } } + else { SC_ABORT ("Cubes should not have internal faces!\n"); } @@ -920,7 +992,13 @@ struct t8_standalone_scheme element_get_tree_face (const t8_element_t *elem, const int face) noexcept { T8_ASSERT (element_is_valid (elem)); - return face; + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + return face; + } + else { + const t8_standalone_element *el = (const t8_standalone_element *) elem; + return t8_sele_lut_type_face_to_tree_face[el->type.to_ulong ()][face]; + } } /** Construct the face neighbor of a given element if this face neighbor @@ -950,17 +1028,49 @@ struct t8_standalone_scheme t8_standalone_element *neighbor = (t8_standalone_element *) neigh; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + int internal_face = t8_sele_lut_face_internal[el->type.to_ulong ()][face]; + if (internal_face) { + /**Determine typebit*/ + int typebit = t8_sele_lut_type_face_to_typebit[el->type.to_ulong ()][face]; + /**Change typebit*/ + neighbor->type.flip (typebit); + *neigh_face = t8_sele_lut_type_face_to_neighface[el->type.to_ulong ()][face]; + return element_is_inside_root (neighbor); + } + } + + int facenormal_dim, sign; + + if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + sign = t8_sele_lut_type_face_to_sign[el->type.to_ulong ()][face]; + facenormal_dim = t8_sele_lut_type_face_to_facenormal_dim[el->type.to_ulong ()][face]; + T8_ASSERT (facenormal_dim != -1); + } + else { + sign = face % 2 ? 1 : -1; + facenormal_dim = face / 2; } - const int facenormal_dim = face / 2; - const int sign = face % 2 ? 1 : -1; /**Adapt coordinates*/ const t8_element_coord length = element_get_len (el->level); - neighbor->coords[facenormal_dim] += length * sign; - *neigh_face = face ^ 1; + if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + for (size_t ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { + /**For all neighboring typebits, change typebit*/ + if (t8_type_edge_equations[ieq][0] == facenormal_dim + || t8_type_edge_equations[ieq][1] == facenormal_dim) { + neighbor->type.flip (ieq); /*ASSERT that flip is in correct direction */ + } + } + } + + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + *neigh_face = face ^ 1; + } + else { + *neigh_face = t8_sele_lut_type_face_to_neighface[el->type.to_ulong ()][face]; + } T8_ASSERT (element_is_valid ((t8_element_t *) neighbor)); /**check inside root*/ @@ -2065,6 +2175,36 @@ struct t8_standalone_scheme } return 0; } + + /* For each typebit, consider the coordinate information between level and p->level |10...11|xxxx|0...0| + * of both inequality defining dimensions */ + + static inline t8_element_type + element_compute_type_at_level (const t8_standalone_element *el, const int level) + { + t8_element_type type = 0; + T8_ASSERT (0 <= el->level && el->level <= T8_ELEMENT_MAXLEVEL[TEclass]); + + for (int e = 0; e < T8_ELEMENT_NUM_EQUATIONS[TEclass]; e++) { + t8_element_coord coord_v0 = el->coords[t8_type_edge_equations[e][0]]; + t8_element_coord coord_v1 = el->coords[t8_type_edge_equations[e][1]]; + + coord_v0 = (coord_v0 << level) & ((1 << T8_ELEMENT_MAXLEVEL[TEclass]) - 1); + coord_v1 = (coord_v1 << level) & ((1 << T8_ELEMENT_MAXLEVEL[TEclass]) - 1); + + if (coord_v0 == coord_v1) { + type[e] = el->type[e] | type[e]; + } + else if (coord_v0 < coord_v1) { + type |= (1 << e); + } + else { + T8_ASSERT (coord_v0 > coord_v1); + T8_ASSERT (!(type & (t8_element_type) (1 << e)).all ()); + } + } + return type; + } }; /** Suppose we have two trees that share a common face f. From 9d3ce51051f15bb7e6c8d38a9aef28f7a785f293 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 11 Apr 2025 11:10:19 +0200 Subject: [PATCH 03/37] add more type functionality --- .../t8_standalone_implementation.hxx | 176 ++++++++++++++---- 1 file changed, 135 insertions(+), 41 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index a1666cd961..ffae8aea0f 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -168,16 +168,12 @@ struct t8_standalone_scheme element_get_num_faces ([[maybe_unused]] const t8_element_t *elem) noexcept { T8_ASSERT (element_is_valid (elem)); -<<<<<<< HEAD if constexpr (TEclass == T8_ECLASS_PYRAMID) { if (t8_sele_shape (elem) == T8_ECLASS_PYRAMID) { return 5; } return 4; } -======= - /* Note: With the introduction of pyramids the implementation will be adjusted. */ ->>>>>>> origin/main return T8_ELEMENT_NUM_FACES[TEclass]; } @@ -649,12 +645,12 @@ struct t8_standalone_scheme int cube_ancestor_level = element_get_cube_nca_level (el1, el2); int real_level = cube_ancestor_level; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - t8_element_type anc_type, anc2_type; + t8_element_type ancestor_type, ancestor2_type; do { - anc_type = element_compute_type_at_level (el1, real_level); - anc2_type = element_compute_type_at_level (el2, real_level); + ancestor_type = element_compute_type_at_level (el1, real_level); + ancestor2_type = element_compute_type_at_level (el2, real_level); real_level--; - } while (anc_type != anc2_type); + } while (ancestor_type != ancestor2_type); real_level++; /* we subtracted once too much*/ } @@ -874,7 +870,6 @@ struct t8_standalone_scheme const bool face_is_1_boundary = face % 2; if (face_is_1_boundary) { //the face is a xi=1 boundary -<<<<<<< HEAD int facenormal_dim; if constexpr (!T8_ELEMENT_NUM_EQUATIONS[eclass_T]) { facenormal_dim = face / 2; @@ -884,11 +879,6 @@ struct t8_standalone_scheme T8_ASSERT (facenormal_dim != -1); } t8_element_coord coord_offset = element_get_len (el->level) - element_get_len (level); -======= - const int facenormal_dim = face / 2; - - const t8_element_coord coord_offset = element_get_len (el->level) - element_get_len (level); ->>>>>>> origin/main first_descendant->coords[facenormal_dim] += coord_offset; } @@ -1030,7 +1020,6 @@ struct t8_standalone_scheme element_get_tree_face ([[maybe_unused]] const t8_element_t *elem, const int face) noexcept { T8_ASSERT (element_is_valid (elem)); -<<<<<<< HEAD if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { return face; } @@ -1038,10 +1027,6 @@ struct t8_standalone_scheme const t8_standalone_element *el = (const t8_standalone_element *) elem; return t8_sele_lut_type_face_to_tree_face[el->type.to_ulong ()][face]; } -======= - T8_ASSERT (0 <= face && face < T8_ELEMENT_NUM_FACES[TEclass]); - return face; ->>>>>>> origin/main } /** Construct the face neighbor of a given element if this face neighbor @@ -1185,10 +1170,12 @@ struct t8_standalone_scheme T8_ASSERT (t8_standalone_scheme::element_is_valid (face)); return extrude_face ((t8_standalone_element *) face, elem, root_face); break; + case T8_ECLASS_TRIANGLE: + T8_ASSERT (t8_standalone_scheme::element_is_valid (face)); + return extrude_face ((t8_standalone_element *) face, elem, root_face); + break; default: - if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); - } + SC_ABORT ("Only useful for two-dimensional eclasses.\n"); return 0; break; } @@ -1224,10 +1211,12 @@ struct t8_standalone_scheme case T8_ECLASS_QUAD: compute_boundary_face (elem, root_face, (t8_standalone_element *) boundary); return; + case T8_ECLASS_TRIANGLE: + compute_boundary_face (elem, root_face, + (t8_standalone_element *) boundary); + return; default: - if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); - } + SC_ABORT ("Only useful for two-dimensional eclasses.\n"); return; } } @@ -1410,7 +1399,9 @@ struct t8_standalone_scheme T8_ASSERT (level <= T8_ELEMENT_MAXLEVEL[TEclass]); T8_ASSERT (level >= 0); if constexpr (TEclass == T8_ECLASS_PYRAMID) { - SC_ABORT ("Not implemented yet.\n"); + t8_linearidx_t two_to_l = 1LL << level; + t8_linearidx_t eight_to_l = 1LL << (3 * level); + return ((eight_to_l << 2) - two_to_l) / 3; } return 1LL << (level * T8_ELEMENT_DIM[TEclass]); } @@ -1808,7 +1799,7 @@ struct t8_standalone_scheme /* Set type */ if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + ancestor->type = element_compute_type_at_level (ancestor, level); } /* The coordinates and the type of the ancestor are defined by the level. */ @@ -1929,7 +1920,14 @@ struct t8_standalone_scheme { T8_ASSERT (leveldiff <= get_maxlevel ()); if constexpr (TEclass == T8_ECLASS_PYRAMID) { - SC_ABORT ("Not implemented yet.\n"); + t8_linearidx_t two_to_l = 1LL << leveldiff; + t8_linearidx_t eight_to_l = 1LL << (3 * leveldiff); + if (element_get_shape (elem) == T8_ECLASS_PYRAMID) { + return ((eight_to_l << 2) - two_to_l) / 3; + } + else { + return ((eight_to_l << 1) + two_to_l) / 3; + } } return 1LL << (T8_ELEMENT_DIM[TEclass] * leveldiff); } @@ -1946,7 +1944,12 @@ struct t8_standalone_scheme T8_ASSERT (0 <= vertex && vertex < element_get_num_corners ((const t8_element_t *) elem)); if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + t8_standalone_element *el = (t8_standalone_element *) elem; + int8_t type = el->type.to_ulong (); + for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { + coords[idim] + = el->coords[idim] + t8_type_vertex_dim_to_binary[type][vertex][idim] * element_get_len (el->level); + } } else { //Hypercubes @@ -1992,7 +1995,7 @@ struct t8_standalone_scheme return 0; } else { - SC_ABORT ("Only implemented for hypercubes.\n"); + return t8_sele_lut_face_internal[elem->type.to_ulong ()][face]; } } @@ -2010,10 +2013,9 @@ struct t8_standalone_scheme return face / 2; } else { - SC_ABORT ("Only implemented for hypercubes.\n"); + return t8_sele_lut_type_face_to_facenormal_dim[elem->type.to_ulong ()][face]; } } - /** Given a face of an element that is also a hypercube face, determine if it is the boundary x_i == 1. * \param [in] elem The input element. * \param [in] face The input face. Needs to be a face of the hypercube the element is embedded in. @@ -2028,7 +2030,7 @@ struct t8_standalone_scheme return face % 2; } else { - SC_ABORT ("Only implemented for hypercubes.\n"); + return t8_sele_lut_type_face_to_is_1_boundary[elem->type.to_ulong ()][face]; } } @@ -2067,7 +2069,7 @@ struct t8_standalone_scheme return T8_ECLASS_QUAD; default: if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + return t8_sele_lut_rootface_to_eclass[root_face]; } return T8_ECLASS_INVALID; } @@ -2117,11 +2119,15 @@ struct t8_standalone_scheme } } if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - SC_ABORT ("Only implemented for hypercubes.\n"); + for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { + int ifaceeq = t8_sele_lut_rootface_eq_to_faceeq[root_face][ieq]; + if (ifaceeq != -1) { + boundary->type[ifaceeq] = elem->type[ieq]; + } + } + T8_ASSERT (t8_standalone_scheme::element_is_valid ((t8_element_t *) boundary)); } - T8_ASSERT (t8_standalone_scheme::element_is_valid ((t8_element_t *) boundary)); } - /** Given a boundary face inside a root tree's face construct * the element inside the root tree that has the given face as a * face. @@ -2167,6 +2173,7 @@ struct t8_standalone_scheme } } else { + /* Set the coordinate orthogonal to the face.*/ if (root_face_is_1_boundary (root_face)) { /* Anchor coordinate is its own length smaller than the length of the root element.*/ @@ -2183,7 +2190,25 @@ struct t8_standalone_scheme return root_face; } else { - SC_ABORT ("Only implemented for hypercubes.\n"); + t8_element_type root_type = 0; + elem->type = root_type; + for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { + int ifaceeq = t8_sele_lut_rootface_eq_to_faceeq[root_face][ieq]; + if (ifaceeq != -1) { + elem->type[ieq] = face->type[ifaceeq]; + } + } + /** Set those typebits, that are connected to the face_normaldim of root_face*/ + for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { + int facenormal_dim = t8_sele_lut_type_face_to_facenormal_dim[root_type.to_ulong ()][root_face]; + if (t8_type_edge_equations[ieq][0] == facenormal_dim) { + elem->type[ieq] = !t8_sele_lut_type_face_to_is_1_boundary[root_type.to_ulong ()][root_face]; + } + else if (t8_type_edge_equations[ieq][1] == facenormal_dim) { + elem->type[ieq] = t8_sele_lut_type_face_to_is_1_boundary[root_type.to_ulong ()][root_face]; + } + } + return t8_sele_lut_type_rootface_to_face[elem->type.to_ulong ()][root_face]; } } @@ -2226,9 +2251,8 @@ struct t8_standalone_scheme } } else { - SC_ABORT ("Only implemented for hypercubes.\n"); + return t8_sele_lut_rootface_dim_to_facedim[root_face][idim]; } - return 0; } /* For each typebit, consider the coordinate information between level and p->level |10...11|xxxx|0...0| @@ -2398,7 +2422,77 @@ t8_standalone_scheme::element_transform_face ([[maybe_unused [[maybe_unused]] const int sign, [[maybe_unused]] const int is_smaller_face) noexcept { - SC_ABORT ("Only implemented for hypercubes.\n"); + T8_ASSERT (0 <= orientation && orientation <= 2); + const t8_standalone_element *el1 = (const t8_standalone_element *) elem1; + t8_standalone_element *el2 = (t8_standalone_element *) elem2; + + t8_element_coord h = element_get_len (el1->level); + + // copy elem1 in tmp so that results can directly be set in elem2 + t8_element_t *temp; + element_copy (elem1, temp); + t8_standalone_element *tmp = (t8_standalone_element *) temp; + + /* + * The corners of the triangle are enumerated like this + * type 0 type 1 + * also root tree + * v_2 v_1 v_2 + * x x--x + * /| | / + * / | |/ + * x--x x + * v_0 v_1 v_0 + * + */ + if (sign) { + /* The tree faces have the same topological orientation, and + * thus we have to perform a coordinate switch. */ + if (el1->type == 0) { + tmp->coords[1] = el1->coords[0] - el1->coords[1]; + } + else { + tmp->coords[1] = el1->coords[0] - el1->coords[1] - h; + } + } + + if (!is_smaller_face && orientation != 0 && !sign) { + /* Translate orientation if triangle1 is not on the smaller face. + * sign = 0 sign = 1 + * 0 -> 0 0 -> 0 + * 1 -> 2 1 -> 1 + * 2 -> 1 2 -> 2 + */ + orientation = 3 - orientation; + } + + el2->level = tmp->level; + el2->type = tmp->type; + switch (orientation) { + case 0: + element_copy ((t8_element_t *) tmp, (t8_element_t *) el2); + break; + case 1: + el2->coords[0] = get_root_len () - h - tmp->coords[1]; + if (tmp->type == 0) { + el2->coords[1] = tmp->coords[0] - tmp->coords[1]; + } + else { + el2->coords[1] = tmp->coords[0] - tmp->coords[1] - h; + } + break; + case 2: + if (tmp->type == 0) { + el2->coords[0] = get_root_len () - h + tmp->coords[1] - tmp->coords[0]; + } + else { + el2->coords[0] = get_root_len () + tmp->coords[1] - tmp->coords[0]; + } + el2->coords[1] = get_root_len () - h - tmp->coords[0]; + break; + default: + SC_ABORT_NOT_REACHED (); + } }; #endif /* T8_STANDALONE_IMPLEMENTATION_HXX */ From 4f3d26e45158747d7e9e9358c5346cdc512c46f9 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 11 Apr 2025 16:03:12 +0200 Subject: [PATCH 04/37] add luts --- .../t8_standalone_lut_prism.hxx | 227 ++++++++ .../t8_standalone_lut_pyra.hxx | 337 ++++++++++++ .../t8_standalone_lut_tet.hxx | 496 ++++++++++++++++++ .../t8_standalone_lut_triangle.hxx | 199 +++++++ 4 files changed, 1259 insertions(+) create mode 100644 src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx create mode 100644 src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx create mode 100644 src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx create mode 100644 src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx new file mode 100644 index 0000000000..7e5beb96f1 --- /dev/null +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx @@ -0,0 +1,227 @@ +/* + 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) 2025 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_SELE_LUT_PRISM_HXX +#define T8_SELE_LUT_PRISM_HXX +// PRISMS +// clang-format off +template<> +constexpr int8_t t8_element_type_Iloc_to_childtype[1< +constexpr int8_t t8_element_type_Iloc_to_childcubeid[1< +constexpr int8_t t8_element_type_cubeid_to_parenttype[1< +constexpr int8_t t8_element_type_cubeid_to_Iloc[1< +constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][2] = { + {0, 1} +}; + +template<> +constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]] + [T8_ELEMENT_NUM_CORNERS[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]] = { + { + {0, 0, 0}, + {1, 0, 0}, + {1, 1, 0}, + {0, 0, 1}, + {1, 0, 1}, + {1, 1, 1} + }, + { + /* PAY ATTENTION TO ORDERING OF ELEMENTS! What is the ordering? **/ + {0, 0, 0}, + {0, 1, 0}, + {1, 1, 0}, + {0, 0, 1}, + {0, 1, 1}, + {1, 1, 1} + } +}; + + +template<> +constexpr int8_t t8_standalone_lut_face_internal[1< +constexpr int8_t t8_standalone_lut_type_face_to_typebit[1< +constexpr int8_t t8_standalone_lut_type_face_to_sign[1< +constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1< +constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1< +constexpr int8_t t8_standalone_lut_type_face_to_neighface[1< +constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1< +constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1< +constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1< +constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1< +constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1< +constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ + {-1,0,1}, + {0,0,1}, + {0,-1,1}, + {0,1,-1}, + {0,1,-1} +}; +template<> +constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]]={ + {-1}, + {-1}, + {-1}, + {0}, + {0} +}; + +template<> +constexpr int8_t t8_standalone_lut_type_rootface_to_face[1< +constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]]={ + T8_ECLASS_QUAD, + T8_ECLASS_QUAD, + T8_ECLASS_QUAD, + T8_ECLASS_TRIANGLE, + T8_ECLASS_TRIANGLE +}; +// clang-format on +#endif /* T8_SELE_LUT_PRISM_HXX */ diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx new file mode 100644 index 0000000000..c7c3fea4ac --- /dev/null +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx @@ -0,0 +1,337 @@ +/* + 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) 2025 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_SELE_LUT_PYRA_HXX +#define T8_SELE_LUT_PYRA_HXX +// PYRAS +// clang-format off + +/** The first type of pyramids in the shape of a pyramid*/ +#define T8_DPYRAMID_FIRST_PYRA_TYPE 0 + +/** The second type of pyramids in the shape of a pyramid*/ +#define T8_DPYRAMID_SECOND_PYRA_TYPE 3 + + +template<> +constexpr int8_t t8_element_type_Iloc_to_childtype[1< +constexpr int8_t t8_element_type_Iloc_to_childcubeid[1< +constexpr int8_t t8_element_type_cubeid_to_parenttype[1< +constexpr int8_t t8_element_type_cubeid_to_Iloc[1< +constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][2] = { + {1, 2}, + {0, 2} +}; + +template<> +constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]] + [T8_ELEMENT_NUM_CORNERS[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]] = { + { + {0, 0, 0}, + {1, 0, 0}, + {0, 1, 0}, + {1, 1, 0}, + {1, 1, 1} + }, + { + {0, 0, 0}, + {1, 0, 0}, + {1, 0, 1}, + {1, 1, 1}, + {-1, -1, -1} + }, + { + {0, 0, 0}, + {0, 1, 0}, + {0, 1, 1}, + {1, 1, 1}, + {-1, -1, -1} + }, + { + /* PAY ATTENTION TO ORDERING OF ELEMENTS! **/ + {0, 0, 1}, + {1, 0, 1}, + {0, 1, 1}, + {1, 1, 1}, + {0, 0, 0} + } +}; + +template<> +constexpr int8_t t8_standalone_lut_face_internal[1< +constexpr int8_t t8_standalone_lut_type_face_to_typebit[1< +constexpr int8_t t8_standalone_lut_type_face_to_sign[1< +constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1< +constexpr int8_t t8_standalone_lut_type_face_to_neighface[1< +constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1< +constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1< +constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1< +constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1< +constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1< +constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1< +constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ + { 1,0,1}, + {-1,0,1}, + {0,1,1}, + {0,-1,1}, + {0,1,-1} +}; +template<> +constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]]={ + {0,-1}, + {0,-1}, + {-1,0}, + {-1,0}, + {-1,-1} +}; + +template<> +constexpr int8_t t8_standalone_lut_type_rootface_to_face[1< +constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]]={ + T8_ECLASS_TRIANGLE, + T8_ECLASS_TRIANGLE, + T8_ECLASS_TRIANGLE, + T8_ECLASS_TRIANGLE, + T8_ECLASS_QUAD +}; +// clang-format on +#endif /* T8_SELE_LUT_PYRA_HXX */ diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx new file mode 100644 index 0000000000..d6ffd7a813 --- /dev/null +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx @@ -0,0 +1,496 @@ +/* + 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) 2025 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_SELE_LUT_TET_HXX +#define T8_SELE_LUT_TET_HXX +// TETS + +// clang-format off +template<> +constexpr int8_t t8_element_type_Iloc_to_childtype[1< +constexpr int8_t t8_element_type_Iloc_to_childcubeid[1< +constexpr int8_t t8_element_type_cubeid_to_parenttype[1< +constexpr int8_t t8_element_type_cubeid_to_Iloc[1<= y >= z*/ +template<> +constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][2] = { + {0, 1}, + {1, 2}, + {0, 2} +}; + +template<> +constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]] + [T8_ELEMENT_NUM_CORNERS[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]] = { + { + {0, 0, 0}, + {1, 0, 0}, + {1, 1, 0}, + {1, 1, 1} + }, + { + {0, 0, 0}, + {0, 1, 0}, + {1, 1, 0}, + {1, 1, 1} + }, + { + {0, 0, 0}, + {1, 0, 0}, + {1, 0, 1}, + {1, 1, 1} + }, + { + {-1, -1, -1}, + {-1, -1, -1}, + {-1, -1, -1}, + {-1, -1, -1} + }, + { + {-1, -1, -1}, + {-1, -1, -1}, + {-1, -1, -1}, + {-1, -1, -1} + }, + { + {0, 0, 0}, + {0, 1, 0}, + {0, 1, 1}, + {1, 1, 1} + }, + { + {0, 0, 0}, + {0, 0, 1}, + {1, 0, 1}, + {1, 1, 1} + }, + { + {0, 0, 0}, + {0, 0, 1}, + {0, 1, 1}, + {1, 1, 1} + } +}; +template<> +constexpr int8_t t8_standalone_lut_face_internal[1< +constexpr int8_t t8_standalone_lut_type_face_to_typebit[1< +constexpr int8_t t8_standalone_lut_type_face_to_sign[1< +constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1< +constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1< +constexpr int8_t t8_standalone_lut_type_face_to_neighface[1< +constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1< +constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1< +constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1< +constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1< +constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1< +constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]]={ + {-1,0,1}, + {0,0,1}, + {0,1,1}, + {0,1,-1} +}; +template<> +constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]]={ + {-1, 0,-1}, + {-1, 0, 0}, + { 0,-1, 0}, + { 0,-1,-1} +}; + +template<> +constexpr int8_t t8_standalone_lut_type_rootface_to_face[1< +constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]]={ + T8_ECLASS_TRIANGLE, + T8_ECLASS_TRIANGLE, + T8_ECLASS_TRIANGLE, + T8_ECLASS_TRIANGLE +}; +// clang-format on +#endif /* T8_SELE_LUT_TET_HXX */ diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx new file mode 100644 index 0000000000..855c152d81 --- /dev/null +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx @@ -0,0 +1,199 @@ +/* + 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) 2025 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_SELE_LUT_TRIANGLE_HXX +#define T8_SELE_LUT_TRIANGLE_HXX +// TRIANGLES +// clang-format off +template<> +constexpr int8_t t8_element_type_Iloc_to_childtype[1< +constexpr int8_t t8_element_type_Iloc_to_childcubeid[1< +constexpr int8_t t8_element_type_cubeid_to_parenttype[1< +constexpr int8_t t8_element_type_cubeid_to_Iloc[1< +constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][2] = { + {0, 1} +}; + +template<> +constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]] + [T8_ELEMENT_NUM_CORNERS[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]] = { + { + {0, 0}, + {1, 0}, + {1, 1} + }, + { + /* PAY ATTENTION TO ORDERING OF ELEMENTS! What is the ordering? **/ + {0, 0}, + {0, 1}, + {1, 1} + } +}; + + +template<> +constexpr int8_t t8_standalone_lut_face_internal[1< +constexpr int8_t t8_standalone_lut_type_face_to_typebit[1< +constexpr int8_t t8_standalone_lut_type_face_to_sign[1< +constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1< +constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1< +constexpr int8_t t8_standalone_lut_type_face_to_neighface[1< +constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1< +constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1< +constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1< +constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1< +constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1< +constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ + {-1,0}, + {0,0}, + {0,-1} +}; +template<> +constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]]={ + {-1}, + {-1}, + {-1} +}; + +template<> +constexpr int8_t t8_standalone_lut_type_rootface_to_face[1< +constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]]={ + T8_ECLASS_LINE, + T8_ECLASS_LINE, + T8_ECLASS_LINE +}; + +// clang-format on +#endif /* T8_SELE_LUT_TRIANGLE_HXX */ From 1176bf7aaf5a80e3f4f9331303e6bcd8739394d2 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 11 Apr 2025 16:03:51 +0200 Subject: [PATCH 05/37] add types to standalone --- src/t8_schemes/t8_scheme.hxx | 6 +- .../t8_standalone/t8_standalone.cxx | 8 +- .../t8_standalone/t8_standalone_elements.hxx | 136 +++++++++--------- .../t8_standalone_implementation.hxx | 98 ++++++------- 4 files changed, 128 insertions(+), 120 deletions(-) diff --git a/src/t8_schemes/t8_scheme.hxx b/src/t8_schemes/t8_scheme.hxx index 2c5fd6143d..5976b4cb6d 100644 --- a/src/t8_schemes/t8_scheme.hxx +++ b/src/t8_schemes/t8_scheme.hxx @@ -98,7 +98,11 @@ class t8_scheme { t8_standalone_scheme, t8_standalone_scheme, t8_standalone_scheme, - t8_standalone_scheme + t8_standalone_scheme, + t8_standalone_scheme, + t8_standalone_scheme, + t8_standalone_scheme, + t8_standalone_scheme >; /* clang-format on */ diff --git a/src/t8_schemes/t8_standalone/t8_standalone.cxx b/src/t8_schemes/t8_standalone/t8_standalone.cxx index b66f35a2b3..ffd3687efa 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone.cxx +++ b/src/t8_schemes/t8_standalone/t8_standalone.cxx @@ -34,11 +34,11 @@ t8_scheme_new_standalone (void) builder.add_eclass_scheme> (); builder.add_eclass_scheme> (); builder.add_eclass_scheme> (); - builder.add_eclass_scheme (); + builder.add_eclass_scheme> (); builder.add_eclass_scheme> (); - builder.add_eclass_scheme (); - builder.add_eclass_scheme (); - builder.add_eclass_scheme (); + builder.add_eclass_scheme> (); + builder.add_eclass_scheme> (); + builder.add_eclass_scheme> (); // builder.add_eclass_scheme> (); //ADD if PYRAMID in "element_get_shape" return builder.build_scheme (); } diff --git a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx index 3b4e1f1cfe..441e14c476 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx @@ -40,86 +40,88 @@ constexpr uint8_t T8_ELEMENT_MAX_NUM_FACECHILDREN[T8_ECLASS_COUNT] = { 0, 1, 2, constexpr uint8_t T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_COUNT] = { 0, 0, 0, 1, 0, 3, 1, 2 }; /**PARENT CHILD BIJECTION*/ -template -constexpr int8_t t8_element_type_Iloc_to_childtype[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_CHILDREN[eclass_T]]; -template -constexpr int8_t t8_element_type_Iloc_to_childcubeid[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_CHILDREN[eclass_T]]; -template -constexpr int8_t t8_element_type_cubeid_to_parenttype[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [1 << T8_ELEMENT_DIM[eclass_T]]; -template -constexpr int8_t t8_element_type_cubeid_to_Iloc[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]][1 << T8_ELEMENT_DIM[eclass_T]]; +template +constexpr int8_t t8_element_type_Iloc_to_childtype[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_CHILDREN[TEclass]]; +template +constexpr int8_t t8_element_type_Iloc_to_childcubeid[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_CHILDREN[TEclass]]; +template +constexpr int8_t t8_element_type_cubeid_to_parenttype[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [1 << T8_ELEMENT_DIM[TEclass]]; +template +constexpr int8_t t8_element_type_cubeid_to_Iloc[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][1 << T8_ELEMENT_DIM[TEclass]]; /**TYPE EQUATIONS*/ -template -constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[eclass_T]][2]; +template +constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[TEclass]][2]; /**VERTEX*/ -template -constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]][T8_ELEMENT_NUM_CORNERS[eclass_T]] - [T8_ELEMENT_DIM[eclass_T]]; +template +constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_CORNERS[TEclass]] + [T8_ELEMENT_DIM[TEclass]]; /**FACE*/ -template -constexpr int8_t t8_sele_lut_face_internal[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]][T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_face_to_typebit[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_face_to_sign[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]][T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_face_to_facenormal_dim[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_face_to_neighface[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_cubeid_face_to_parentface[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [1 << T8_ELEMENT_DIM[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_face_to_is_1_boundary[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_face_to_last_facechilds_cubeid[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_face_facechildid_to_childid[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]] - [T8_ELEMENT_MAX_NUM_FACECHILDREN[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_childid_face_to_childface[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_CHILDREN[eclass_T]] - [T8_ELEMENT_MAX_NUM_FACECHILDREN[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_face_to_tree_face[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr int8_t t8_sele_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[eclass_T]][T8_ELEMENT_DIM[eclass_T]]; -template -constexpr int8_t t8_sele_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[eclass_T]][T8_ELEMENT_NUM_EQUATIONS[eclass_T]]; -template -constexpr int8_t t8_sele_lut_type_rootface_to_face[1 << T8_ELEMENT_NUM_EQUATIONS[eclass_T]] - [T8_ELEMENT_NUM_FACES[eclass_T]]; -template -constexpr t8_eclass_t t8_sele_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[eclass_T]]; - -// #include "t8_sele_lut_triangle_cxx.hxx" -// #include "t8_sele_lut_prism_cxx.hxx" -// #include "t8_sele_lut_pyra_cxx.hxx" -// #include "t8_sele_lut_tet_cxx.hxx" +template +constexpr int8_t t8_standalone_lut_face_internal[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_face_to_typebit[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_face_to_sign[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_face_to_neighface[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [1 << T8_ELEMENT_DIM[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]] + [T8_ELEMENT_MAX_NUM_FACECHILDREN[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_CHILDREN[TEclass]] + [T8_ELEMENT_MAX_NUM_FACECHILDREN[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[TEclass]][T8_ELEMENT_DIM[TEclass]]; +template +constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[TEclass]] + [T8_ELEMENT_NUM_EQUATIONS[TEclass]]; +template +constexpr int8_t t8_standalone_lut_type_rootface_to_face[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] + [T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr t8_eclass t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[TEclass]]; + +#include "t8_standalone_lut/t8_standalone_lut_triangle.hxx" +#include "t8_standalone_lut/t8_standalone_lut_prism.hxx" +#include "t8_standalone_lut/t8_standalone_lut_pyra.hxx" +#include "t8_standalone_lut/t8_standalone_lut_tet.hxx" typedef int32_t t8_element_coord; typedef uint8_t t8_element_level; typedef uint8_t t8_cube_id; typedef uint8_t t8_child_id; -template +template using t8_element_type = std::bitset; -template +template using t8_element_coords = std::array; template struct t8_standalone_element @@ -129,7 +131,7 @@ struct t8_standalone_element /** The refinement level of the element relative to the root at level 0. */ t8_element_level level; /** Bit array: which inequality is fulfilled at which level. */ - t8_element_type_t type; + t8_element_type type; }; #endif /* T8_STANDALONE_ELEMENTS_HXX */ diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index ffae8aea0f..4e1dd65ced 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -169,7 +169,7 @@ struct t8_standalone_scheme { T8_ASSERT (element_is_valid (elem)); if constexpr (TEclass == T8_ECLASS_PYRAMID) { - if (t8_sele_shape (elem) == T8_ECLASS_PYRAMID) { + if (element_get_shape (elem) == T8_ECLASS_PYRAMID) { return 5; } return 4; @@ -382,8 +382,8 @@ struct t8_standalone_scheme T8_ASSERT (el->level > 0); if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - const t8_cube_id cube_id = t8_sele_compute_cubeid (el, el->level); - parent->type = t8_element_type_cubeid_to_parenttype[el->type.to_ulong ()][cube_id]; + const t8_cube_id cube_id = compute_cubeid (el, el->level); + parent_elem->type = t8_element_type_cubeid_to_parenttype[el->type.to_ulong ()][cube_id]; } const t8_element_coord length = element_get_len ((el->level)); @@ -413,7 +413,9 @@ struct t8_standalone_scheme T8_ASSERT (0 < el->level && el->level <= T8_ELEMENT_MAXLEVEL[TEclass]); /* To get the number siblings, we first get the parent and then get the number of children of that parent*/ if constexpr (refines_irregular ()) { - SC_ABORT ("This function is not implemented yet.\n"); + t8_standalone_element parent; + element_get_parent ((t8_element_t *) el, (t8_element_t *) &parent); + return element_get_num_children ((t8_element_t *) &parent); } else { return T8_ELEMENT_NUM_CHILDREN[TEclass]; @@ -466,7 +468,8 @@ struct t8_standalone_scheme /* Compute the cube id and shift the coordinates accordingly */ t8_cube_id cube_id; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - child_id = t8_element_type_cubeid_to_Iloc[el->type.to_ulong ()][cube_id]; + cube_id = t8_element_type_cubeid_to_Iloc[el->type.to_ulong ()][childid]; + c->type = t8_element_type_Iloc_to_childtype[el->type.to_ulong ()][childid]; } else { cube_id = childid; @@ -490,7 +493,7 @@ struct t8_standalone_scheme { T8_ASSERT (element_is_valid (elem)); if constexpr (TEclass == T8_ECLASS_PYRAMID) { - if (element_get_shape (el) == T8_ECLASS_PYRAMID) { + if (element_get_shape (elem) == T8_ECLASS_PYRAMID) { return 10; } return 6; @@ -766,7 +769,7 @@ struct t8_standalone_scheme else { for (int ifacechild = 0; ifacechild < num_children; ifacechild++) { child_indices[ifacechild] - = t8_sele_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][ifacechild]; + = t8_standalone_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][ifacechild]; // t8_debugf("looked up child index %i for type %i, face %i, ifacechild %i\n", child_indices[ifacechild], elem->type.to_ulong(), face, ifacechild); } } @@ -805,8 +808,9 @@ struct t8_standalone_scheme } else { t8_standalone_element *el = (t8_standalone_element *) elem; - int child_id = t8_sele_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][face_child]; - return t8_sele_lut_type_childid_face_to_childface[el->type.to_ulong ()][child_id][face]; + int child_id + = t8_standalone_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][face_child]; + return t8_standalone_lut_type_childid_face_to_childface[el->type.to_ulong ()][child_id][face]; } } @@ -838,8 +842,8 @@ struct t8_standalone_scheme return face; } else { - t8_cube_id cube_id = t8_sele_compute_cubeid (el, el->level); - return t8_sele_lut_type_cubeid_face_to_parentface[el->type.to_ulong ()][cube_id][face]; + t8_cube_id cube_id = compute_cubeid (el, el->level); + return t8_standalone_lut_type_cubeid_face_to_parentface[el->type.to_ulong ()][cube_id][face]; } } @@ -871,11 +875,11 @@ struct t8_standalone_scheme if (face_is_1_boundary) { //the face is a xi=1 boundary int facenormal_dim; - if constexpr (!T8_ELEMENT_NUM_EQUATIONS[eclass_T]) { + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { facenormal_dim = face / 2; } else { - facenormal_dim = t8_sele_lut_type_face_to_facenormal_dim[el->type.to_ulong ()][face]; + facenormal_dim = t8_standalone_lut_type_face_to_facenormal_dim[el->type.to_ulong ()][face]; T8_ASSERT (facenormal_dim != -1); } t8_element_coord coord_offset = element_get_len (el->level) - element_get_len (level); @@ -915,7 +919,7 @@ struct t8_standalone_scheme multiplier = (idim == face / 2) ? face % 2 : 1; } else { - t8_cube_id_t cube_id = t8_sele_lut_type_face_to_last_facechilds_cubeid[el->type.to_ulong ()][face]; + t8_cube_id cube_id = t8_standalone_lut_type_face_to_last_facechilds_cubeid[el->type.to_ulong ()][face]; multiplier = (cube_id & (1 << idim)) >> idim; // = cubeid[idim]; } last_descendant->coords[idim] = el->coords[idim] + multiplier * coord_offset; @@ -948,12 +952,12 @@ struct t8_standalone_scheme // all edges containing dim must be fulfilled with x_d-a_d >= x_j-a_j or x_j-a_j <= x_d-a_d if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - if (t8_type_edge_equations[ieq][0] == dimid) { + if (t8_type_edge_equations[ieq][0] == dim) { if (el->type[ieq]) { return 0; } } - else if (t8_type_edge_equations[ieq][1] == dimid) { + else if (t8_type_edge_equations[ieq][1] == dim) { if (!el->type[ieq]) { return 0; } @@ -970,12 +974,12 @@ struct t8_standalone_scheme // all edges containing dimid must be fulfilled with x_d-a_d <= x_j-a_j or x_j-a_j >= x_d-a_d if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - if (t8_type_edge_equations[ieq][0] == dimid) { + if (t8_type_edge_equations[ieq][0] == dim) { if (!el->type[ieq]) { return 0; } } - else if (t8_type_edge_equations[ieq][1] == dimid) { + else if (t8_type_edge_equations[ieq][1] == dim) { if (el->type[ieq]) { return 0; } @@ -989,7 +993,7 @@ struct t8_standalone_scheme // get graph edge e (or ieq) = (xi,xj) // ai = aj is necessary and sufficient if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - int ieq = t8_sele_lut_type_face_to_typebit[el->type.to_ulong ()][face]; + int ieq = t8_standalone_lut_type_face_to_typebit[el->type.to_ulong ()][face]; if (el->coords[t8_type_edge_equations[ieq][0]] != el->coords[t8_type_edge_equations[ieq][1]]) { return 0; @@ -1025,7 +1029,7 @@ struct t8_standalone_scheme } else { const t8_standalone_element *el = (const t8_standalone_element *) elem; - return t8_sele_lut_type_face_to_tree_face[el->type.to_ulong ()][face]; + return t8_standalone_lut_type_face_to_tree_face[el->type.to_ulong ()][face]; } } @@ -1057,13 +1061,13 @@ struct t8_standalone_scheme t8_standalone_element *neighbor = (t8_standalone_element *) neigh; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - int internal_face = t8_sele_lut_face_internal[el->type.to_ulong ()][face]; + int internal_face = t8_standalone_lut_face_internal[el->type.to_ulong ()][face]; if (internal_face) { /**Determine typebit*/ - int typebit = t8_sele_lut_type_face_to_typebit[el->type.to_ulong ()][face]; + int typebit = t8_standalone_lut_type_face_to_typebit[el->type.to_ulong ()][face]; /**Change typebit*/ neighbor->type.flip (typebit); - *neigh_face = t8_sele_lut_type_face_to_neighface[el->type.to_ulong ()][face]; + *neigh_face = t8_standalone_lut_type_face_to_neighface[el->type.to_ulong ()][face]; return element_is_inside_root (neighbor); } } @@ -1071,8 +1075,8 @@ struct t8_standalone_scheme int facenormal_dim, sign; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - sign = t8_sele_lut_type_face_to_sign[el->type.to_ulong ()][face]; - facenormal_dim = t8_sele_lut_type_face_to_facenormal_dim[el->type.to_ulong ()][face]; + sign = t8_standalone_lut_type_face_to_sign[el->type.to_ulong ()][face]; + facenormal_dim = t8_standalone_lut_type_face_to_facenormal_dim[el->type.to_ulong ()][face]; T8_ASSERT (facenormal_dim != -1); } else { @@ -1092,13 +1096,10 @@ struct t8_standalone_scheme neighbor->type.flip (ieq); /*ASSERT that flip is in correct direction */ } } - } - - if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - *neigh_face = face ^ 1; + *neigh_face = t8_standalone_lut_type_face_to_neighface[el->type.to_ulong ()][face]; } else { - *neigh_face = t8_sele_lut_type_face_to_neighface[el->type.to_ulong ()][face]; + *neigh_face = face ^ 1; } T8_ASSERT (element_is_valid ((t8_element_t *) neighbor)); @@ -1155,7 +1156,7 @@ struct t8_standalone_scheme element_extrude_face ([[maybe_unused]] const t8_element_t *face, [[maybe_unused]] t8_element_t *elem, [[maybe_unused]] const int root_face, [[maybe_unused]] const t8_scheme *scheme) noexcept { - const t8_eclass_t TFaceEclass = get_face_eclass (); + const t8_eclass_t TFaceEclass = get_root_face_eclass (root_face); T8_ASSERT (0 <= root_face && root_face < T8_ELEMENT_NUM_FACES[TEclass]); switch (TFaceEclass) { case T8_ECLASS_ZERO: @@ -1199,7 +1200,7 @@ struct t8_standalone_scheme T8_ASSERT (element_is_valid (elem)); T8_ASSERT (0 <= face && face < T8_ELEMENT_NUM_FACES[TEclass]); const int root_face = element_get_tree_face (elem, face); - const t8_eclass_t TFaceEclass = get_face_eclass (); + const t8_eclass_t TFaceEclass = get_root_face_eclass (root_face); switch (TFaceEclass) { case T8_ECLASS_VERTEX: @@ -1995,7 +1996,7 @@ struct t8_standalone_scheme return 0; } else { - return t8_sele_lut_face_internal[elem->type.to_ulong ()][face]; + return t8_standalone_lut_face_internal[elem->type.to_ulong ()][face]; } } @@ -2013,7 +2014,7 @@ struct t8_standalone_scheme return face / 2; } else { - return t8_sele_lut_type_face_to_facenormal_dim[elem->type.to_ulong ()][face]; + return t8_standalone_lut_type_face_to_facenormal_dim[elem->type.to_ulong ()][face]; } } /** Given a face of an element that is also a hypercube face, determine if it is the boundary x_i == 1. @@ -2030,7 +2031,7 @@ struct t8_standalone_scheme return face % 2; } else { - return t8_sele_lut_type_face_to_is_1_boundary[elem->type.to_ulong ()][face]; + return t8_standalone_lut_type_face_to_is_1_boundary[elem->type.to_ulong ()][face]; } } @@ -2046,7 +2047,8 @@ struct t8_standalone_scheme } else { /* Get root element or type*/ - SC_ABORT ("Only implemented for hypercubes.\n"); + int root_type = 0; //TODO: Make other root_types possible + return t8_standalone_lut_type_face_to_is_1_boundary[root_type][root_face]; } } @@ -2055,7 +2057,7 @@ struct t8_standalone_scheme * Note: Only implemented for hypercubes */ static constexpr t8_eclass_t - get_face_eclass () noexcept + get_root_face_eclass (const int root_face) noexcept { switch (TEclass) { case T8_ECLASS_VERTEX: @@ -2069,7 +2071,7 @@ struct t8_standalone_scheme return T8_ECLASS_QUAD; default: if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - return t8_sele_lut_rootface_to_eclass[root_face]; + return t8_standalone_lut_rootface_to_eclass[root_face]; } return T8_ECLASS_INVALID; } @@ -2120,9 +2122,9 @@ struct t8_standalone_scheme } if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - int ifaceeq = t8_sele_lut_rootface_eq_to_faceeq[root_face][ieq]; + int ifaceeq = t8_standalone_lut_rootface_eq_to_faceeq[root_face][ieq]; if (ifaceeq != -1) { - boundary->type[ifaceeq] = elem->type[ieq]; + boundary->type[ifaceeq] = el->type[ieq]; } } T8_ASSERT (t8_standalone_scheme::element_is_valid ((t8_element_t *) boundary)); @@ -2191,24 +2193,24 @@ struct t8_standalone_scheme } else { t8_element_type root_type = 0; - elem->type = root_type; + el->type = root_type; for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - int ifaceeq = t8_sele_lut_rootface_eq_to_faceeq[root_face][ieq]; + int ifaceeq = t8_standalone_lut_rootface_eq_to_faceeq[root_face][ieq]; if (ifaceeq != -1) { - elem->type[ieq] = face->type[ifaceeq]; + el->type[ieq] = face->type[ifaceeq]; } } /** Set those typebits, that are connected to the face_normaldim of root_face*/ for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - int facenormal_dim = t8_sele_lut_type_face_to_facenormal_dim[root_type.to_ulong ()][root_face]; + int facenormal_dim = t8_standalone_lut_type_face_to_facenormal_dim[root_type.to_ulong ()][root_face]; if (t8_type_edge_equations[ieq][0] == facenormal_dim) { - elem->type[ieq] = !t8_sele_lut_type_face_to_is_1_boundary[root_type.to_ulong ()][root_face]; + el->type[ieq] = !t8_standalone_lut_type_face_to_is_1_boundary[root_type.to_ulong ()][root_face]; } else if (t8_type_edge_equations[ieq][1] == facenormal_dim) { - elem->type[ieq] = t8_sele_lut_type_face_to_is_1_boundary[root_type.to_ulong ()][root_face]; + el->type[ieq] = t8_standalone_lut_type_face_to_is_1_boundary[root_type.to_ulong ()][root_face]; } } - return t8_sele_lut_type_rootface_to_face[elem->type.to_ulong ()][root_face]; + return t8_standalone_lut_type_rootface_to_face[el->type.to_ulong ()][root_face]; } } @@ -2251,7 +2253,7 @@ struct t8_standalone_scheme } } else { - return t8_sele_lut_rootface_dim_to_facedim[root_face][idim]; + return t8_standalone_lut_rootface_dim_to_facedim[root_face][idim]; } } From b6c665d54d1ebec0cd8c92c54bed266813be9d5d Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Tue, 15 Apr 2025 16:38:55 +0200 Subject: [PATCH 06/37] fix type functionality --- .../t8_standalone_implementation.hxx | 93 +++++++++++++------ 1 file changed, 66 insertions(+), 27 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index 4e1dd65ced..9ca849ea4a 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -274,6 +274,7 @@ struct t8_standalone_scheme { T8_ASSERT (element_is_valid (elem)); T8_ASSERT (0 <= face && face < T8_ELEMENT_NUM_FACES[TEclass]); + t8_standalone_element *el = (t8_standalone_element *) elem; switch (TEclass) { case T8_ECLASS_VERTEX: SC_ABORT ("Vertices do not have faces.\n"); @@ -281,8 +282,29 @@ struct t8_standalone_scheme return T8_ECLASS_VERTEX; case T8_ECLASS_QUAD: return T8_ECLASS_LINE; + case T8_ECLASS_TRIANGLE: + return T8_ECLASS_LINE; case T8_ECLASS_HEX: return T8_ECLASS_QUAD; + case T8_ECLASS_TET: + return T8_ECLASS_TRIANGLE; + case T8_ECLASS_PRISM: + if (face <= 2) { + return T8_ECLASS_QUAD; + } + else { + return T8_ECLASS_TRIANGLE; + } + case T8_ECLASS_PYRAMID: + if (el->type[0] != el->type[1]) { + return T8_ECLASS_TRIANGLE; + } + else { + if (face == 0) // TODO: Check + return T8_ECLASS_QUAD; + else + return T8_ECLASS_TRIANGLE; + } default: SC_ABORT ("This function is not implemented yet.\n"); } @@ -468,7 +490,7 @@ struct t8_standalone_scheme /* Compute the cube id and shift the coordinates accordingly */ t8_cube_id cube_id; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - cube_id = t8_element_type_cubeid_to_Iloc[el->type.to_ulong ()][childid]; + cube_id = t8_element_type_Iloc_to_childcubeid[el->type.to_ulong ()][childid]; c->type = t8_element_type_Iloc_to_childtype[el->type.to_ulong ()][childid]; } else { @@ -871,7 +893,14 @@ struct t8_standalone_scheme } std::copy (el->coords.begin (), el->coords.end (), first_descendant->coords.begin ()); - const bool face_is_1_boundary = face % 2; + int face_is_1_boundary; + + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + face_is_1_boundary = face % 2; + } + else { + face_is_1_boundary = t8_standalone_lut_type_face_to_is_1_boundary[el->type.to_ulong ()][face]; + } if (face_is_1_boundary) { //the face is a xi=1 boundary int facenormal_dim; @@ -1088,6 +1117,7 @@ struct t8_standalone_scheme const t8_element_coord length = element_get_len (el->level); neighbor->coords[facenormal_dim] += length * sign; + /**Adapt typebits*/ if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { for (size_t ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { /**For all neighboring typebits, change typebit*/ @@ -1347,6 +1377,8 @@ struct t8_standalone_scheme const t8_child_id child_id = element_get_child_id ((const t8_element_t *) elem); const int num_siblings = element_get_num_siblings ((const t8_element_t *) elem); + t8_debugf ("child_id: %i\n", child_id); + t8_debugf ("num_siblings: %i\n", num_siblings); T8_ASSERT (0 <= child_id && child_id < num_siblings); /* If the element is the last child of the parent, we need to go to the parent's successor (go to a coarser level)*/ if (child_id == num_siblings - 1) { @@ -1392,7 +1424,7 @@ struct t8_standalone_scheme * is the root (level 0) element. * * This is a convenience function, and can be implemented via - * \ref t8_element_count_leaves. + * \ref element_count_leaves. */ static constexpr t8_gloidx_t count_leaves_from_root (const t8_element_level level) noexcept @@ -1648,10 +1680,9 @@ struct t8_standalone_scheme for (int i = 0; i < T8_ELEMENT_DIM[TEclass]; i++) { t8_debugf ("x_%i: %i \n", i, el->coords[i]); } - /** for (int e = 0; e < T8_ELEMENT_NUM_EQUATIONS[TEclass]; e++) { - * t8_debugf ("t_%i: %i \n", e, el->type[e]); - *} - * ToDo-Type */ + for (int e = 0; e < T8_ELEMENT_NUM_EQUATIONS[TEclass]; e++) { + t8_debugf ("t_%i: %i \n", e, el->type[e]); + } } static constexpr void @@ -1692,6 +1723,10 @@ struct t8_standalone_scheme } mpiret = sc_MPI_Pack (&els[ielem]->level, 1, sc_MPI_INT8_T, send_buffer, buffer_size, position, comm); SC_CHECK_MPI (mpiret); + + int8_t type = els[ielem]->type.to_ulong (); + mpiret = sc_MPI_Pack (&type, 1, sc_MPI_INT8_T, send_buffer, buffer_size, position, comm); + SC_CHECK_MPI (mpiret); } } @@ -1712,10 +1747,10 @@ struct t8_standalone_scheme SC_CHECK_MPI (mpiret); singlesize += T8_ELEMENT_DIM[TEclass] * datasize; - /* level */ + /* level & type */ mpiret = sc_MPI_Pack_size (1, sc_MPI_INT8_T, comm, &datasize); SC_CHECK_MPI (mpiret); - singlesize += datasize; + singlesize += 2 * datasize; *pack_size = count * singlesize; } @@ -1742,6 +1777,11 @@ struct t8_standalone_scheme } mpiret = sc_MPI_Unpack (recvbuf, buffer_size, position, &(els[ielem]->level), 1, sc_MPI_INT8_T, comm); SC_CHECK_MPI (mpiret); + + int8_t type; + mpiret = sc_MPI_Unpack (recvbuf, buffer_size, position, &type, 1, sc_MPI_INT8_T, comm); + SC_CHECK_MPI (mpiret); + els[ielem]->type = type; } } @@ -1974,7 +2014,8 @@ struct t8_standalone_scheme /**Check that we are in the correct cube*/ if (std::all_of (ancestor.coords.begin (), ancestor.coords.end (), [] (int coord) { return coord == 0; })) { - return 1; + return ancestor.type == 0; + //TODO: root type } else { return 0; @@ -2054,7 +2095,6 @@ struct t8_standalone_scheme /** Get the eclass of the face for the element eclass * \return The eclass of the face. - * Note: Only implemented for hypercubes */ static constexpr t8_eclass_t get_root_face_eclass (const int root_face) noexcept @@ -2431,9 +2471,8 @@ t8_standalone_scheme::element_transform_face ([[maybe_unused t8_element_coord h = element_get_len (el1->level); // copy elem1 in tmp so that results can directly be set in elem2 - t8_element_t *temp; - element_copy (elem1, temp); - t8_standalone_element *tmp = (t8_standalone_element *) temp; + t8_standalone_element tmp; + element_copy (elem1, (t8_element_t *) &tmp); /* * The corners of the triangle are enumerated like this @@ -2451,10 +2490,10 @@ t8_standalone_scheme::element_transform_face ([[maybe_unused /* The tree faces have the same topological orientation, and * thus we have to perform a coordinate switch. */ if (el1->type == 0) { - tmp->coords[1] = el1->coords[0] - el1->coords[1]; + tmp.coords[1] = el1->coords[0] - el1->coords[1]; } else { - tmp->coords[1] = el1->coords[0] - el1->coords[1] - h; + tmp.coords[1] = el1->coords[0] - el1->coords[1] - h; } } @@ -2468,29 +2507,29 @@ t8_standalone_scheme::element_transform_face ([[maybe_unused orientation = 3 - orientation; } - el2->level = tmp->level; - el2->type = tmp->type; + el2->level = tmp.level; + el2->type = tmp.type; switch (orientation) { case 0: - element_copy ((t8_element_t *) tmp, (t8_element_t *) el2); + element_copy ((t8_element_t *) &tmp, (t8_element_t *) el2); break; case 1: - el2->coords[0] = get_root_len () - h - tmp->coords[1]; - if (tmp->type == 0) { - el2->coords[1] = tmp->coords[0] - tmp->coords[1]; + el2->coords[0] = get_root_len () - h - tmp.coords[1]; + if (tmp.type == 0) { + el2->coords[1] = tmp.coords[0] - tmp.coords[1]; } else { - el2->coords[1] = tmp->coords[0] - tmp->coords[1] - h; + el2->coords[1] = tmp.coords[0] - tmp.coords[1] - h; } break; case 2: - if (tmp->type == 0) { - el2->coords[0] = get_root_len () - h + tmp->coords[1] - tmp->coords[0]; + if (tmp.type == 0) { + el2->coords[0] = get_root_len () - h + tmp.coords[1] - tmp.coords[0]; } else { - el2->coords[0] = get_root_len () + tmp->coords[1] - tmp->coords[0]; + el2->coords[0] = get_root_len () + tmp.coords[1] - tmp.coords[0]; } - el2->coords[1] = get_root_len () - h - tmp->coords[0]; + el2->coords[1] = get_root_len () - h - tmp.coords[0]; break; default: SC_ABORT_NOT_REACHED (); From 0993001b758915f1ecc7821bf1e8e36848e66833 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 16 Apr 2025 16:28:38 +0200 Subject: [PATCH 07/37] rebuild count_leaves test --- test/CMakeLists.txt | 45 +++++++++-------- .../t8_gtest_default_pyramid_count_leaves.cxx | 50 +++++++++++++++++++ .../t8_gtest_element_count_leaves.cxx | 49 +++++++++++++++--- 3 files changed, 115 insertions(+), 29 deletions(-) create mode 100644 test/t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b638ffb235..4f46a06769 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -125,28 +125,29 @@ add_t8_test( NAME t8_gtest_point_inside_serial SOURCES t8_g add_t8_test( NAME t8_gtest_vtk_reader_parallel SOURCES t8_gtest_main.cxx t8_IO/t8_gtest_vtk_reader.cxx ) add_t8_test( NAME t8_gtest_vtk_writer_parallel SOURCES t8_gtest_main.cxx t8_IO/t8_gtest_vtk_writer.cxx ) -add_t8_test( NAME t8_gtest_nca_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_nca.cxx ) -add_t8_test( NAME t8_gtest_pyra_connectivity_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_pyra_connectivity.cxx ) -add_t8_test( NAME t8_gtest_face_neigh_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_neigh.cxx ) -add_t8_test( NAME t8_gtest_get_linear_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_get_linear_id.cxx ) -add_t8_test( NAME t8_gtest_ancestor_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_ancestor.cxx ) -add_t8_test( NAME t8_gtest_ancestor_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_ancestor_id.cxx ) -add_t8_test( NAME t8_gtest_element_count_leaves_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_element_count_leaves.cxx ) -add_t8_test( NAME t8_gtest_element_ref_coords_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_element_ref_coords.cxx ) -add_t8_test( NAME t8_gtest_descendant_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_descendant.cxx ) -add_t8_test( NAME t8_gtest_find_parent_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_find_parent.cxx ) -add_t8_test( NAME t8_gtest_equal_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_equal.cxx ) -add_t8_test( NAME t8_gtest_successor_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_successor.cxx ) -add_t8_test( NAME t8_gtest_boundary_extrude_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_boundary_extrude.cxx ) -add_t8_test( NAME t8_gtest_face_descendant_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_descendant.cxx ) -add_t8_test( NAME t8_gtest_default_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default.cxx ) -add_t8_test( NAME t8_gtest_child_parent_face_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_child_parent_face.cxx ) -add_t8_test( NAME t8_gtest_pack_unpack_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_pack_unpack.cxx ) -add_t8_test( NAME t8_gtest_root_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_root.cxx ) -add_t8_test( NAME t8_gtest_scheme_consistency_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_scheme_consistency.cxx ) -add_t8_test( NAME t8_gtest_input_equal_output_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_input_equal_output.cxx ) -add_t8_test( NAME t8_gtest_face_corner_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_corner.cxx ) -add_t8_test( NAME t8_gtest_set_linear_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_set_linear_id.cxx ) +add_t8_test( NAME t8_gtest_nca_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_nca.cxx ) +add_t8_test( NAME t8_gtest_pyra_connectivity_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_pyra_connectivity.cxx ) +add_t8_test( NAME t8_gtest_face_neigh_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_neigh.cxx ) +add_t8_test( NAME t8_gtest_get_linear_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_get_linear_id.cxx ) +add_t8_test( NAME t8_gtest_ancestor_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_ancestor.cxx ) +add_t8_test( NAME t8_gtest_ancestor_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_ancestor_id.cxx ) +add_t8_test( NAME t8_gtest_element_count_leaves_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_element_count_leaves.cxx ) +add_t8_test( NAME t8_gtest_element_ref_coords_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_element_ref_coords.cxx ) +add_t8_test( NAME t8_gtest_descendant_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_descendant.cxx ) +add_t8_test( NAME t8_gtest_find_parent_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_find_parent.cxx ) +add_t8_test( NAME t8_gtest_equal_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_equal.cxx ) +add_t8_test( NAME t8_gtest_successor_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_successor.cxx ) +add_t8_test( NAME t8_gtest_boundary_extrude_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_boundary_extrude.cxx ) +add_t8_test( NAME t8_gtest_face_descendant_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_descendant.cxx ) +add_t8_test( NAME t8_gtest_default_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default.cxx ) +add_t8_test( NAME t8_gtest_child_parent_face_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_child_parent_face.cxx ) +add_t8_test( NAME t8_gtest_pack_unpack_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_pack_unpack.cxx ) +add_t8_test( NAME t8_gtest_root_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_root.cxx ) +add_t8_test( NAME t8_gtest_scheme_consistency_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_scheme_consistency.cxx ) +add_t8_test( NAME t8_gtest_input_equal_output_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_input_equal_output.cxx ) +add_t8_test( NAME t8_gtest_face_corner_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_corner.cxx ) +add_t8_test( NAME t8_gtest_set_linear_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_set_linear_id.cxx ) +add_t8_test( NAME t8_gtest_default_pyramid_count_leaves_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx ) if( T8CODE_BUILD_FORTRAN_INTERFACE AND T8CODE_ENABLE_MPI ) add_t8_test( NAME t8_test_fortran_mpi_interface_init_parallel SOURCES api/t8_fortran_interface/t8_test_mpi_init.f90 ) diff --git a/test/t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx b/test/t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx new file mode 100644 index 0000000000..22820a96aa --- /dev/null +++ b/test/t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx @@ -0,0 +1,50 @@ +/* + 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. +*/ + +#include +#include +#include + +TEST (class_element_leaves, test_default_pyramid_count_leaves_root) +{ + + const t8_scheme *scheme; + scheme = t8_scheme_new_default (); + t8_eclass_t eclass = T8_ECLASS_PYRAMID; + + const int maxlevel = scheme->get_maxlevel (eclass); + t8_gloidx_t compare_value = 1; + t8_gloidx_t sum1 = 1; + t8_gloidx_t sum2 = 1; + + for (int level = 0; level <= maxlevel; ++level) { + const t8_gloidx_t leaf_count = scheme->count_leaves_from_root (eclass, level); + ASSERT_EQ (leaf_count, compare_value) + << "Incorrect leaf count " << leaf_count << " at eclass " << t8_eclass_to_string[eclass] << " and level " << level + << " (expecting " << compare_value << ")"; + //Calculate the copare value for the default pyramid + sum1 *= 8; + sum2 *= 6; + compare_value = 2 * sum1 - sum2; + } + scheme->unref (); +} diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index 9e74fea9bb..9d623e0c99 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -43,22 +43,57 @@ class class_element_leaves: public testing::TestWithParam (GetParam ()); eclass = scheme->get_eclass_scheme_eclass (eclass); + + scheme->element_new (eclass, 1, &element); + scheme->element_new (eclass, 1, &child); + scheme->element_new (eclass, 1, &parent); } void TearDown () override { + scheme->element_destroy (eclass, 1, &element); + scheme->element_destroy (eclass, 1, &child); + scheme->element_destroy (eclass, 1, &parent); scheme->unref (); } + t8_element_t *element; + t8_element_t *child; + t8_element_t *parent; const t8_scheme *scheme; t8_eclass_t eclass; }; +t8_gloidx_t +helper (t8_element_t *child, const t8_scheme *scheme, t8_eclass_t eclass, int level) +{ + t8_gloidx_t num_leaves = 0; + if (scheme->element_get_level (eclass, child) < level) { + int num_children = scheme->element_get_num_children (eclass, child); + for (int ichild = 0; ichild < num_children; ichild++) { + scheme->element_get_child (eclass, child, ichild, child); + num_leaves = num_leaves + helper (child, scheme, eclass, level); + scheme->element_get_parent (eclass, child, child); + } + } + else { + return scheme->element_get_num_children (eclass, child); + } + return num_leaves; +} + TEST_P (class_element_leaves, test_element_count_leaves_root) { +#if T8CODE_TEST_LEVEL >= 1 + const int maxlevel = 4; +#else const int maxlevel = scheme->get_maxlevel (eclass); + ; +#endif t8_gloidx_t compare_value = 1; + t8_gloidx_t test_value = 1; t8_gloidx_t sum1 = 1; t8_gloidx_t sum2 = 1; + t8_gloidx_t num_leaves = 0; for (int level = 0; level <= maxlevel; ++level) { const t8_gloidx_t leaf_count = scheme->count_leaves_from_root (eclass, level); @@ -66,13 +101,13 @@ TEST_P (class_element_leaves, test_element_count_leaves_root) << "Incorrect leaf count " << leaf_count << " at eclass " << t8_eclass_to_string[eclass] << " and level " << level << " (expecting " << compare_value << ")"; /* Multiply the compare_value with 2^dim (= number of children per element) */ - if (eclass == T8_ECLASS_PYRAMID) { - sum1 *= 8; - sum2 *= 6; - compare_value = 2 * sum1 - sum2; - } - else { - compare_value *= 1 << t8_eclass_to_dimension[eclass]; + + scheme->element_copy (eclass, element, child); + t8_gloidx_t num_leaves = helper (child, scheme, eclass, level); + compare_value = num_leaves; + if (!scheme->refines_irregular (eclass)) { + test_value *= 1 << t8_eclass_to_dimension[eclass]; + EXPECT_EQ (test_value, compare_value); } } } From 35eaa8f79382c6461c350e0df58746347fcc56cd Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 23 Apr 2025 09:22:09 +0200 Subject: [PATCH 08/37] add lut for face-corner and corner-face --- .../t8_standalone/t8_standalone_elements.hxx | 10 ++ .../t8_standalone_implementation.hxx | 28 ++++- .../t8_standalone_lut_prism.hxx | 38 +++++++ .../t8_standalone_lut_pyra.hxx | 61 ++++++++++ .../t8_standalone_lut_tet.hxx | 104 ++++++++++++++++++ .../t8_standalone_lut_triangle.hxx | 28 +++++ 6 files changed, 265 insertions(+), 4 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx index 441e14c476..3ece23d274 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx @@ -36,6 +36,8 @@ constexpr uint8_t T8_ELEMENT_NUM_CHILDREN[T8_ECLASS_COUNT] = { 1, 2, 4, 4, 8, 8, constexpr uint8_t T8_ELEMENT_NUM_CORNERS[T8_ECLASS_COUNT] = { 1, 2, 4, 3, 8, 4, 6, 5 }; constexpr uint8_t T8_ELEMENT_NUM_FACES[T8_ECLASS_COUNT] = { 0, 2, 4, 3, 6, 4, 5, 5 }; constexpr uint8_t T8_ELEMENT_MAX_NUM_FACECHILDREN[T8_ECLASS_COUNT] = { 0, 1, 2, 2, 4, 4, 4, 4 }; +constexpr uint8_t T8_ELEMENT_NUM_CORNER_FACES[T8_ECLASS_COUNT] = { 0, 1, 2, 2, 3, 3, 3, 4 }; +constexpr uint8_t T8_ELEMENT_NUM_FACE_CORNERS[T8_ECLASS_COUNT] = { 0, 2, 2, 2, 4, 3, 4, 4 }; constexpr uint8_t T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_COUNT] = { 0, 0, 0, 1, 0, 3, 1, 2 }; @@ -108,6 +110,14 @@ constexpr int8_t t8_standalone_lut_type_rootface_to_face[1 << T8_ELEMENT_NUM_EQU template constexpr t8_eclass t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[TEclass]]; +template +constexpr int8_t t8_standalone_lut_cornerface[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_CORNERS[TEclass]] + [T8_ELEMENT_NUM_CORNER_FACES[TEclass]]; + +template +constexpr int8_t t8_standalone_lut_facecorner[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_FACES[TEclass]] + [T8_ELEMENT_NUM_FACE_CORNERS[TEclass]]; + #include "t8_standalone_lut/t8_standalone_lut_triangle.hxx" #include "t8_standalone_lut/t8_standalone_lut_prism.hxx" #include "t8_standalone_lut/t8_standalone_lut_pyra.hxx" diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index 9ca849ea4a..0c7a394213 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -235,9 +235,19 @@ struct t8_standalone_scheme T8_ASSERT (element_is_valid (element)); T8_ASSERT (0 <= face && face < T8_ELEMENT_NUM_FACES[TEclass]); T8_ASSERT (0 <= corner && corner < T8_ELEMENT_NUM_CORNERS[TEclass]); - const int face_sign = face % 2; - const int face_dim = face / 2; - return get_hypercube_face_corner_index (face_dim, face_sign, corner); + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + const int face_sign = face % 2; + const int face_dim = face / 2; + t8_debugf ("this will be the wrong answer:\n"); + return get_hypercube_face_corner_index (face_dim, face_sign, corner); + } + else { + t8_standalone_element *el = (t8_standalone_element *) element; + t8_debugf ("face: %i, corner: %i \n", face, corner); + t8_debugf ("eclass: %i \n", TEclass); + t8_debugf ("return_value: %i \n", t8_standalone_lut_facecorner[1][face][corner]); + return t8_standalone_lut_facecorner[el->type.to_ulong ()][face][corner]; + } } /** Return the face numbers of the faces sharing an element's corner. @@ -258,7 +268,15 @@ struct t8_standalone_scheme T8_ASSERT (element_is_valid (element)); T8_ASSERT (0 <= face && face < T8_ELEMENT_NUM_FACES[TEclass]); T8_ASSERT (0 <= corner && corner < T8_ELEMENT_NUM_CORNERS[TEclass]); - return (corner >> face & 1) + 2 * face; + T8_ASSERTF (t8_standalone_lut_facecorner[0][1][1] == 2, "LUT falsch!"); + + if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + return (corner >> face & 1) + 2 * face; + } + else { + t8_standalone_element *el = (t8_standalone_element *) element; + return t8_standalone_lut_cornerface[el->type.to_ulong ()][corner][face]; + } } /** Compute the shape of the face of an element. @@ -1490,6 +1508,8 @@ struct t8_standalone_scheme } else { int coords_int[T8_ELEMENT_DIM[TEclass]]; + t8_debugf ("vertex: %i\n", vertex); + t8_debugf ("T8_ELEMENT_NUM_CORNERS[TEclass]: %i\n", T8_ELEMENT_NUM_CORNERS[TEclass]); T8_ASSERT (0 <= vertex && vertex < T8_ELEMENT_NUM_CORNERS[TEclass]); element_compute_coords (el, vertex, coords_int); for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx index 7e5beb96f1..58c065d3f2 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx @@ -215,6 +215,44 @@ constexpr int8_t t8_standalone_lut_type_rootface_to_face[1< +constexpr int8_t t8_standalone_lut_cornerface[1< +constexpr int8_t t8_standalone_lut_facecorner[1< constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]]={ T8_ECLASS_QUAD, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx index c7c3fea4ac..3687ead4a4 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx @@ -325,6 +325,67 @@ constexpr int8_t t8_standalone_lut_type_rootface_to_face[1< +constexpr int8_t t8_standalone_lut_cornerface[1< +constexpr int8_t t8_standalone_lut_facecorner[1< constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]]={ T8_ECLASS_TRIANGLE, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx index d6ffd7a813..e5c01ecc58 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx @@ -485,6 +485,110 @@ constexpr int8_t t8_standalone_lut_type_rootface_to_face[1< +constexpr int8_t t8_standalone_lut_cornerface[1< +constexpr int8_t t8_standalone_lut_facecorner[1< constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]]={ T8_ECLASS_TRIANGLE, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx index 855c152d81..535af17872 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx @@ -188,6 +188,34 @@ constexpr int8_t t8_standalone_lut_type_rootface_to_face[1<< {-1,-1,-1} }; +template<> +constexpr int8_t t8_standalone_lut_cornerface[1< +constexpr int8_t t8_standalone_lut_facecorner[1< constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]]={ T8_ECLASS_LINE, From a6cba7451368c6ac1c55bd699664e2fa14e211da Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 25 Apr 2025 11:10:30 +0200 Subject: [PATCH 09/37] add calculation of standalone pyramid contro volume --- test/t8_forest/t8_gtest_element_volume.cxx | 31 ++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/test/t8_forest/t8_gtest_element_volume.cxx b/test/t8_forest/t8_gtest_element_volume.cxx index 81cbb27b7e..8ff9e2245b 100644 --- a/test/t8_forest/t8_gtest_element_volume.cxx +++ b/test/t8_forest/t8_gtest_element_volume.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 classes in parallel. - Copyright (C) 2015 the developers + Copyright (C) 2025 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 @@ -64,29 +64,38 @@ class t8_forest_volume: public testing::TestWithParampyramid.level) * 3); - /* Ancestors switch the shape. A tetrahedron has a 1/16th of its parents volume. - * For all levels we already divided the control-volume by 8, hence we - * divide it by 2 once. */ - if (pyra->switch_shape_at_level > 0) { - control_volume /= 2; + int level = scheme->element_get_level (eclass, pyra); + for (int ilvl = level; ilvl > 0; ilvl--) { + t8_element_shape_t shape = scheme->element_get_shape (eclass, pyra); + scheme->element_get_parent (eclass, pyra, pyra); + t8_element_shape_t parent_shape = scheme->element_get_shape (eclass, pyra); + control_volume = control_volume * shape_factor[shape][parent_shape]; + int test_level = scheme->element_get_level (eclass, pyra); } return control_volume; @@ -109,7 +118,7 @@ TEST_P (t8_forest_volume, volume_check) const t8_element_t *element = t8_forest_get_element_in_tree (forest, itree, ielement); const double volume = t8_forest_element_volume (forest, itree, element); if (eclass == T8_ECLASS_PYRAMID) { - const double shape_volume = pyramid_control_volume ((t8_dpyramid_t *) element); + const double shape_volume = pyramid_control_volume ((t8_element_t *) element, eclass, scheme); EXPECT_NEAR (volume, shape_volume, T8_PRECISION_SQRT_EPS); } else { From 3b9b087cdaea792cbaf399183003cac337f1e925 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 25 Apr 2025 11:11:20 +0200 Subject: [PATCH 10/37] new name for helper function --- test/t8_schemes/t8_gtest_element_count_leaves.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index 9d623e0c99..551fb06ae4 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -64,14 +64,14 @@ class class_element_leaves: public testing::TestWithParamelement_get_level (eclass, child) < level) { int num_children = scheme->element_get_num_children (eclass, child); for (int ichild = 0; ichild < num_children; ichild++) { scheme->element_get_child (eclass, child, ichild, child); - num_leaves = num_leaves + helper (child, scheme, eclass, level); + num_leaves = num_leaves + count_leaves_recursive (child, scheme, eclass, level); scheme->element_get_parent (eclass, child, child); } } @@ -103,7 +103,7 @@ TEST_P (class_element_leaves, test_element_count_leaves_root) /* Multiply the compare_value with 2^dim (= number of children per element) */ scheme->element_copy (eclass, element, child); - t8_gloidx_t num_leaves = helper (child, scheme, eclass, level); + t8_gloidx_t num_leaves = count_leaves_recursive (child, scheme, eclass, level); compare_value = num_leaves; if (!scheme->refines_irregular (eclass)) { test_value *= 1 << t8_eclass_to_dimension[eclass]; From 40ffd203e0f9116ba333e4e71c6b7f8d70e855b8 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 25 Apr 2025 16:30:47 +0200 Subject: [PATCH 11/37] add new test for reference coords --- test/CMakeLists.txt | 1 + test/t8_schemes/t8_gtest_reference_coords.cxx | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 test/t8_schemes/t8_gtest_reference_coords.cxx diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4f46a06769..4c3a52e6c6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -148,6 +148,7 @@ add_t8_test( NAME t8_gtest_input_equal_output_serial SOURCES add_t8_test( NAME t8_gtest_face_corner_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_corner.cxx ) add_t8_test( NAME t8_gtest_set_linear_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_set_linear_id.cxx ) add_t8_test( NAME t8_gtest_default_pyramid_count_leaves_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx ) +add_t8_test( NAME t8_gtest_reference_coords_serianl SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_reference_coords.cxx ) if( T8CODE_BUILD_FORTRAN_INTERFACE AND T8CODE_ENABLE_MPI ) add_t8_test( NAME t8_test_fortran_mpi_interface_init_parallel SOURCES api/t8_fortran_interface/t8_test_mpi_init.f90 ) diff --git a/test/t8_schemes/t8_gtest_reference_coords.cxx b/test/t8_schemes/t8_gtest_reference_coords.cxx new file mode 100644 index 0000000000..bdcdd6c9c5 --- /dev/null +++ b/test/t8_schemes/t8_gtest_reference_coords.cxx @@ -0,0 +1,82 @@ +/* + 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) 2025 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. +*/ + +#include +#include +#include +#include +#include +#include "t8_gtest_dfs_base.hxx" + +/** This test is used to test the corner_face and face_corner scheme functions. + * The first test gets the corners of all faces of an element and checks if the reverse function can get the correct face of the corner. + * The second test does the same but in reverse order. + */ +class class_reference_coords_test: public TestDFS { + + void + check_element () override + { + for (int ivertex = 0; ivertex < scheme->element_get_num_corners (eclass, element); ivertex++) { + double vertex_coords[3]; + double reference_coords[3]; + scheme->element_debug_print (eclass, element); + scheme->element_get_vertex_reference_coords (eclass, element, ivertex, vertex_coords); + t8_debugf ("vertex_coords: %lf, %lf, %lf \n", vertex_coords[0], vertex_coords[1], vertex_coords[2]); + t8_element_shape_t shape = scheme->element_get_shape (eclass, element); + scheme->element_get_reference_coords (eclass, element, t8_element_corner_ref_coords[shape][ivertex], 1, + reference_coords); + t8_debugf ("reference_lut: %lf, %lf, %lf \n", t8_element_corner_ref_coords[shape][ivertex][0], + t8_element_corner_ref_coords[shape][ivertex][1], t8_element_corner_ref_coords[shape][ivertex][2]); + t8_debugf ("reference_coords: %lf, %lf, %lf \n", reference_coords[0], reference_coords[1], reference_coords[2]); + + for (int idim = 0; idim < T8_ELEMENT_DIM[eclass]; idim++) { + EXPECT_NEAR (vertex_coords[idim], reference_coords[idim], T8_PRECISION_SQRT_EPS); + } + } + } + + protected: + void + SetUp () override + { + dfs_test_setup (); + } + void + TearDown () override + { + /* Destroy DFS test */ + dfs_test_teardown (); + } +}; + +TEST_P (class_reference_coords_test, test_equal_dfs) +{ +#if T8CODE_TEST_LEVEL >= 1 + const int maxlvl = 3; +#else + const int maxlvl = 5; +#endif + check_recursive_dfs_to_max_lvl (maxlvl); +} + +INSTANTIATE_TEST_SUITE_P (t8_gtest_test_all_imps, class_reference_coords_test, AllSchemes, print_all_schemes); From c957d1c938079bc5a062eef9a9b8e63c5ca135cc Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 25 Apr 2025 16:31:22 +0200 Subject: [PATCH 12/37] fix reference coordinate issues --- .../t8_standalone/t8_standalone_elements.hxx | 3 ++ .../t8_standalone_implementation.hxx | 40 ++++++++++++++--- .../t8_standalone_lut_prism.hxx | 15 +++++++ .../t8_standalone_lut_pyra.hxx | 34 ++++++++++++-- .../t8_standalone_lut_tet.hxx | 44 +++++++++++++++++++ .../t8_standalone_lut_triangle.hxx | 29 ++++++++---- 6 files changed, 147 insertions(+), 18 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx index 3ece23d274..202f2b3750 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx @@ -117,6 +117,9 @@ constexpr int8_t t8_standalone_lut_cornerface[1 << T8_ELEMENT_NUM_EQUATIONS[TEcl template constexpr int8_t t8_standalone_lut_facecorner[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_FACES[TEclass]] [T8_ELEMENT_NUM_FACE_CORNERS[TEclass]]; +template +constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_DIM[TEclass]] + [T8_ELEMENT_DIM[TEclass]]; #include "t8_standalone_lut/t8_standalone_lut_triangle.hxx" #include "t8_standalone_lut/t8_standalone_lut_prism.hxx" diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index 0c7a394213..bd0f6c32ef 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -1530,20 +1530,46 @@ struct t8_standalone_scheme element_get_reference_coords (const t8_element_t *elem, const double *ref_coords, const size_t num_coords, double *out_coords) noexcept { + const t8_standalone_element *el = (const t8_standalone_element *) elem; double *current_ref_coords = (double *) ref_coords; double *current_out_coords = out_coords; t8_element_coord length = element_get_len (element_get_level (elem)); - for (size_t coord = 0; coord < num_coords; ++coord) { - for (int dim = 0; dim < T8_ELEMENT_DIM[TEclass]; ++dim) { - current_out_coords[dim] - = ((t8_standalone_element *) elem)->coords[dim] + current_ref_coords[dim] * length; + if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { + double tmp_coords[T8_ELEMENT_DIM[TEclass]] = {}; + for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; ++idim) { + for (int jdim = 0; jdim < T8_ELEMENT_DIM[TEclass]; ++jdim) { + tmp_coords[idim] + += t8_standalone_lut_transform_coords[el->type.to_ulong ()][idim][jdim] * current_ref_coords[jdim]; + } + if (TEclass == T8_ECLASS_PYRAMID && el->type == T8_DPYRAMID_SECOND_PYRA_TYPE) { + tmp_coords[idim] += 1.0; + } + } + + for (size_t coord = 0; coord < num_coords; ++coord) { + for (int dim = 0; dim < T8_ELEMENT_DIM[TEclass]; ++dim) { + current_out_coords[dim] = el->coords[dim] + tmp_coords[dim] * length; + + current_out_coords[dim] /= (double) get_root_len (); + } - current_out_coords[dim] /= (double) get_root_len (); + current_ref_coords += T8_ECLASS_MAX_DIM; + current_out_coords += T8_ELEMENT_DIM[TEclass]; } + } + + else { + for (size_t coord = 0; coord < num_coords; ++coord) { + for (int dim = 0; dim < T8_ELEMENT_DIM[TEclass]; ++dim) { + current_out_coords[dim] = el->coords[dim] + current_ref_coords[dim] * length; - current_ref_coords += T8_ECLASS_MAX_DIM; - current_out_coords += T8_ELEMENT_DIM[TEclass]; + current_out_coords[dim] /= (double) get_root_len (); + } + + current_ref_coords += T8_ECLASS_MAX_DIM; + current_out_coords += T8_ELEMENT_DIM[TEclass]; + } } } diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx index 58c065d3f2..4ee5e2ab98 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx @@ -253,6 +253,21 @@ constexpr int8_t t8_standalone_lut_facecorner[1< +constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} + }, + { + {0, 1, 0}, + {1, 0, 0}, + {0, 0, 1} + } +}; + + template<> constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]]={ T8_ECLASS_QUAD, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx index 3687ead4a4..4996846638 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx @@ -100,10 +100,15 @@ constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT }, { /* PAY ATTENTION TO ORDERING OF ELEMENTS! **/ - {0, 0, 1}, - {1, 0, 1}, - {0, 1, 1}, + // {0, 0, 1}, + // {1, 0, 1}, + // {0, 1, 1}, + // {1, 1, 1}, + // {0, 0, 0} {1, 1, 1}, + {0, 1, 1}, + {1, 0, 1}, + {0, 0, 1}, {0, 0, 0} } }; @@ -383,7 +388,30 @@ constexpr int8_t t8_standalone_lut_facecorner[1< +constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} + }, + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} + }, + { + {0, 1, 0}, + {1, 0, 0}, + {0, 0, 1} + }, + { + {-1, 0, 0}, + {0, -1, 0}, + {0, 0, -1} + } }; template<> diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx index e5c01ecc58..8af11e07f0 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx @@ -589,6 +589,50 @@ constexpr int8_t t8_standalone_lut_facecorner[1< +constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]]={ + { + {1, 0, 0}, + {0, 0, 1}, + {0, 1, 0} + }, + { + {0, 0, 1}, + {1, 0, 0}, + {0, 1, 0} + }, + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} + }, + { + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0} + }, + { + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0} + }, + { + {0, 1, 0}, + {1, 0, 0}, + {0, 0, 1} + }, + { + {0, 0, 1}, + {0, 1, 0}, + {1, 0, 0} + }, + { + {0, 1, 0}, + {0, 0, 1}, + {1, 0, 0} + } +}; + template<> constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]]={ T8_ECLASS_TRIANGLE, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx index 535af17872..f15a703ba7 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx @@ -191,31 +191,44 @@ constexpr int8_t t8_standalone_lut_type_rootface_to_face[1<< template<> constexpr int8_t t8_standalone_lut_cornerface[1< constexpr int8_t t8_standalone_lut_facecorner[1< +constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ + { + {1, 0}, + {0, 1} + }, + { + {0, 1}, + {1, 0} + } +}; + + template<> constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]]={ T8_ECLASS_LINE, From 8b3b0d3b9e5127c330870ba6f1988ed7b8b35601 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 9 May 2025 16:10:25 +0200 Subject: [PATCH 13/37] fix reference coords for standalone scheme --- .../t8_standalone/t8_standalone_elements.hxx | 4 ++ .../t8_standalone_implementation.hxx | 36 +++++++++------ .../t8_standalone_lut_prism.hxx | 13 ++++++ .../t8_standalone_lut_pyra.hxx | 44 ++++++++++++++++--- .../t8_standalone_lut_tet.hxx | 44 +++++++++++++++++++ .../t8_standalone_lut_triangle.hxx | 11 +++++ 6 files changed, 133 insertions(+), 19 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx index 202f2b3750..d28ca0456d 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx @@ -121,6 +121,10 @@ template constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_DIM[TEclass]] [T8_ELEMENT_DIM[TEclass]]; +template +constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_DIM[TEclass]] + [T8_ELEMENT_DIM[TEclass]]; + #include "t8_standalone_lut/t8_standalone_lut_triangle.hxx" #include "t8_standalone_lut/t8_standalone_lut_prism.hxx" #include "t8_standalone_lut/t8_standalone_lut_pyra.hxx" diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index bd0f6c32ef..9b61f831e0 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -238,14 +238,10 @@ struct t8_standalone_scheme if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { const int face_sign = face % 2; const int face_dim = face / 2; - t8_debugf ("this will be the wrong answer:\n"); return get_hypercube_face_corner_index (face_dim, face_sign, corner); } else { t8_standalone_element *el = (t8_standalone_element *) element; - t8_debugf ("face: %i, corner: %i \n", face, corner); - t8_debugf ("eclass: %i \n", TEclass); - t8_debugf ("return_value: %i \n", t8_standalone_lut_facecorner[1][face][corner]); return t8_standalone_lut_facecorner[el->type.to_ulong ()][face][corner]; } } @@ -318,7 +314,7 @@ struct t8_standalone_scheme return T8_ECLASS_TRIANGLE; } else { - if (face == 0) // TODO: Check + if (face == 4) // TODO: Check return T8_ECLASS_QUAD; else return T8_ECLASS_TRIANGLE; @@ -810,7 +806,6 @@ struct t8_standalone_scheme for (int ifacechild = 0; ifacechild < num_children; ifacechild++) { child_indices[ifacechild] = t8_standalone_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][ifacechild]; - // t8_debugf("looked up child index %i for type %i, face %i, ifacechild %i\n", child_indices[ifacechild], elem->type.to_ulong(), face, ifacechild); } } for (int ifacechild = num_children - 1; ifacechild >= 0; ifacechild--) { @@ -1395,8 +1390,6 @@ struct t8_standalone_scheme const t8_child_id child_id = element_get_child_id ((const t8_element_t *) elem); const int num_siblings = element_get_num_siblings ((const t8_element_t *) elem); - t8_debugf ("child_id: %i\n", child_id); - t8_debugf ("num_siblings: %i\n", num_siblings); T8_ASSERT (0 <= child_id && child_id < num_siblings); /* If the element is the last child of the parent, we need to go to the parent's successor (go to a coarser level)*/ if (child_id == num_siblings - 1) { @@ -1508,8 +1501,6 @@ struct t8_standalone_scheme } else { int coords_int[T8_ELEMENT_DIM[TEclass]]; - t8_debugf ("vertex: %i\n", vertex); - t8_debugf ("T8_ELEMENT_NUM_CORNERS[TEclass]: %i\n", T8_ELEMENT_NUM_CORNERS[TEclass]); T8_ASSERT (0 <= vertex && vertex < T8_ELEMENT_NUM_CORNERS[TEclass]); element_compute_coords (el, vertex, coords_int); for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { @@ -1548,12 +1539,22 @@ struct t8_standalone_scheme } for (size_t coord = 0; coord < num_coords; ++coord) { + double tmp_out_coords[T8_ELEMENT_DIM[TEclass]] = {}; for (int dim = 0; dim < T8_ELEMENT_DIM[TEclass]; ++dim) { current_out_coords[dim] = el->coords[dim] + tmp_coords[dim] * length; current_out_coords[dim] /= (double) get_root_len (); } - + for (int dim = 0; dim < T8_ELEMENT_DIM[TEclass]; ++dim) { + for (int jdim = 0; jdim < T8_ELEMENT_DIM[TEclass]; ++jdim) { + tmp_out_coords[dim] + += t8_standalone_lut_backtransform_coords[0][dim][jdim] * current_out_coords[jdim]; + } + } + for (int dim = 0; dim < T8_ELEMENT_DIM[TEclass]; ++dim) { + current_out_coords[dim] = tmp_out_coords[dim]; + } + // current_out_coords = tmp_out_coords; current_ref_coords += T8_ECLASS_MAX_DIM; current_out_coords += T8_ELEMENT_DIM[TEclass]; } @@ -1722,12 +1723,9 @@ struct t8_standalone_scheme const t8_standalone_element *el = (const t8_standalone_element *) elem; - t8_debugf ("level: %i\n", el->level); for (int i = 0; i < T8_ELEMENT_DIM[TEclass]; i++) { - t8_debugf ("x_%i: %i \n", i, el->coords[i]); } for (int e = 0; e < T8_ELEMENT_NUM_EQUATIONS[TEclass]; e++) { - t8_debugf ("t_%i: %i \n", e, el->type[e]); } } @@ -2033,10 +2031,20 @@ struct t8_standalone_scheme if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { t8_standalone_element *el = (t8_standalone_element *) elem; int8_t type = el->type.to_ulong (); + int tmp_out_coords[T8_ELEMENT_DIM[TEclass]] = {}; for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { coords[idim] = el->coords[idim] + t8_type_vertex_dim_to_binary[type][vertex][idim] * element_get_len (el->level); } + for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; ++idim) { + for (int jdim = 0; jdim < T8_ELEMENT_DIM[TEclass]; ++jdim) { + tmp_out_coords[idim] += t8_standalone_lut_backtransform_coords[0][idim][jdim] * coords[jdim]; + } + } + for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; ++idim) { + coords[idim] = tmp_out_coords[idim]; + } + //coords = tmp_out_coords; } else { //Hypercubes diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx index 4ee5e2ab98..a43d839234 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx @@ -267,6 +267,19 @@ constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELE } }; +template<> +constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} + }, + { + {0, 1, 0}, + {1, 0, 0}, + {0, 0, 1} + } +}; template<> constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]]={ diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx index 4996846638..6a8629b13a 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx @@ -352,10 +352,15 @@ constexpr int8_t t8_standalone_lut_cornerface[1<[1<[1 << T8_E } }; +template<> +constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} + }, + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} + }, + { + {0, 1, 0}, + {1, 0, 0}, + {0, 0, 1} + }, + { + {-1, 0, 0}, + {0, -1, 0}, + {0, 0, -1} + } +}; + template<> constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]]={ T8_ECLASS_TRIANGLE, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx index 8af11e07f0..4497a104d0 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx @@ -633,6 +633,50 @@ constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEME } }; +template<> +constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]] = { + { + {1, 0, 0}, + {0, 0, 1}, + {0, 1, 0} + }, + { + {0, 1, 0}, + {0, 0, 1}, + {1, 0, 0} + }, + { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} + }, + { + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0} + }, + { + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0} + }, + { + {0, 1, 0}, + {1, 0, 0}, + {0, 0, 1} + }, + { + {0, 0, 1}, + {0, 1, 0}, + {1, 0, 0} + }, + { + {0, 0, 1}, + {1, 0, 0}, + {0, 1, 0} + } +}; + template<> constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]]={ T8_ECLASS_TRIANGLE, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx index f15a703ba7..0beee2d0c6 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx @@ -228,6 +228,17 @@ constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ } }; +template<> +constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ + { + {1, 0}, + {0, 1} + }, + { + {0, 1}, + {1, 0} + } +}; template<> constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]]={ From 3599a72bf6ceb58026dc28612c81f54d72dcab48 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 9 May 2025 16:13:49 +0200 Subject: [PATCH 14/37] cleanup --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4c3a52e6c6..da7626ff24 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -148,7 +148,7 @@ add_t8_test( NAME t8_gtest_input_equal_output_serial SOURCES add_t8_test( NAME t8_gtest_face_corner_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_corner.cxx ) add_t8_test( NAME t8_gtest_set_linear_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_set_linear_id.cxx ) add_t8_test( NAME t8_gtest_default_pyramid_count_leaves_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx ) -add_t8_test( NAME t8_gtest_reference_coords_serianl SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_reference_coords.cxx ) +add_t8_test( NAME t8_gtest_reference_coords_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_reference_coords.cxx ) if( T8CODE_BUILD_FORTRAN_INTERFACE AND T8CODE_ENABLE_MPI ) add_t8_test( NAME t8_test_fortran_mpi_interface_init_parallel SOURCES api/t8_fortran_interface/t8_test_mpi_init.f90 ) From 4d82579de9efb1e190d3e5f53849972a97e90f85 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 9 May 2025 16:15:01 +0200 Subject: [PATCH 15/37] add Assertions to check tet coords --- src/t8_forest/t8_forest.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index b24e6e130f..9cc4822af0 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -407,6 +407,14 @@ t8_forest_element_coordinate (t8_forest_t forest, t8_locidx_t ltree_id, const t8 const t8_gloidx_t gtreeid = t8_forest_global_tree_id (forest, ltree_id); /* Get the cmesh */ const t8_cmesh_t cmesh = t8_forest_get_cmesh (forest); +#if T8_ENABLE_DEBUG + if (tree_class == T8_ECLASS_TET) { + T8_ASSERT (vertex_coords[1] >= 0.0); + T8_ASSERT (vertex_coords[2] >= vertex_coords[1]); + T8_ASSERT (vertex_coords[0] >= vertex_coords[2]); + T8_ASSERT (vertex_coords[0] <= 1.0); + } +#endif /* Evaluate the geometry */ t8_geometry_evaluate (cmesh, gtreeid, vertex_coords, 1, coordinates); } From 66ef631f261ca1702517f98f569528306be18430 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 9 May 2025 16:31:02 +0200 Subject: [PATCH 16/37] delete duplicated test --- test/t8_schemes/t8_gtest_reference_coords.cxx | 82 ------------------- 1 file changed, 82 deletions(-) delete mode 100644 test/t8_schemes/t8_gtest_reference_coords.cxx diff --git a/test/t8_schemes/t8_gtest_reference_coords.cxx b/test/t8_schemes/t8_gtest_reference_coords.cxx deleted file mode 100644 index bdcdd6c9c5..0000000000 --- a/test/t8_schemes/t8_gtest_reference_coords.cxx +++ /dev/null @@ -1,82 +0,0 @@ -/* - 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) 2025 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. -*/ - -#include -#include -#include -#include -#include -#include "t8_gtest_dfs_base.hxx" - -/** This test is used to test the corner_face and face_corner scheme functions. - * The first test gets the corners of all faces of an element and checks if the reverse function can get the correct face of the corner. - * The second test does the same but in reverse order. - */ -class class_reference_coords_test: public TestDFS { - - void - check_element () override - { - for (int ivertex = 0; ivertex < scheme->element_get_num_corners (eclass, element); ivertex++) { - double vertex_coords[3]; - double reference_coords[3]; - scheme->element_debug_print (eclass, element); - scheme->element_get_vertex_reference_coords (eclass, element, ivertex, vertex_coords); - t8_debugf ("vertex_coords: %lf, %lf, %lf \n", vertex_coords[0], vertex_coords[1], vertex_coords[2]); - t8_element_shape_t shape = scheme->element_get_shape (eclass, element); - scheme->element_get_reference_coords (eclass, element, t8_element_corner_ref_coords[shape][ivertex], 1, - reference_coords); - t8_debugf ("reference_lut: %lf, %lf, %lf \n", t8_element_corner_ref_coords[shape][ivertex][0], - t8_element_corner_ref_coords[shape][ivertex][1], t8_element_corner_ref_coords[shape][ivertex][2]); - t8_debugf ("reference_coords: %lf, %lf, %lf \n", reference_coords[0], reference_coords[1], reference_coords[2]); - - for (int idim = 0; idim < T8_ELEMENT_DIM[eclass]; idim++) { - EXPECT_NEAR (vertex_coords[idim], reference_coords[idim], T8_PRECISION_SQRT_EPS); - } - } - } - - protected: - void - SetUp () override - { - dfs_test_setup (); - } - void - TearDown () override - { - /* Destroy DFS test */ - dfs_test_teardown (); - } -}; - -TEST_P (class_reference_coords_test, test_equal_dfs) -{ -#if T8CODE_TEST_LEVEL >= 1 - const int maxlvl = 3; -#else - const int maxlvl = 5; -#endif - check_recursive_dfs_to_max_lvl (maxlvl); -} - -INSTANTIATE_TEST_SUITE_P (t8_gtest_test_all_imps, class_reference_coords_test, AllSchemes, print_all_schemes); From 18ab26d574f59761df044fbfff5337975f7ca4ca Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 9 May 2025 16:33:47 +0200 Subject: [PATCH 17/37] cleanup --- .../t8_standalone_lut/t8_standalone_lut_pyra.hxx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx index 6a8629b13a..d8987620ec 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx @@ -352,11 +352,6 @@ constexpr int8_t t8_standalone_lut_cornerface[1<[1< Date: Fri, 9 May 2025 16:39:21 +0200 Subject: [PATCH 18/37] delete duplicated test --- test/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ef1c6f0808..8ff1272da8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -152,8 +152,7 @@ add_t8_test( NAME t8_gtest_scheme_consistency_serial SOURCES add_t8_test( NAME t8_gtest_input_equal_output_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_input_equal_output.cxx ) add_t8_test( NAME t8_gtest_face_corner_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_face_corner.cxx ) add_t8_test( NAME t8_gtest_set_linear_id_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_set_linear_id.cxx ) -add_t8_test( NAME t8_gtest_default_pyramid_count_leaves_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx ) -add_t8_test( NAME t8_gtest_reference_coords_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_reference_coords.cxx ) +add_t8_test( NAME t8_gtest_default_pyramid_count_leaves_serial SOURCES t8_gtest_main.cxx t8_schemes/t8_gtest_default_pyramid_count_leaves.cxx ) if( T8CODE_BUILD_FORTRAN_INTERFACE AND T8CODE_ENABLE_MPI ) add_t8_test( NAME t8_test_fortran_mpi_interface_init_parallel SOURCES api/t8_fortran_interface/t8_test_mpi_init.f90 ) From dc59084f7c7c436030cb0e8447352e43ad4aa32b Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 9 May 2025 16:51:54 +0200 Subject: [PATCH 19/37] fix debug print error --- src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index 8d9543c6b7..7c59ac9946 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -1722,9 +1722,12 @@ struct t8_standalone_scheme const t8_standalone_element *el = (const t8_standalone_element *) elem; + t8_debugf ("level: %i\n", el->level); for (int i = 0; i < T8_ELEMENT_DIM[TEclass]; i++) { + t8_debugf ("x_%i: %i \n", i, el->coords[i]); } for (int e = 0; e < T8_ELEMENT_NUM_EQUATIONS[TEclass]; e++) { + t8_debugf ("t_%i: %i \n", e, el->type[e]); } } From 2822d28b7b598a5f1c0b03d0434b5fb2e84310fd Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 9 May 2025 17:28:09 +0200 Subject: [PATCH 20/37] remove unused value --- test/t8_forest/t8_gtest_element_volume.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/test/t8_forest/t8_gtest_element_volume.cxx b/test/t8_forest/t8_gtest_element_volume.cxx index 8ff9e2245b..a3402eeda2 100644 --- a/test/t8_forest/t8_gtest_element_volume.cxx +++ b/test/t8_forest/t8_gtest_element_volume.cxx @@ -95,7 +95,6 @@ pyramid_control_volume (t8_element_t *pyra, t8_eclass_t eclass, const t8_scheme scheme->element_get_parent (eclass, pyra, pyra); t8_element_shape_t parent_shape = scheme->element_get_shape (eclass, pyra); control_volume = control_volume * shape_factor[shape][parent_shape]; - int test_level = scheme->element_get_level (eclass, pyra); } return control_volume; From 38aff555425a2ee869809f1d00d3a59eed8b8a31 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Fri, 9 May 2025 17:44:28 +0200 Subject: [PATCH 21/37] remove unused variable --- test/t8_schemes/t8_gtest_element_count_leaves.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index 551fb06ae4..f7c336291f 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -91,9 +91,9 @@ TEST_P (class_element_leaves, test_element_count_leaves_root) #endif t8_gloidx_t compare_value = 1; t8_gloidx_t test_value = 1; - t8_gloidx_t sum1 = 1; - t8_gloidx_t sum2 = 1; - t8_gloidx_t num_leaves = 0; + // t8_gloidx_t sum1 = 1; + // t8_gloidx_t sum2 = 1; + // t8_gloidx_t num_leaves = 0; for (int level = 0; level <= maxlevel; ++level) { const t8_gloidx_t leaf_count = scheme->count_leaves_from_root (eclass, level); From f6d5752bd75fbad325d243c4a74eb1ec619f4d58 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Mon, 12 May 2025 08:57:26 +0200 Subject: [PATCH 22/37] fix test --- test/t8_schemes/t8_gtest_element_count_leaves.cxx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index f7c336291f..e3f59b13bc 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -86,8 +86,7 @@ TEST_P (class_element_leaves, test_element_count_leaves_root) #if T8CODE_TEST_LEVEL >= 1 const int maxlevel = 4; #else - const int maxlevel = scheme->get_maxlevel (eclass); - ; + const int maxlevel = 8; #endif t8_gloidx_t compare_value = 1; t8_gloidx_t test_value = 1; From 9beb28a9de97f76bccc00d8067a22cf7c0dd3e11 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 14 May 2025 16:43:32 +0200 Subject: [PATCH 23/37] add function get_max_num_children --- src/t8_forest/t8_forest_adapt.cxx | 18 +++++++++--------- .../t8_default_hex/t8_default_hex.cxx | 6 ++++++ .../t8_default_hex/t8_default_hex.hxx | 6 ++++++ .../t8_default_line/t8_default_line.cxx | 6 ++++++ .../t8_default_line/t8_default_line.hxx | 6 ++++++ .../t8_default_prism/t8_default_prism.cxx | 6 ++++++ .../t8_default_prism/t8_default_prism.hxx | 6 ++++++ .../t8_default_pyramid/t8_default_pyramid.cxx | 6 ++++++ .../t8_default_pyramid/t8_default_pyramid.hxx | 6 ++++++ .../t8_default_quad/t8_default_quad.cxx | 6 ++++++ .../t8_default_quad/t8_default_quad.hxx | 6 ++++++ .../t8_default_tet/t8_default_tet.cxx | 6 ++++++ .../t8_default_tet/t8_default_tet.hxx | 6 ++++++ .../t8_default_tri/t8_default_tri.cxx | 6 ++++++ .../t8_default_tri/t8_default_tri.hxx | 6 ++++++ .../t8_default_vertex/t8_default_vertex.cxx | 6 ++++++ .../t8_default_vertex/t8_default_vertex.hxx | 6 ++++++ src/t8_schemes/t8_scheme.h | 8 ++++++++ src/t8_schemes/t8_scheme.hxx | 10 ++++++++++ .../t8_standalone_implementation.hxx | 9 +++++++++ 20 files changed, 132 insertions(+), 9 deletions(-) diff --git a/src/t8_forest/t8_forest_adapt.cxx b/src/t8_forest/t8_forest_adapt.cxx index 7179cf6ab5..f374c04623 100644 --- a/src/t8_forest/t8_forest_adapt.cxx +++ b/src/t8_forest/t8_forest_adapt.cxx @@ -457,7 +457,7 @@ t8_forest_adapt (t8_forest_t forest) /* el_coarsen is the index of the first element in the new element * array which could be coarsened recursively. */ el_coarsen = 0; - num_children = scheme->element_get_num_children (tree->eclass, first_element_from); + num_children = scheme->get_max_num_children (tree->eclass); curr_size_elements = num_children; curr_size_elements_from = scheme->element_get_num_siblings (tree->eclass, first_element_from); /* Buffer for a family of new elements */ @@ -548,10 +548,10 @@ t8_forest_adapt (t8_forest_t forest) if (refine == 1) { /* The first element is to be refined */ num_children = scheme->element_get_num_children (tree->eclass, elements_from[0]); - if (num_children > curr_size_elements) { - elements = T8_REALLOC (elements, t8_element_t *, num_children); - curr_size_elements = num_children; - } + // if (num_children > curr_size_elements) { + // elements = T8_REALLOC (elements, t8_element_t *, num_children); + // curr_size_elements = num_children; + // } if (forest->set_adapt_recursive) { /* Create the children of this element */ scheme->element_new (tree->eclass, num_children, elements); @@ -590,10 +590,10 @@ t8_forest_adapt (t8_forest_t forest) * as num_siblings is always associated with elements_from*/ num_children = num_siblings; el_inserted++; - if (num_children > curr_size_elements) { - elements = T8_REALLOC (elements, t8_element_t *, num_children); - curr_size_elements = num_children; - } + // if (num_children > curr_size_elements) { + // elements = T8_REALLOC (elements, t8_element_t *, num_children); + // curr_size_elements = num_children; + // } if (forest->set_adapt_recursive) { /* Adaptation is recursive. * We check whether the just generated parent is the last in its diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx index bfe80b7740..8642d94f9e 100644 --- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx +++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx @@ -114,6 +114,12 @@ t8_default_scheme_hex::element_get_num_children ([[maybe_unused]] const t8_eleme return P8EST_CHILDREN; } +int +t8_default_scheme_hex::get_max_num_children () const +{ + return 8; +} + int t8_default_scheme_hex::element_get_num_face_children ([[maybe_unused]] const t8_element_t *elem, [[maybe_unused]] const int face) const diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx index 54ef5521b7..d437fc819b 100644 --- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx +++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx @@ -189,6 +189,12 @@ class t8_default_scheme_hex: public t8_default_scheme_common Date: Thu, 15 May 2025 11:55:12 +0200 Subject: [PATCH 24/37] fix merge error --- .../t8_standalone/t8_standalone_implementation.hxx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index ef00189c45..0e6e2de72c 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -545,15 +545,6 @@ struct t8_standalone_scheme return T8_ELEMENT_NUM_CHILDREN[TEclass]; } - /** Return the max number of children of an eclass. - * \return The max number of children of \a element. - */ - static constexpr int - get_max_num_children () noexcept - { - return T8_ELEMENT_NUM_CHILDREN[TEclass]; - } - /** * Indicates if an element is refinable. Possible reasons for being not refinable could be * that the element has reached its max level. From 534a96b9a8feacf7fba8fab1ec579ed632c8b7f5 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Thu, 15 May 2025 17:14:06 +0200 Subject: [PATCH 25/37] disable test --- test/t8_schemes/t8_gtest_element_count_leaves.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index e3f59b13bc..b8bb866f92 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -81,7 +81,7 @@ count_leaves_recursive (t8_element_t *child, const t8_scheme *scheme, t8_eclass_ return num_leaves; } -TEST_P (class_element_leaves, test_element_count_leaves_root) +TEST_P (class_element_leaves, DISABLED_test_element_count_leaves_root) { #if T8CODE_TEST_LEVEL >= 1 const int maxlevel = 4; From 2dc799950d301e07cbc0b7415ceb55fa74281370 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Tue, 20 May 2025 09:16:44 +0200 Subject: [PATCH 26/37] implement new test logic --- .../t8_gtest_element_count_leaves.cxx | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index b8bb866f92..73b7be7bb7 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include /* * In this file we test whether the t8_element_count_leaves{_from_root} @@ -45,70 +48,55 @@ class class_element_leaves: public testing::TestWithParamget_eclass_scheme_eclass (eclass); scheme->element_new (eclass, 1, &element); - scheme->element_new (eclass, 1, &child); - scheme->element_new (eclass, 1, &parent); } void TearDown () override { scheme->element_destroy (eclass, 1, &element); - scheme->element_destroy (eclass, 1, &child); - scheme->element_destroy (eclass, 1, &parent); scheme->unref (); } t8_element_t *element; - t8_element_t *child; - t8_element_t *parent; const t8_scheme *scheme; t8_eclass_t eclass; }; -t8_gloidx_t -count_leaves_recursive (t8_element_t *child, const t8_scheme *scheme, t8_eclass_t eclass, int level) +static int +adapt_all (t8_forest_t forest, t8_forest_t forest_from, t8_locidx_t which_tree, const t8_eclass_t tree_class, + t8_locidx_t lelement_id, const t8_scheme_c *scheme, const int is_family, const int num_elements, + t8_element_t *elements[]) { - t8_gloidx_t num_leaves = 0; - if (scheme->element_get_level (eclass, child) < level) { - int num_children = scheme->element_get_num_children (eclass, child); - for (int ichild = 0; ichild < num_children; ichild++) { - scheme->element_get_child (eclass, child, ichild, child); - num_leaves = num_leaves + count_leaves_recursive (child, scheme, eclass, level); - scheme->element_get_parent (eclass, child, child); - } - } - else { - return scheme->element_get_num_children (eclass, child); - } - return num_leaves; + return 1; } -TEST_P (class_element_leaves, DISABLED_test_element_count_leaves_root) +TEST_P (class_element_leaves, test_element_count_leaves_root) { #if T8CODE_TEST_LEVEL >= 1 const int maxlevel = 4; #else - const int maxlevel = 8; + const int maxlevel = 6; #endif t8_gloidx_t compare_value = 1; t8_gloidx_t test_value = 1; - // t8_gloidx_t sum1 = 1; - // t8_gloidx_t sum2 = 1; - // t8_gloidx_t num_leaves = 0; - + t8_cmesh_t cmesh = t8_cmesh_new_from_class (eclass, sc_MPI_COMM_WORLD); + t8_cmesh_ref (cmesh); + t8_forest_t forest = t8_forest_new_uniform (cmesh, scheme, 0, 0, sc_MPI_COMM_WORLD); + scheme->ref (); for (int level = 0; level <= maxlevel; ++level) { const t8_gloidx_t leaf_count = scheme->count_leaves_from_root (eclass, level); ASSERT_EQ (leaf_count, compare_value) << "Incorrect leaf count " << leaf_count << " at eclass " << t8_eclass_to_string[eclass] << " and level " << level << " (expecting " << compare_value << ")"; - /* Multiply the compare_value with 2^dim (= number of children per element) */ + forest = t8_forest_new_adapt (forest, adapt_all, 0, 0, NULL); + t8_gloidx_t num_leaves = t8_forest_get_local_num_elements (forest); - scheme->element_copy (eclass, element, child); - t8_gloidx_t num_leaves = count_leaves_recursive (child, scheme, eclass, level); compare_value = num_leaves; if (!scheme->refines_irregular (eclass)) { test_value *= 1 << t8_eclass_to_dimension[eclass]; EXPECT_EQ (test_value, compare_value); } } + t8_cmesh_unref (&cmesh); + t8_forest_unref (&forest); } /* Tests whether the leaf count for the same level is equal to 1 From 303a496b14e9f4636c6fc24eaaaacbcb8cb328da Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Tue, 20 May 2025 09:46:41 +0200 Subject: [PATCH 27/37] add maybe_unused --- test/t8_schemes/t8_gtest_element_count_leaves.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index 73b7be7bb7..095eb0a65f 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -61,9 +61,11 @@ class class_element_leaves: public testing::TestWithParam Date: Wed, 21 May 2025 14:32:33 +0200 Subject: [PATCH 28/37] apply suggestions from review --- .../t8_standalone_implementation.hxx | 42 +++++++------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index 0e6e2de72c..7ccf350dc6 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -263,7 +263,7 @@ struct t8_standalone_scheme T8_ASSERT (element_is_valid (element)); T8_ASSERT (0 <= face && face < T8_ELEMENT_NUM_FACES[TEclass]); T8_ASSERT (0 <= corner && corner < T8_ELEMENT_NUM_CORNERS[TEclass]); - T8_ASSERTF (t8_standalone_lut_facecorner[0][1][1] == 2, "LUT falsch!"); + T8_ASSERTF (t8_standalone_lut_facecorner[0][1][1] == 2, "LUT is wrong!"); if constexpr (!T8_ELEMENT_NUM_EQUATIONS[TEclass]) { return (corner >> face & 1) + 2 * face; @@ -851,7 +851,7 @@ struct t8_standalone_scheme } else { t8_standalone_element *el = (t8_standalone_element *) elem; - int child_id + const int child_id = t8_standalone_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][face_child]; return t8_standalone_lut_type_childid_face_to_childface[el->type.to_ulong ()][child_id][face]; } @@ -1001,16 +1001,10 @@ struct t8_standalone_scheme } // all edges containing dim must be fulfilled with x_d-a_d >= x_j-a_j or x_j-a_j <= x_d-a_d if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - if (t8_type_edge_equations[ieq][0] == dim) { - if (el->type[ieq]) { - return 0; - } - } - else if (t8_type_edge_equations[ieq][1] == dim) { - if (!el->type[ieq]) { - return 0; - } + for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ++ieq) { + if ((t8_type_edge_equations[ieq][0] == dim && el->type[ieq]) + || (t8_type_edge_equations[ieq][1] == dim && !el->type[ieq])) { + return 0; } } } @@ -1024,15 +1018,9 @@ struct t8_standalone_scheme // all edges containing dimid must be fulfilled with x_d-a_d <= x_j-a_j or x_j-a_j >= x_d-a_d if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - if (t8_type_edge_equations[ieq][0] == dim) { - if (!el->type[ieq]) { - return 0; - } - } - else if (t8_type_edge_equations[ieq][1] == dim) { - if (el->type[ieq]) { - return 0; - } + if ((t8_type_edge_equations[ieq][0] == dim && !el->type[ieq]) + || (t8_type_edge_equations[ieq][1] == dim && el->type[ieq])) { + return 0; } } } @@ -1043,7 +1031,7 @@ struct t8_standalone_scheme // get graph edge e (or ieq) = (xi,xj) // ai = aj is necessary and sufficient if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - int ieq = t8_standalone_lut_type_face_to_typebit[el->type.to_ulong ()][face]; + int const ieq = t8_standalone_lut_type_face_to_typebit[el->type.to_ulong ()][face]; if (el->coords[t8_type_edge_equations[ieq][0]] != el->coords[t8_type_edge_equations[ieq][1]]) { return 0; @@ -1111,7 +1099,7 @@ struct t8_standalone_scheme t8_standalone_element *neighbor = (t8_standalone_element *) neigh; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - int internal_face = t8_standalone_lut_face_internal[el->type.to_ulong ()][face]; + const int internal_face = t8_standalone_lut_face_internal[el->type.to_ulong ()][face]; if (internal_face) { /**Determine typebit*/ int typebit = t8_standalone_lut_type_face_to_typebit[el->type.to_ulong ()][face]; @@ -1140,7 +1128,7 @@ struct t8_standalone_scheme /**Adapt typebits*/ if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - for (size_t ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { + for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { /**For all neighboring typebits, change typebit*/ if (t8_type_edge_equations[ieq][0] == facenormal_dim || t8_type_edge_equations[ieq][1] == facenormal_dim) { @@ -1451,8 +1439,8 @@ struct t8_standalone_scheme T8_ASSERT (level <= T8_ELEMENT_MAXLEVEL[TEclass]); T8_ASSERT (level >= 0); if constexpr (TEclass == T8_ECLASS_PYRAMID) { - t8_linearidx_t two_to_l = 1LL << level; - t8_linearidx_t eight_to_l = 1LL << (3 * level); + const t8_linearidx_t two_to_l = 1LL << level; + const t8_linearidx_t eight_to_l = 1LL << (3 * level); return ((eight_to_l << 2) - two_to_l) / 3; } return 1LL << (level * T8_ELEMENT_DIM[TEclass]); @@ -1535,7 +1523,7 @@ struct t8_standalone_scheme t8_element_coord length = element_get_len (element_get_level (elem)); if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - double tmp_coords[T8_ELEMENT_DIM[TEclass]] = {}; + double tmp_coords[T8_ELEMENT_DIM[TEclass]] = { 0.0 }; for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; ++idim) { for (int jdim = 0; jdim < T8_ELEMENT_DIM[TEclass]; ++jdim) { tmp_coords[idim] From 126d1ec0424337cb5f2f0e5d4f7bb7358c472233 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 21 May 2025 14:57:51 +0200 Subject: [PATCH 29/37] apply review --- test/t8_schemes/t8_gtest_element_count_leaves.cxx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index 095eb0a65f..054e753810 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -89,9 +89,8 @@ TEST_P (class_element_leaves, test_element_count_leaves_root) << "Incorrect leaf count " << leaf_count << " at eclass " << t8_eclass_to_string[eclass] << " and level " << level << " (expecting " << compare_value << ")"; forest = t8_forest_new_adapt (forest, adapt_all, 0, 0, NULL); - t8_gloidx_t num_leaves = t8_forest_get_local_num_elements (forest); + compare_value = t8_forest_get_local_num_leaf_elements (forest); - compare_value = num_leaves; if (!scheme->refines_irregular (eclass)) { test_value *= 1 << t8_eclass_to_dimension[eclass]; EXPECT_EQ (test_value, compare_value); From 29fc2e001406caf02d8795507408f399af0d0df4 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Mon, 26 May 2025 11:37:10 +0200 Subject: [PATCH 30/37] switch are_family implementation --- .../t8_standalone_implementation.hxx | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index 7ccf350dc6..95fd01de70 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -641,29 +641,14 @@ struct t8_standalone_scheme static constexpr int elements_are_family (t8_element_t *const *fam) noexcept { -#if T8_ENABLE_DEBUG - const int num_siblings = element_get_num_siblings (fam[0]); - for (int isib = 0; isib < num_siblings; isib++) { - T8_ASSERT (element_is_valid (fam[isib])); + if (element_get_child_id (fam[0]) != 0) { + return 0; } -#endif - t8_standalone_element parent, compare; - /* Take the parent of the first element as baseline to compare against */ - element_get_parent ((const t8_element_t *) fam[0], (t8_element_t *) &parent); - const int num_children = element_get_num_children ((const t8_element_t *) &parent); - for (int childid = 0; childid < num_children; childid++) { - /* check whether each element has the same parent */ - element_get_parent ((const t8_element_t *) fam[childid], (t8_element_t *) &compare); - if (element_compare ((const t8_element_t *) &parent, (const t8_element_t *) &compare)) { - return 0; - } - - /* check whether each element is the correct child of the collective parent */ - /* Could be replaced by type comparison as level is already checked in parent comparison */ - element_get_child ((const t8_element_t *) &parent, childid, (t8_element_t *) &compare); - - if (element_compare ((const t8_element_t *) fam[childid], (const t8_element_t *) &compare)) { + const int num_siblings = element_get_num_siblings (fam[0]); + const int level = element_get_level (fam[0]); + for (int ielement = 1; ielement < num_siblings; ielement++) { + if (element_get_level (fam[ielement]) != level) { return 0; } } From ada35355409f0065a0ff6f008ae55409531bf8a7 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Tue, 19 Aug 2025 13:22:22 +0200 Subject: [PATCH 31/37] apply review --- .../t8_standalone_implementation.hxx | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index 95fd01de70..27ed11f851 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -287,7 +287,7 @@ struct t8_standalone_scheme { T8_ASSERT (element_is_valid (elem)); T8_ASSERT (0 <= face && face < T8_ELEMENT_NUM_FACES[TEclass]); - t8_standalone_element *el = (t8_standalone_element *) elem; + const t8_standalone_element *el = (const t8_standalone_element *) elem; switch (TEclass) { case T8_ECLASS_VERTEX: SC_ABORT ("Vertices do not have faces.\n"); @@ -674,7 +674,7 @@ struct t8_standalone_scheme const t8_standalone_element *el1 = (const t8_standalone_element *) elem1; const t8_standalone_element *el2 = (const t8_standalone_element *) elem2; /* get the first possible level of the nca*/ - int cube_ancestor_level = element_get_cube_nca_level (el1, el2); + const int cube_ancestor_level = element_get_cube_nca_level (el1, el2); int real_level = cube_ancestor_level; if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { t8_element_type ancestor_type, ancestor2_type; @@ -835,7 +835,7 @@ struct t8_standalone_scheme return face; } else { - t8_standalone_element *el = (t8_standalone_element *) elem; + const t8_standalone_element *el = (const t8_standalone_element *) elem; const int child_id = t8_standalone_lut_type_face_facechildid_to_childid[el->type.to_ulong ()][face][face_child]; return t8_standalone_lut_type_childid_face_to_childface[el->type.to_ulong ()][child_id][face]; @@ -1016,7 +1016,7 @@ struct t8_standalone_scheme // get graph edge e (or ieq) = (xi,xj) // ai = aj is necessary and sufficient if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { - int const ieq = t8_standalone_lut_type_face_to_typebit[el->type.to_ulong ()][face]; + const int ieq = t8_standalone_lut_type_face_to_typebit[el->type.to_ulong ()][face]; if (el->coords[t8_type_edge_equations[ieq][0]] != el->coords[t8_type_edge_equations[ieq][1]]) { return 0; @@ -1705,11 +1705,11 @@ struct t8_standalone_scheme const t8_standalone_element *el = (const t8_standalone_element *) elem; t8_debugf ("level: %i\n", el->level); - for (int i = 0; i < T8_ELEMENT_DIM[TEclass]; i++) { - t8_debugf ("x_%i: %i \n", i, el->coords[i]); + for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { + t8_debugf ("x_%i: %i \n", idim, el->coords[idim]); } - for (int e = 0; e < T8_ELEMENT_NUM_EQUATIONS[TEclass]; e++) { - t8_debugf ("t_%i: %i \n", e, el->type[e]); + for (int e_num = 0; e_num < T8_ELEMENT_NUM_EQUATIONS[TEclass]; e_num++) { + t8_debugf ("t_%i: %i \n", e_num, el->type[e_num]); } } @@ -1989,8 +1989,8 @@ struct t8_standalone_scheme { T8_ASSERT (leveldiff <= get_maxlevel ()); if constexpr (TEclass == T8_ECLASS_PYRAMID) { - t8_linearidx_t two_to_l = 1LL << leveldiff; - t8_linearidx_t eight_to_l = 1LL << (3 * leveldiff); + const t8_linearidx_t two_to_l = 1LL << leveldiff; + const t8_linearidx_t eight_to_l = 1LL << (3 * leveldiff); if (element_get_shape (elem) == T8_ECLASS_PYRAMID) { return ((eight_to_l << 2) - two_to_l) / 3; } @@ -2014,7 +2014,7 @@ struct t8_standalone_scheme if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { t8_standalone_element *el = (t8_standalone_element *) elem; - int8_t type = el->type.to_ulong (); + const int8_t type = el->type.to_ulong (); int tmp_out_coords[T8_ELEMENT_DIM[TEclass]] = {}; for (int idim = 0; idim < T8_ELEMENT_DIM[TEclass]; idim++) { coords[idim] @@ -2200,7 +2200,7 @@ struct t8_standalone_scheme } if constexpr (T8_ELEMENT_NUM_EQUATIONS[TEclass]) { for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - int ifaceeq = t8_standalone_lut_rootface_eq_to_faceeq[root_face][ieq]; + const int ifaceeq = t8_standalone_lut_rootface_eq_to_faceeq[root_face][ieq]; if (ifaceeq != -1) { boundary->type[ifaceeq] = el->type[ieq]; } @@ -2273,14 +2273,15 @@ struct t8_standalone_scheme t8_element_type root_type = 0; el->type = root_type; for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - int ifaceeq = t8_standalone_lut_rootface_eq_to_faceeq[root_face][ieq]; + const int ifaceeq = t8_standalone_lut_rootface_eq_to_faceeq[root_face][ieq]; if (ifaceeq != -1) { el->type[ieq] = face->type[ifaceeq]; } } /** Set those typebits, that are connected to the face_normaldim of root_face*/ for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { - int facenormal_dim = t8_standalone_lut_type_face_to_facenormal_dim[root_type.to_ulong ()][root_face]; + const int facenormal_dim + = t8_standalone_lut_type_face_to_facenormal_dim[root_type.to_ulong ()][root_face]; if (t8_type_edge_equations[ieq][0] == facenormal_dim) { el->type[ieq] = !t8_standalone_lut_type_face_to_is_1_boundary[root_type.to_ulong ()][root_face]; } @@ -2506,7 +2507,7 @@ t8_standalone_scheme::element_transform_face ([[maybe_unused const t8_standalone_element *el1 = (const t8_standalone_element *) elem1; t8_standalone_element *el2 = (t8_standalone_element *) elem2; - t8_element_coord h = element_get_len (el1->level); + const t8_element_coord length = element_get_len (el1->level); // copy elem1 in tmp so that results can directly be set in elem2 t8_standalone_element tmp; @@ -2531,7 +2532,7 @@ t8_standalone_scheme::element_transform_face ([[maybe_unused tmp.coords[1] = el1->coords[0] - el1->coords[1]; } else { - tmp.coords[1] = el1->coords[0] - el1->coords[1] - h; + tmp.coords[1] = el1->coords[0] - el1->coords[1] - length; } } @@ -2552,22 +2553,22 @@ t8_standalone_scheme::element_transform_face ([[maybe_unused element_copy ((t8_element_t *) &tmp, (t8_element_t *) el2); break; case 1: - el2->coords[0] = get_root_len () - h - tmp.coords[1]; + el2->coords[0] = get_root_len () - length - tmp.coords[1]; if (tmp.type == 0) { el2->coords[1] = tmp.coords[0] - tmp.coords[1]; } else { - el2->coords[1] = tmp.coords[0] - tmp.coords[1] - h; + el2->coords[1] = tmp.coords[0] - tmp.coords[1] - length; } break; case 2: if (tmp.type == 0) { - el2->coords[0] = get_root_len () - h + tmp.coords[1] - tmp.coords[0]; + el2->coords[0] = get_root_len () - length + tmp.coords[1] - tmp.coords[0]; } else { el2->coords[0] = get_root_len () + tmp.coords[1] - tmp.coords[0]; } - el2->coords[1] = get_root_len () - h - tmp.coords[0]; + el2->coords[1] = get_root_len () - length - tmp.coords[0]; break; default: SC_ABORT_NOT_REACHED (); From c84c888ad69bde69de8cd75f9e76a2736cdf30a0 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Mon, 5 Oct 2026 16:29:05 +0200 Subject: [PATCH 32/37] fix merge errors --- src/t8_schemes/t8_scheme.hxx | 2 +- test/t8_schemes/t8_gtest_element_count_leaves.cxx | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/t8_schemes/t8_scheme.hxx b/src/t8_schemes/t8_scheme.hxx index 386117da65..8e21cfb7eb 100644 --- a/src/t8_schemes/t8_scheme.hxx +++ b/src/t8_schemes/t8_scheme.hxx @@ -107,7 +107,7 @@ struct t8_scheme t8_standalone_scheme, t8_standalone_scheme, t8_standalone_scheme, - t8_standalone_scheme + t8_standalone_scheme, /* Subelement schemes */ t8_subelem_scheme_hanging_nodes_quad, t8_subelem_scheme_hanging_nodes_tri diff --git a/test/t8_schemes/t8_gtest_element_count_leaves.cxx b/test/t8_schemes/t8_gtest_element_count_leaves.cxx index 02244e85f8..e676043468 100644 --- a/test/t8_schemes/t8_gtest_element_count_leaves.cxx +++ b/test/t8_schemes/t8_gtest_element_count_leaves.cxx @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -73,14 +73,16 @@ adapt_all ([[maybe_unused]] t8_forest_t forest, [[maybe_unused]] t8_forest_t for TEST_P (class_element_leaves, test_element_count_leaves_root) { -#if T8CODE_TEST_LEVEL >= 1 - const int maxlevel = 4; +#if T8_TEST_LEVEL_INT >= 1 + const int maxlevel = 3; #else - const int maxlevel = 6; + const int maxlevel = 5; #endif t8_gloidx_t compare_value = 1; t8_gloidx_t test_value = 1; - t8_cmesh_t cmesh = t8_cmesh_new_from_class (eclass, sc_MPI_COMM_WORLD); + t8_cmesh_t cmesh; + t8_cmesh_init (&cmesh); + t8_cmesh_new_from_class (cmesh, eclass, sc_MPI_COMM_WORLD); t8_cmesh_ref (cmesh); t8_forest_t forest = t8_forest_new_uniform (cmesh, scheme, 0, 0, sc_MPI_COMM_WORLD); scheme->ref (); From a999e41296e78f4c0fea99b33cbba8068fc9be4d Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 7 Oct 2026 15:23:26 +0200 Subject: [PATCH 33/37] clear bitset before setting it --- src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index b81f89eb57..f4f5e156d8 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -2250,6 +2250,7 @@ struct t8_standalone_scheme: public t8_scheme_helperstype = 0; for (int ieq = 0; ieq < T8_ELEMENT_NUM_EQUATIONS[TEclass]; ieq++) { const int ifaceeq = t8_standalone_lut_rootface_eq_to_faceeq[root_face][ieq]; if (ifaceeq != -1) { From 6f432373850f53b0932977bcd341fdf3c8ba0ebd Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 7 Oct 2026 15:38:12 +0200 Subject: [PATCH 34/37] remove redundant OR --- src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index f4f5e156d8..c671d0e3b8 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -2405,7 +2405,7 @@ struct t8_standalone_scheme: public t8_scheme_helperstype[e] | type[e]; + type[e] = el->type[e]; } else if (coord_v0 < coord_v1) { type |= (1 << e); From fcec7f93c7b4321c9d55744098b10bc7082d5d0a Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 7 Oct 2026 16:06:05 +0200 Subject: [PATCH 35/37] add documentation for LUTs --- .../t8_standalone/t8_standalone_elements.hxx | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx index 5574abab67..c0fc4371e0 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_elements.hxx @@ -59,92 +59,139 @@ constexpr uint8_t T8_ELEMENT_NUM_FACES[T8_ECLASS_COUNT] = { 0, 2, 4, 3, 6, 4, 5, /** Number of face children of the standalone element types */ constexpr uint8_t T8_ELEMENT_MAX_NUM_FACECHILDREN[T8_ECLASS_COUNT] = { 0, 1, 2, 2, 4, 4, 4, 4 }; + +/** Number of faces per corner of the standalone element types */ constexpr uint8_t T8_ELEMENT_NUM_CORNER_FACES[T8_ECLASS_COUNT] = { 0, 1, 2, 2, 3, 3, 3, 4 }; + +/** Number of corners per face of the standalone element types */ constexpr uint8_t T8_ELEMENT_NUM_FACE_CORNERS[T8_ECLASS_COUNT] = { 0, 2, 2, 2, 4, 3, 4, 4 }; /** Number of equations of the standalone element types */ constexpr uint8_t T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_COUNT] = { 0, 0, 0, 1, 0, 3, 1, 2 }; +/* The following lookup tables (LUTs) are only specialized for element classes with type equations + * (triangle, tet, prism, pyramid), see t8_standalone_lut/. Unless stated otherwise, the first index + * is the element type interpreted as integer (type.to_ulong ()). */ + /**PARENT CHILD BIJECTION*/ +/** Type of a child. Indexed by [parent type][child id (Iloc)]. */ template constexpr int8_t t8_element_type_Iloc_to_childtype[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_CHILDREN[TEclass]]; +/** Cube id of a child, i.e. its position inside the parent's cube. Indexed by [parent type][child id (Iloc)]. */ template constexpr int8_t t8_element_type_Iloc_to_childcubeid[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_CHILDREN[TEclass]]; +/** Type of the parent. Indexed by [child type][child cube id]. */ template constexpr int8_t t8_element_type_cubeid_to_parenttype[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [1 << T8_ELEMENT_DIM[TEclass]]; +/** Child id (Iloc) of an element relative to its parent. Indexed by [child type][child cube id]. */ template constexpr int8_t t8_element_type_cubeid_to_Iloc[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][1 << T8_ELEMENT_DIM[TEclass]]; /**TYPE EQUATIONS*/ +/** The two coordinate dimensions compared by each type equation. Indexed by [equation][0|1]. + * Bit i of the element type encodes the ordering of the coordinates in these two dimensions. */ template constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[TEclass]][2]; /**VERTEX*/ +/** Offset (0 or 1, in units of the element length) of a vertex relative to the anchor node. + * Indexed by [type][vertex][dim]. */ template constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_CORNERS[TEclass]] [T8_ELEMENT_DIM[TEclass]]; /**FACE*/ +/** 1 if the face lies inside the element's cube (neighbor differs only in its type), 0 if it lies on the cube boundary. + * Indexed by [type][face]. */ template constexpr int8_t t8_standalone_lut_face_internal[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_FACES[TEclass]]; +/** Type bit that is flipped to obtain the neighbor across an internal face, -1 for cube boundary faces. + * Indexed by [type][face]. */ template constexpr int8_t t8_standalone_lut_type_face_to_typebit[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** Orientation (+1/-1) of the outward face normal along \ref t8_standalone_lut_type_face_to_facenormal_dim, + * 0 for internal faces. Indexed by [type][face]. */ template constexpr int8_t t8_standalone_lut_type_face_to_sign[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** Coordinate dimension of the face normal for cube boundary faces, -1 for internal faces. Indexed by [type][face]. */ template constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** Face number of the face neighbor's face that coincides with the given face. Indexed by [type][face]. */ template constexpr int8_t t8_standalone_lut_type_face_to_neighface[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** Face of the parent on which the given face of the child lies, -1 if it lies inside the parent. + * Indexed by [child type][child cube id][child face]. */ template constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [1 << T8_ELEMENT_DIM[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** 1 if the face lies on the upper boundary (coordinate = anchor + length) of the face normal dimension, + * 0 if it lies on the lower boundary. Indexed by [type][face]. */ template constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** Cube id of the last descendant touching the face, used to compute the last face descendant. + * Indexed by [type][face]. */ template constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** Child id of the i-th child touching the face. Indexed by [parent type][parent face][face child id]. */ template constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]] [T8_ELEMENT_MAX_NUM_FACECHILDREN[TEclass]]; +/** Face of the child that lies on the given parent face, -1 if none. Indexed by [parent type][child id][parent face]. */ template constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_CHILDREN[TEclass]] [T8_ELEMENT_MAX_NUM_FACECHILDREN[TEclass]]; +/** Root tree face on which the element face can lie, -1 if an element of this type + * cannot touch the tree boundary with this face. Indexed by [type][face]. */ template constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** Coordinate dimension of the boundary face element corresponding to a dimension of the volume element, + * -1 if the dimension is dropped. Indexed by [root face][volume dim]. */ template constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[TEclass]][T8_ELEMENT_DIM[TEclass]]; +/** Type equation of the boundary face element corresponding to a type equation of the volume element, + * -1 if the equation is dropped. Indexed by [root face][volume equation]. */ template constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[TEclass]] [T8_ELEMENT_NUM_EQUATIONS[TEclass]]; +/** Element face that lies on the given root tree face, -1 if an element of this type cannot touch it. + * Indexed by [type][root face]. */ template constexpr int8_t t8_standalone_lut_type_rootface_to_face[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]] [T8_ELEMENT_NUM_FACES[TEclass]]; +/** Element class of each root tree face. Indexed by [root face]. */ template constexpr t8_eclass t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[TEclass]]; +/** Faces adjacent to a corner. Indexed by [type][corner][i]. */ template constexpr int8_t t8_standalone_lut_cornerface[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_CORNERS[TEclass]] [T8_ELEMENT_NUM_CORNER_FACES[TEclass]]; +/** Corners of a face. Indexed by [type][face][i]. */ template constexpr int8_t t8_standalone_lut_facecorner[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_NUM_FACES[TEclass]] [T8_ELEMENT_NUM_FACE_CORNERS[TEclass]]; +/** Matrix mapping reference coordinates of the reference element to the element of the given type. + * Indexed by [type][out dim][in dim]. */ template constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_DIM[TEclass]] [T8_ELEMENT_DIM[TEclass]]; +/** Matrix mapping the internal coordinate frame back to the reference coordinates of the tree. + * Indexed by [type][out dim][in dim]; currently only type 0 is used. */ template constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[TEclass]][T8_ELEMENT_DIM[TEclass]] [T8_ELEMENT_DIM[TEclass]]; @@ -154,6 +201,7 @@ constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUA #include "t8_standalone_lut/t8_standalone_lut_pyra.hxx" #include "t8_standalone_lut/t8_standalone_lut_tet.hxx" +/** Type for the element coordinates. */ typedef int32_t t8_element_coord; /** Type for the element level. */ typedef uint8_t t8_element_level; From 197e302c907582bc9bc0c413e1b17c57f7efbb29 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 7 Oct 2026 16:16:58 +0200 Subject: [PATCH 36/37] fix error for other compilers --- src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx index c671d0e3b8..ec6aa6ba45 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_implementation.hxx @@ -1755,7 +1755,7 @@ struct t8_standalone_scheme: public t8_scheme_helperscoords[idim]); } for (int e_num = 0; e_num < T8_ELEMENT_NUM_EQUATIONS[TEclass]; e_num++) { - t8_debugf ("t_%i: %i \n", e_num, el->type[e_num]); + t8_debugf ("t_%i: %i \n", e_num, (int) el->type.test (e_num)); } } From 70217754b3ad66f0a1e11079c4a674cb79c4b492 Mon Sep 17 00:00:00 2001 From: Ole Albers Date: Wed, 7 Oct 2026 16:25:42 +0200 Subject: [PATCH 37/37] make all LUTs inline constexpr --- .../t8_standalone_lut_prism.hxx | 50 +++++++++---------- .../t8_standalone_lut_pyra.hxx | 50 +++++++++---------- .../t8_standalone_lut_tet.hxx | 50 +++++++++---------- .../t8_standalone_lut_triangle.hxx | 50 +++++++++---------- 4 files changed, 100 insertions(+), 100 deletions(-) diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx index a43d839234..37ce9e5dc4 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_prism.hxx @@ -25,27 +25,27 @@ // PRISMS // clang-format off template<> -constexpr int8_t t8_element_type_Iloc_to_childtype[1<[1< -constexpr int8_t t8_element_type_Iloc_to_childcubeid[1<[1< -constexpr int8_t t8_element_type_cubeid_to_parenttype[1<[1< -constexpr int8_t t8_element_type_cubeid_to_Iloc[1<[1<[1< -constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][2] = { +inline constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][2] = { {0, 1} }; template<> -constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]] +inline constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]] [T8_ELEMENT_NUM_CORNERS[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]] = { { {0, 0, 0}, @@ -81,41 +81,41 @@ constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_N template<> -constexpr int8_t t8_standalone_lut_face_internal[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_typebit[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_sign[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_neighface[1<[1< -constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1<[1< -constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1<[1< -constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1<[1< -constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ +inline constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ {-1,0,1}, {0,0,1}, {0,-1,1}, @@ -201,7 +201,7 @@ constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_E {0,1,-1} }; template<> -constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]]={ +inline constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]]={ {-1}, {-1}, {-1}, @@ -210,13 +210,13 @@ constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELE }; template<> -constexpr int8_t t8_standalone_lut_type_rootface_to_face[1<[1< -constexpr int8_t t8_standalone_lut_cornerface[1<[1<[1< -constexpr int8_t t8_standalone_lut_facecorner[1<[1<[1< -constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ +inline constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ { {1, 0, 0}, {0, 1, 0}, @@ -268,7 +268,7 @@ constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELE }; template<> -constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ +inline constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]][T8_ELEMENT_DIM[T8_ECLASS_PRISM]]={ { {1, 0, 0}, {0, 1, 0}, @@ -282,7 +282,7 @@ constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8 }; template<> -constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]]={ +inline constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PRISM]]={ T8_ECLASS_QUAD, T8_ECLASS_QUAD, T8_ECLASS_QUAD, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx index d8987620ec..12ab0a5e1f 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_pyra.hxx @@ -33,7 +33,7 @@ template<> -constexpr int8_t t8_element_type_Iloc_to_childtype[1<[1<[1< -constexpr int8_t t8_element_type_Iloc_to_childcubeid[1<[1<[1< -constexpr int8_t t8_element_type_cubeid_to_parenttype[1<[1<[1< -constexpr int8_t t8_element_type_cubeid_to_Iloc[1<[1<[1< -constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][2] = { +inline constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][2] = { {1, 2}, {0, 2} }; template<> -constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]] +inline constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]] [T8_ELEMENT_NUM_CORNERS[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]] = { { {0, 0, 0}, @@ -114,14 +114,14 @@ constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT }; template<> -constexpr int8_t t8_standalone_lut_face_internal[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_typebit[1<[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_sign[1<[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_neighface[1<[1<[1<< }; template<> -constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1<[1<[1<< template<> -constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1<[1< -constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1<[1< }; template<> -constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1<[1< -constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1<[1< -constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ +inline constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ { 1,0,1}, {-1,0,1}, {0,1,1}, @@ -314,7 +314,7 @@ constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8 {0,1,-1} }; template<> -constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]]={ +inline constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]]={ {0,-1}, {0,-1}, {-1,0}, @@ -323,7 +323,7 @@ constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_E }; template<> -constexpr int8_t t8_standalone_lut_type_rootface_to_face[1<[1<[1< -constexpr int8_t t8_standalone_lut_cornerface[1<[1<[1< -constexpr int8_t t8_standalone_lut_facecorner[1<[1<[1< -constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ +inline constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ { {1, 0, 0}, {0, 1, 0}, @@ -415,7 +415,7 @@ constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_E }; template<> -constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ +inline constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]][T8_ELEMENT_DIM[T8_ECLASS_PYRAMID]]={ { {1, 0, 0}, {0, 1, 0}, @@ -439,7 +439,7 @@ constexpr int8_t t8_standalone_lut_backtransform_coords[1 << }; template<> -constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]]={ +inline constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_PYRAMID]]={ T8_ECLASS_TRIANGLE, T8_ECLASS_TRIANGLE, T8_ECLASS_TRIANGLE, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx index 4497a104d0..360c248cd8 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_tet.hxx @@ -26,7 +26,7 @@ // clang-format off template<> -constexpr int8_t t8_element_type_Iloc_to_childtype[1<[1<[1< -constexpr int8_t t8_element_type_Iloc_to_childcubeid[1<[1<[1< -constexpr int8_t t8_element_type_cubeid_to_parenttype[1<[1<[1< -constexpr int8_t t8_element_type_cubeid_to_Iloc[1<[1<[1<= y >= z*/ template<> -constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][2] = { +inline constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][2] = { {0, 1}, {1, 2}, {0, 2} }; template<> -constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]] +inline constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]] [T8_ELEMENT_NUM_CORNERS[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]] = { { {0, 0, 0}, @@ -139,7 +139,7 @@ constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM } }; template<> -constexpr int8_t t8_standalone_lut_face_internal[1<[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_typebit[1<[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_sign[1<[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1<[1<[1< }; template<> -constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1<[1<[1<< template<> -constexpr int8_t t8_standalone_lut_type_face_to_neighface[1<[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1<[1<[1< -constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1<[1< }; template<> -constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1<[1< }; template<> -constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1<[1< -constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1<[1< -constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]]={ +inline constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]]={ {-1,0,1}, {0,0,1}, {0,1,1}, {0,1,-1} }; template<> -constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]]={ +inline constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]]={ {-1, 0,-1}, {-1, 0, 0}, { 0,-1, 0}, @@ -474,7 +474,7 @@ constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEME }; template<> -constexpr int8_t t8_standalone_lut_type_rootface_to_face[1<[1<[1< -constexpr int8_t t8_standalone_lut_cornerface[1<[1<[1< -constexpr int8_t t8_standalone_lut_facecorner[1<[1<[1< -constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]]={ +inline constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]]={ { {1, 0, 0}, {0, 0, 1}, @@ -634,7 +634,7 @@ constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEME }; template<> -constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]] = { +inline constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]][T8_ELEMENT_DIM[T8_ECLASS_TET]] = { { {1, 0, 0}, {0, 0, 1}, @@ -678,7 +678,7 @@ constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_E }; template<> -constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]]={ +inline constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TET]]={ T8_ECLASS_TRIANGLE, T8_ECLASS_TRIANGLE, T8_ECLASS_TRIANGLE, diff --git a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx index 0beee2d0c6..078010cc24 100644 --- a/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx +++ b/src/t8_schemes/t8_standalone/t8_standalone_lut/t8_standalone_lut_triangle.hxx @@ -25,39 +25,39 @@ // TRIANGLES // clang-format off template<> -constexpr int8_t t8_element_type_Iloc_to_childtype[1<[1< -constexpr int8_t t8_element_type_Iloc_to_childcubeid[1<[1< -constexpr int8_t t8_element_type_cubeid_to_parenttype[1<[1< -constexpr int8_t t8_element_type_cubeid_to_Iloc[1<[1< -constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][2] = { +inline constexpr int8_t t8_type_edge_equations[T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][2] = { {0, 1} }; template<> -constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]] +inline constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]] [T8_ELEMENT_NUM_CORNERS[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]] = { { {0, 0}, @@ -74,50 +74,50 @@ constexpr int8_t t8_type_vertex_dim_to_binary[1 << T8_ELEMEN template<> -constexpr int8_t t8_standalone_lut_face_internal[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_typebit[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_sign[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_is_1_boundary[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_facenormal_dim[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_neighface[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_tree_face[1<[1< -constexpr int8_t t8_standalone_lut_type_cubeid_face_to_parentface[1<[1< -constexpr int8_t t8_standalone_lut_type_childid_face_to_childface[1<[1< -constexpr int8_t t8_standalone_lut_type_face_to_last_facechilds_cubeid[1<[1< -constexpr int8_t t8_standalone_lut_type_face_facechildid_to_childid[1<[1< -constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ +inline constexpr int8_t t8_standalone_lut_rootface_dim_to_facedim[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ {-1,0}, {0,0}, {0,-1} }; template<> -constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]]={ +inline constexpr int8_t t8_standalone_lut_rootface_eq_to_faceeq[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]][T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]]={ {-1}, {-1}, {-1} }; template<> -constexpr int8_t t8_standalone_lut_type_rootface_to_face[1<[1< -constexpr int8_t t8_standalone_lut_cornerface[1<[1<[1< -constexpr int8_t t8_standalone_lut_facecorner[1<[1<[1< -constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ +inline constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ { {1, 0}, {0, 1} @@ -229,7 +229,7 @@ constexpr int8_t t8_standalone_lut_transform_coords[1 << T8_ }; template<> -constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ +inline constexpr int8_t t8_standalone_lut_backtransform_coords[1 << T8_ELEMENT_NUM_EQUATIONS[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]][T8_ELEMENT_DIM[T8_ECLASS_TRIANGLE]]={ { {1, 0}, {0, 1} @@ -241,7 +241,7 @@ constexpr int8_t t8_standalone_lut_backtransform_coords[1 << }; template<> -constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]]={ +inline constexpr t8_eclass_t t8_standalone_lut_rootface_to_eclass[T8_ELEMENT_NUM_FACES[T8_ECLASS_TRIANGLE]]={ T8_ECLASS_LINE, T8_ECLASS_LINE, T8_ECLASS_LINE