Program Listing for File t8_eclass.h

Return to documentation for file (src/t8_eclass/t8_eclass.h)

/*
  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_ECLASS_H
#define T8_ECLASS_H

#include <t8.h>

T8_EXTERN_C_BEGIN ();

typedef enum t8_eclass {
  T8_ECLASS_ZERO = 0,
  T8_ECLASS_VERTEX = T8_ECLASS_ZERO,
  T8_ECLASS_LINE,
  T8_ECLASS_QUAD,
  T8_ECLASS_TRIANGLE,
  T8_ECLASS_HEX,
  T8_ECLASS_TET,
  T8_ECLASS_PRISM,
  T8_ECLASS_PYRAMID,
  T8_ECLASS_COUNT,
  T8_ECLASS_INVALID
} t8_eclass_t;

#define T8_MPI_ECLASS_TYPE (T8_ASSERT (sizeof (int) == sizeof (t8_eclass_t)), sc_MPI_INT)

#define T8_ECLASS_MAX_FACES 6
#define T8_ECLASS_MAX_EDGES 12
#define T8_ECLASS_MAX_EDGES_2D 4
#define T8_ECLASS_MAX_CORNERS_2D 4
#define T8_ECLASS_MAX_CORNERS 8
#define T8_ECLASS_MAX_DIM 3
#define T8_ECLASS_MAX_CHILDREN 10
#define T8_ECLASS_MAX_FACE_CHILDREN 4

/* clang-format off */

#define T8_ECLASS_TO_DIMENSION_VALUES      { 0, 1, 2, 2, 3, 3, 3, 3 }
#define T8_ECLASS_NUM_FACES_VALUES         { 0, 2, 4, 3, 6, 4, 5, 5 }
#define T8_ECLASS_MAX_NUM_FACES_VALUES     { 0, 2, 4, 6 }
#define T8_ECLASS_MAX_NUM_CHILDREN_VALUES  { 1, 2, 4, 4, 8, 8, 8, 10 }
#define T8_FACE_VERTEX_TO_TREE_VERTEX_VALUES {\
  { { -1 } },                                                                                         /* vertex */    \
  { { 0 }, { 1 } },                                                                                   /* line */      \
  { { 0, 2 }, { 1, 3 }, { 0, 1 }, { 2, 3 } },                                                         /* quad */      \
  { { 1, 2 }, { 0, 2 }, { 0, 1 } },                                                                   /* triangle */  \
  { { 0, 2, 4, 6 }, { 1, 3, 5, 7 }, { 0, 1, 4, 5 }, { 2, 3, 6, 7 }, { 0, 1, 2, 3 }, { 4, 5, 6, 7 } }, /* hex */       \
  { { 1, 2, 3 }, { 0, 2, 3 }, { 0, 1, 3 }, { 0, 1, 2 } },                                             /* tet */       \
  { { 1, 2, 4, 5 }, { 0, 2, 3, 5 }, { 0, 1, 3, 4 }, { 0, 1, 2 }, { 3, 4, 5 } },                       /* prism */     \
  { { 0, 2, 4 }, { 1, 3, 4 }, { 0, 1, 4 }, { 2, 3, 4 }, { 0, 1, 2, 3 } }                              /* pyramid */   \
}
#define T8_FACE_EDGE_TO_TREE_EDGE_VALUES {\
  { { -1 } },                                                                                             /* vertex */      \
  { { 0 } },                                                                                              /* line */        \
  { { 0 }, { 1 }, { 2 }, { 3 } },                                                                         /* quad */        \
  { { 0 }, { 1 }, { 2 } },                                                                                /* triangle */    \
  { { 8, 10, 4, 6 }, { 9, 11, 5, 7 }, { 8, 9, 0, 2 }, { 10, 11, 1, 3 }, { 4, 5, 0, 1 }, { 6, 7, 2, 3 } }, /* hex */         \
  { { 3, 4, 5 }, { 1, 2, 5 }, { 0, 2, 4 }, { 0, 1, 3 } },                                                 /* tet */         \
  { { 0, 7, 3, 6 }, { 1, 8, 4, 7 }, { 2, 6, 5, 8 }, { 0, 1, 2 }, { 3, 4, 5 } },                           /* prism */       \
  { { -1 } },                                                                                             /* pyramid */     \
}
#define T8_FACE_TO_EDGE_NEIGHBOR_VALUES {\
  { { -1 } },                                                                                             /* vertex */    \
  { { -1 } },                                                                                             /* line */      \
  { { 2, 3 }, { 2, 3 }, { 0, 1 }, { 0, 1 } },                                                             /* quad */      \
  { { 2, 1 }, { 2, 0 }, { 1, 0 } },                                                                       /* triangle */  \
  { { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 8, 9, 10, 11 } }, /* hex */       \
  { { 0, 1, 2 }, { 0, 3, 4 }, { 1, 3, 5 }, { 2, 4, 5 } },                                                 /* tet */       \
  { { 1, 2, 4, 5 }, { 0, 2, 3, 5 }, { 0, 1, 3, 4 }, { 6, 7, 8 }, { 6, 7, 8 } },                           /* prism */     \
  { { -1 } },                                                                                             /* pyramid */   \
}
#define T8_EDGE_VERTEX_TO_TREE_VERTEX_VALUES {\
  { { -1 } },                                                                                                                 /* vertex */    \
  { { 0 }, { 1 } },                                                                                                           /* line */      \
  { { 0, 2 }, { 1, 3 }, { 0, 1 }, { 2, 3 } },                                                                                 /* quad */      \
  { { 1, 2 }, { 0, 2 }, { 0, 1 } },                                                                                           /* triangle */  \
  { { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, { 0, 2 }, { 1, 3 }, { 4, 6 }, { 5, 7 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } }, /* hex */       \
  { { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 1, 3 }, { 2, 3 } },                                                             /* tet */       \
  { { 1, 2 }, { 0, 2 }, { 0, 1 }, { 4, 5 }, { 3, 5 }, { 3, 4 }, { 1, 4 }, { 2, 5 }, { 0, 3 } },                               /* prism */     \
  { { -1 } },                                                                                                                 /* pyramid */   \
}
#define T8_EDGE_TO_FACE_VALUES {\
  { { -1 } },                                                                                                                   /* vertex */    \
  { { 0 } },                                                                                                                    /* line */      \
  { { 0 }, { 1 }, { 2 }, { 3 } },                                                                                               /* quad */      \
  { { 0 }, { 1 }, { 2 } },                                                                                                      /* triangle */  \
  { { 2, 4 }, { 3, 4 }, { 2, 5 }, { 3, 5 }, { 0, 4 }, { 1, 4 }, { 0, 5 }, { 1, 5 }, { 0, 2 }, { 1, 2 }, { 0, 3 }, { 1, 3 } },   /* hex */       \
  { { 2, 3 }, { 1, 3 }, { 1, 2 }, { 0, 3 }, { 0, 2 }, { 0, 1 } },                                                               /* tet */       \
  { { 0, 3 }, { 1, 3 }, { 2, 3 }, { 0, 4 }, { 1, 4 }, { 2, 4 }, { 0, 2 }, { 0, 1 }, { 1, 2 } },                                 /* prism */     \
  { { -1 } },                                                                                                                   /* pyramid */   \
}
#define T8_ECLASS_FACE_ORIENTATION_VALUES {\
  { 0, -1, -1, -1, -1, -1 }, /* vertex */   \
  { 0, 0, -1, -1, -1, -1 },  /* line */     \
  { 0, 0, 0, 0, -1, -1 },    /* quad */     \
  { 0, 0, 0, -1, -1, -1 },   /* triangle */ \
  { 0, 1, 1, 0, 0, 1 },      /* hex */      \
  { 0, 1, 0, 1, -1, -1 },    /* tet */      \
  { 1, 0, 1, 0, 1, -1 },     /* prism */    \
  { 0, 1, 1, 0, 0, -1 }      /* pyramid */  \
}
#define T8_REFERENCE_FACE_NORMAL_TET_VALUES { { -1, 0, 0 }, { 1, 0, -1 }, { 0, -1, 1 }, { 0, 1, 0 } }

#define T8_ECLASS_NUM_VERTICES_VALUES { 1, 2, 4, 3, 8, 4, 6, 5 }
#define T8_ECLASS_NUM_EDGES_VALUES { 0, 1, 4, 3, 12, 6, 9, 8 }
#define T8_ECLASS_VTK_TYPE_VALUES { 1, 3, 9, 5, 12, 10, 13, 14 }
#define T8_ECLASS_VTK_TO_T8_CORNER_NUMBER_VALUES {\
  { 0, -1, -1, -1, -1, -1, -1, -1 }, /* vertex */   \
  { 0, 1, -1, -1, -1, -1, -1, -1 },  /* line */     \
  { 0, 1, 3, 2, -1, -1, -1, -1 },    /* quad */     \
  { 0, 1, 2, -1, -1, -1, -1, -1 },   /* triangle */ \
  { 0, 1, 3, 2, 4, 5, 7, 6 },        /* hex */      \
  { 0, 2, 1, 3, -1, -1, -1, -1 },    /* tet */      \
  { 0, 2, 1, 3, 5, 4, -1, -1 },      /* prism */    \
  { 0, 1, 3, 2, 4, -1, -1, -1 }      /* pyramid */  \
}
#define T8_ECLASS_T8_TO_VTK_CORNER_NUMBER_VALUES {\
  { 0, -1, -1, -1, -1, -1, -1, -1 }, /* vertex */   \
  { 0, 1, -1, -1, -1, -1, -1, -1 },  /* line */     \
  { 0, 1, 3, 2, -1, -1, -1, -1 },    /* quad */     \
  { 0, 1, 2, -1, -1, -1, -1, -1 },   /* triangle */ \
  { 0, 1, 3, 2, 4, 5, 7, 6 },        /* hex */      \
  { 0, 2, 1, 3, -1, -1, -1, -1 },    /* tet */      \
  { 0, 2, 1, 3, 5, 4, -1, -1 },      /* prism */    \
  { 0, 1, 3, 2, 4, -1, -1, -1 }      /* pyramid */  \
}
#define T8_ECLASS_FACE_TYPES_VALUES {\
  { -1, -1, -1, -1, -1, -1 }, /* vertex */    \
  { 0, 0, -1, -1, -1, -1 },   /* line */      \
  { 1, 1, 1, 1, -1, -1 },     /* quad */      \
  { 1, 1, 1, -1, -1, -1 },    /* triangle */  \
  { 2, 2, 2, 2, 2, 2 },       /* hex */       \
  { 3, 3, 3, 3, -1, -1 },     /* tet */       \
  { 2, 2, 2, 3, 3, -1 },      /* prism */     \
  { 3, 3, 3, 3, 2, -1 }       /* pyramid */   \
}
#define T8_ECLASS_BOUNDARY_COUNT_VALUES {\
  { 0, 0, 0, 0, 0, 0, 0, 0 },  /* vertex */   \
  { 2, 0, 0, 0, 0, 0, 0, 0 },  /* line */     \
  { 4, 4, 0, 0, 0, 0, 0, 0 },  /* quad */     \
  { 3, 3, 0, 0, 0, 0, 0, 0 },  /* triangle */ \
  { 8, 12, 6, 0, 0, 0, 0, 0 }, /* hex */      \
  { 4, 6, 0, 4, 0, 0, 0, 0 },  /* tet */      \
  { 6, 9, 3, 2, 0, 0, 0, 0 },  /* prism */    \
  { 5, 8, 1, 4, 0, 0, 0, 0 }   /* pyramid */  \
}
#define T8_ECLASS_TO_STRING_VALUES { "Vertex", "Line", "Quad", "Triangle", "Hex", "Tet", "Prism", "Pyramid", "Invalid" }

/* clang-format on */

#ifdef __cplusplus
/* constexpr variables for cpp. They are wrapped in a namespace to have a different symbol
 * as the C variables. The namespace also gets activated for all files which are compiled
 * by a cpp compiler. This is necessary, because this header will be compiled by a C and CPP
 * compiler and will be linked into the same library. And the same library cannot contain
 * the same symbol twice. T8_EXTERN_C is disabled, because it disables the namespace.*/

T8_EXTERN_C_END ();

namespace t8cpp
{
inline constexpr int t8_eclass_to_dimension[T8_ECLASS_COUNT] = T8_ECLASS_TO_DIMENSION_VALUES;

inline constexpr int t8_eclass_num_faces[T8_ECLASS_COUNT] = T8_ECLASS_NUM_FACES_VALUES;

inline constexpr int t8_eclass_max_num_faces[T8_ECLASS_MAX_DIM + 1] = T8_ECLASS_MAX_NUM_FACES_VALUES;

inline constexpr int t8_eclass_max_num_children[T8_ECLASS_COUNT] = T8_ECLASS_MAX_NUM_CHILDREN_VALUES;

inline constexpr int t8_face_vertex_to_tree_vertex[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES][T8_ECLASS_MAX_CORNERS_2D]
  = T8_FACE_VERTEX_TO_TREE_VERTEX_VALUES;

inline constexpr int t8_face_edge_to_tree_edge[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES][T8_ECLASS_MAX_EDGES_2D]
  = T8_FACE_EDGE_TO_TREE_EDGE_VALUES;

inline constexpr int t8_face_to_edge_neighbor[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES][T8_ECLASS_MAX_CORNERS_2D]
  = T8_FACE_TO_EDGE_NEIGHBOR_VALUES;

inline constexpr int t8_edge_vertex_to_tree_vertex[T8_ECLASS_COUNT][T8_ECLASS_MAX_EDGES][2]
  = T8_EDGE_VERTEX_TO_TREE_VERTEX_VALUES;

inline constexpr int t8_edge_to_face[T8_ECLASS_COUNT][T8_ECLASS_MAX_EDGES][2] = T8_EDGE_TO_FACE_VALUES;

inline constexpr int t8_eclass_face_orientation[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES]
  = T8_ECLASS_FACE_ORIENTATION_VALUES;

inline constexpr int t8_reference_face_normal_tet[T8_ECLASS_MAX_FACES][3] = T8_REFERENCE_FACE_NORMAL_TET_VALUES;

inline constexpr int t8_eclass_num_vertices[T8_ECLASS_COUNT] = T8_ECLASS_NUM_VERTICES_VALUES;

inline constexpr int t8_eclass_num_edges[T8_ECLASS_COUNT] = T8_ECLASS_NUM_EDGES_VALUES;

inline constexpr int t8_eclass_vtk_type[T8_ECLASS_COUNT] = T8_ECLASS_VTK_TYPE_VALUES;

inline constexpr int t8_eclass_vtk_to_t8_corner_number[T8_ECLASS_COUNT][T8_ECLASS_MAX_CORNERS]
  = T8_ECLASS_VTK_TO_T8_CORNER_NUMBER_VALUES;

inline constexpr int t8_eclass_t8_to_vtk_corner_number[T8_ECLASS_COUNT][T8_ECLASS_MAX_CORNERS]
  = T8_ECLASS_T8_TO_VTK_CORNER_NUMBER_VALUES;

inline constexpr int t8_eclass_face_types[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES] = T8_ECLASS_FACE_TYPES_VALUES;

inline constexpr int t8_eclass_boundary_count[T8_ECLASS_COUNT][T8_ECLASS_COUNT] = T8_ECLASS_BOUNDARY_COUNT_VALUES;

inline constexpr const char *t8_eclass_to_string[T8_ECLASS_INVALID] = T8_ECLASS_TO_STRING_VALUES;
} /* namespace t8cpp */

using namespace t8cpp;

T8_EXTERN_C_BEGIN ();

#else
/* extern variables for c. */

extern const int t8_eclass_to_dimension[T8_ECLASS_COUNT];

extern const int t8_eclass_num_faces[T8_ECLASS_COUNT];

extern const int t8_eclass_max_num_faces[T8_ECLASS_MAX_DIM + 1];

extern const int t8_eclass_max_num_children[T8_ECLASS_COUNT];

extern const int t8_face_vertex_to_tree_vertex[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES][T8_ECLASS_MAX_CORNERS_2D];

extern const int t8_face_edge_to_tree_edge[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES][T8_ECLASS_MAX_EDGES_2D];

extern const int t8_face_to_edge_neighbor[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES][T8_ECLASS_MAX_CORNERS_2D];

extern const int t8_edge_vertex_to_tree_vertex[T8_ECLASS_COUNT][T8_ECLASS_MAX_EDGES][2];

extern const int t8_edge_to_face[T8_ECLASS_COUNT][T8_ECLASS_MAX_EDGES][2];

extern const int t8_eclass_face_orientation[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES];

extern const int t8_reference_face_normal_tet[T8_ECLASS_MAX_FACES][3];

extern const int t8_eclass_num_vertices[T8_ECLASS_COUNT];

extern const int t8_eclass_num_edges[T8_ECLASS_COUNT];

extern const int t8_eclass_vtk_type[T8_ECLASS_COUNT];

extern const int t8_eclass_vtk_to_t8_corner_number[T8_ECLASS_COUNT][T8_ECLASS_MAX_CORNERS];

extern const int t8_eclass_t8_to_vtk_corner_number[T8_ECLASS_COUNT][T8_ECLASS_MAX_CORNERS];

extern const int t8_eclass_face_types[T8_ECLASS_COUNT][T8_ECLASS_MAX_FACES];

extern const int t8_eclass_boundary_count[T8_ECLASS_COUNT][T8_ECLASS_COUNT];

extern const char *t8_eclass_to_string[T8_ECLASS_INVALID];

#endif /* !__cplusplus */

/* Undefine values so that they do not leak into other files.
  * They can be kept using KEEP_ECLASS_VALUE_DEFINITIONS. This is needed
  * to use them in the eclass.c file. */
#ifndef KEEP_ECLASS_VALUE_DEFINITIONS

#undef T8_ECLASS_TO_DIMENSION_VALUES
#undef T8_ECLASS_NUM_FACES_VALUES
#undef T8_ECLASS_MAX_NUM_FACES_VALUES
#undef T8_ECLASS_MAX_NUM_CHILDREN_VALUES
#undef T8_FACE_VERTEX_TO_TREE_VERTEX_VALUES
#undef T8_FACE_EDGE_TO_TREE_EDGE_VALUES
#undef T8_FACE_TO_EDGE_NEIGHBOR_VALUES
#undef T8_EDGE_VERTEX_TO_TREE_VERTEX_VALUES
#undef T8_EDGE_TO_FACE_VALUES
#undef T8_ECLASS_FACE_ORIENTATION_VALUES
#undef T8_REFERENCE_FACE_NORMAL_TET_VALUES
#undef T8_ECLASS_NUM_VERTICES_VALUES
#undef T8_ECLASS_NUM_EDGES_VALUES
#undef T8_ECLASS_VTK_TYPE_VALUES
#undef T8_ECLASS_VTK_TO_T8_CORNER_NUMBER_VALUES
#undef T8_ECLASS_T8_TO_VTK_CORNER_NUMBER_VALUES
#undef T8_ECLASS_FACE_TYPES_VALUES
#undef T8_ECLASS_BOUNDARY_COUNT_VALUES
#undef T8_ECLASS_TO_STRING_VALUES

#endif

int
t8_eclass_count_boundary (t8_eclass_t theclass, int min_dim, int *per_eclass);

int
t8_eclass_compare (t8_eclass_t eclass1, t8_eclass_t eclass2);

int
t8_eclass_is_valid (t8_eclass_t eclass);

T8_EXTERN_C_END ();

#endif /* !T8_ELEMENT_H */