From 9efbb842ad2434b60a36f342cc080316bf98eb33 Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Mon, 19 Feb 2024 11:59:50 +0100
Subject: [PATCH 01/15] add scheme mempool base

---
 .../t8_default_common_cxx.cxx                 | 85 ----------------
 .../t8_default_common_cxx.hxx                 | 32 +-----
 .../t8_default_hex/t8_default_hex_cxx.cxx     |  5 +-
 .../t8_default_line/t8_default_line_cxx.cxx   |  4 +-
 .../t8_default_prism/t8_default_prism_cxx.cxx |  4 +-
 .../t8_default_pyramid_cxx.cxx                |  4 +-
 .../t8_default_quad/t8_default_quad_cxx.cxx   |  4 +-
 .../t8_default_tet/t8_default_tet_cxx.cxx     |  5 +-
 .../t8_default_tri/t8_default_tri_cxx.cxx     |  4 +-
 .../t8_default_vertex_cxx.cxx                 |  4 +-
 src/t8_schemes/t8_scheme_mempool_cxx.hxx      | 99 +++++++++++++++++++
 11 files changed, 111 insertions(+), 139 deletions(-)
 create mode 100644 src/t8_schemes/t8_scheme_mempool_cxx.hxx

diff --git a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx
index 64c3df7c4b..ccfc53b449 100644
--- a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.cxx
@@ -26,34 +26,6 @@
 /* We want to export the whole implementation to be callable from "C" */
 T8_EXTERN_C_BEGIN ();
 
-/** This class independent function assumes an sc_mempool_t as context.
- * It is suitable as the elem_new callback in \ref t8_eclass_scheme_t.
- * We assume that the mempool has been created with the correct element size.
- * \param [in,out] ts_context   An element is allocated in this sc_mempool_t.
- * \param [in]     length       Non-negative number of elements to allocate.
- * \param [in,out] elem         Array of correct size whose members are filled.
- */
-static void
-t8_default_mempool_alloc (sc_mempool_t *ts_context, int length, t8_element_t **elem);
-
-/** This class independent function assumes an sc_mempool_t as context.
- * It is suitable as the elem_destroy callback in \ref t8_eclass_scheme_t.
- * We assume that the mempool has been created with the correct element size.
- * \param [in,out] ts_context   An element is returned to this sc_mempool_t.
- * \param [in]     length       Non-negative number of elements to destroy.
- * \param [in,out] elem         Array whose members are returned to the mempool.
- */
-static void
-t8_default_mempool_free (sc_mempool_t *ts_context, int length, t8_element_t **elem);
-
-/* Destructor */
-t8_default_scheme_common_c::~t8_default_scheme_common_c ()
-{
-  T8_ASSERT (ts_context != NULL);
-  SC_ASSERT (((sc_mempool_t *) ts_context)->elem_count == 0);
-  sc_mempool_destroy ((sc_mempool_t *) ts_context);
-}
-
 /** Compute the number of corners of a given element. */
 int
 t8_default_scheme_common_c::t8_element_num_corners (const t8_element_t *elem) const
@@ -63,46 +35,6 @@ t8_default_scheme_common_c::t8_element_num_corners (const t8_element_t *elem) co
   return t8_eclass_num_vertices[eclass];
 }
 
-void
-t8_default_scheme_common_c::t8_element_new (int length, t8_element_t **elem) const
-{
-  t8_default_mempool_alloc ((sc_mempool_t *) this->ts_context, length, elem);
-}
-
-void
-t8_default_scheme_common_c::t8_element_destroy (int length, t8_element_t **elem) const
-{
-  t8_default_mempool_free ((sc_mempool_t *) this->ts_context, length, elem);
-}
-
-static void
-t8_default_mempool_alloc (sc_mempool_t *ts_context, int length, t8_element_t **elem)
-{
-  int i;
-
-  T8_ASSERT (ts_context != NULL);
-  T8_ASSERT (0 <= length);
-  T8_ASSERT (elem != NULL);
-
-  for (i = 0; i < length; ++i) {
-    elem[i] = (t8_element_t *) sc_mempool_alloc (ts_context);
-  }
-}
-
-static void
-t8_default_mempool_free (sc_mempool_t *ts_context, int length, t8_element_t **elem)
-{
-  int i;
-
-  T8_ASSERT (ts_context != NULL);
-  T8_ASSERT (0 <= length);
-  T8_ASSERT (elem != NULL);
-
-  for (i = 0; i < length; ++i) {
-    sc_mempool_free (ts_context, elem[i]);
-  }
-}
-
 t8_element_shape_t
 t8_default_scheme_common_c::t8_element_shape (const t8_element_t *elem) const
 {
@@ -153,21 +85,4 @@ t8_default_scheme_common_c::t8_element_count_leaves_from_root (int level) const
   return count_leaves_from_level (0, level, dim);
 }
 
-void
-t8_default_scheme_common_c::t8_element_general_function (const t8_element_t *elem, const void *indata,
-                                                         void *outdata) const
-{
-  /* This function is intentionally left blank. */
-}
-
-#if T8_ENABLE_DEBUG
-void
-t8_default_scheme_common_c::t8_element_debug_print (const t8_element_t *elem) const
-{
-  char debug_string[BUFSIZ];
-  t8_element_to_string (elem, debug_string, BUFSIZ);
-  t8_debugf ("%s\n", debug_string);
-}
-#endif
-
 T8_EXTERN_C_END ();
diff --git a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
index eb9fda8d31..bc772e73d3 100644
--- a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
@@ -28,28 +28,21 @@
 #define T8_DEFAULT_COMMON_CXX_HXX
 
 #include <t8_element_cxx.hxx>
+#include <t8_schemes/t8_scheme_mempool_cxx.hxx>
 
 /* Macro to check whether a pointer (VAR) to a base class, comes from an
  * implementation of a child class (TYPE). */
 #define T8_COMMON_IS_TYPE(VAR, TYPE) ((dynamic_cast<TYPE> (VAR)) != NULL)
 
-class t8_default_scheme_common_c: public t8_eclass_scheme_c {
+class t8_default_scheme_common_c: public t8_scheme_mempool_c {
  public:
-  /** Destructor for all default schemes */
-  virtual ~t8_default_scheme_common_c ();
+  /* Call parent constructor */
+  t8_default_scheme_common_c (t8_eclass_t eclass, int elem_size): t8_scheme_mempool_c (eclass, elem_size) {};
 
   /** Compute the number of corners of a given element. */
   virtual int
   t8_element_num_corners (const t8_element_t *elem) const;
 
-  /** Allocate space for a bunch of elements. */
-  virtual void
-  t8_element_new (int length, t8_element_t **elem) const;
-
-  /** Deallocate space for a bunch of elements. */
-  virtual void
-  t8_element_destroy (int length, t8_element_t **elem) const;
-
   /** Return the shape of an element */
   virtual t8_element_shape_t
   t8_element_shape (const t8_element_t *elem) const;
@@ -82,19 +75,6 @@ class t8_default_scheme_common_c: public t8_eclass_scheme_c {
   virtual t8_gloidx_t
   t8_element_count_leaves_from_root (int level) const;
 
-  /** The common implementation of the general function for the default scheme
-   * has no effect. This function literally does nothing.
-   * The tri, tet and prism scheme override this implementation with a function that
-   * stores the type of the element in \a outdata.
-   *  \param [in] elem A valid element
-   *  \param [in] indata Is ignored. Can be NULL.
-   *  \param [out] outdata Is ignored. Can be NULL.
-   * \note Calling this function has no effect. See the specialized implementations in
-   * t8_default_tri_cxx.hxx, t8_default_tet_cxx.hxx and t8_default_prism_cxx.hxx.
-   */
-  virtual void
-  t8_element_general_function (const t8_element_t *elem, const void *indata, void *outdata) const;
-
   /** Compute the integer coordinates of a given element vertex.
    * The default scheme implements the Morton type SFCs. In these SFCs the
    * elements are positioned in a cube [0,1]^(dL) with dimension d (=0,1,2,3) and 
@@ -137,10 +117,6 @@ class t8_default_scheme_common_c: public t8_eclass_scheme_c {
   virtual void
   t8_element_anchor (const t8_element_t *elem, int anchor[3]) const
     = 0;
-#if T8_ENABLE_DEBUG
-  virtual void
-  t8_element_debug_print (const t8_element_t *elem) const;
-#endif
 };
 
 #endif /* !T8_DEFAULT_COMMON_CXX_HXX */
diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.cxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.cxx
index c66fcd9614..e6997c94c3 100644
--- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex_cxx.cxx
@@ -646,11 +646,8 @@ t8_default_scheme_hex_c::t8_element_to_string (const t8_element_t *elem, char *d
 #endif
 
 /* Constructor */
-t8_default_scheme_hex_c::t8_default_scheme_hex_c (void)
+t8_default_scheme_hex_c::t8_default_scheme_hex_c (void): t8_default_scheme_common_c (T8_ECLASS_HEX, sizeof (t8_phex_t))
 {
-  eclass = T8_ECLASS_HEX;
-  element_size = sizeof (t8_phex_t);
-  ts_context = sc_mempool_new (element_size);
 }
 
 t8_default_scheme_hex_c::~t8_default_scheme_hex_c ()
diff --git a/src/t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.cxx b/src/t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.cxx
index 42b3610eb7..ce8f4239f3 100644
--- a/src/t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_line/t8_default_line_cxx.cxx
@@ -442,10 +442,8 @@ t8_default_scheme_line_c::t8_element_init (int length, t8_element_t *elem, int n
 
 /* Constructor */
 t8_default_scheme_line_c::t8_default_scheme_line_c (void)
+  : t8_default_scheme_common_c (T8_ECLASS_LINE, sizeof (t8_default_line_t))
 {
-  eclass = T8_ECLASS_LINE;
-  element_size = sizeof (t8_default_line_t);
-  ts_context = sc_mempool_new (element_size);
 }
 
 t8_default_scheme_line_c::~t8_default_scheme_line_c ()
diff --git a/src/t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.cxx b/src/t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.cxx
index 81d61c1f73..5f227f8195 100644
--- a/src/t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_prism/t8_default_prism_cxx.cxx
@@ -462,10 +462,8 @@ t8_default_scheme_prism_c::t8_element_to_string (const t8_element_t *elem, char
 
 /* Constructor */
 t8_default_scheme_prism_c::t8_default_scheme_prism_c (void)
+  : t8_default_scheme_common_c (T8_ECLASS_PRISM, sizeof (t8_default_prism_t))
 {
-  eclass = T8_ECLASS_PRISM;
-  element_size = sizeof (t8_default_prism_t);
-  ts_context = sc_mempool_new (element_size);
 }
 
 t8_default_scheme_prism_c::~t8_default_scheme_prism_c ()
diff --git a/src/t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.cxx b/src/t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.cxx
index cf5dad9f25..940a9bf599 100644
--- a/src/t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_pyramid/t8_default_pyramid_cxx.cxx
@@ -429,10 +429,8 @@ t8_default_scheme_pyramid_c::t8_element_to_string (const t8_element_t *elem, cha
 
 /* Constructor */
 t8_default_scheme_pyramid_c::t8_default_scheme_pyramid_c (void)
+  : t8_default_scheme_common_c (T8_ECLASS_PYRAMID, sizeof (t8_default_pyramid_t))
 {
-  eclass = T8_ECLASS_PYRAMID;
-  element_size = sizeof (t8_default_pyramid_t);
-  ts_context = sc_mempool_new (element_size);
 }
 
 t8_default_scheme_pyramid_c::~t8_default_scheme_pyramid_c ()
diff --git a/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.cxx b/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.cxx
index 153eb73aef..481029cafe 100644
--- a/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_quad/t8_default_quad_cxx.cxx
@@ -778,10 +778,8 @@ t8_default_scheme_quad_c::t8_element_to_string (const t8_element_t *elem, char *
 
 /* Constructor */
 t8_default_scheme_quad_c::t8_default_scheme_quad_c (void)
+  : t8_default_scheme_common_c (T8_ECLASS_QUAD, sizeof (t8_pquad_t))
 {
-  eclass = T8_ECLASS_QUAD;
-  element_size = sizeof (t8_pquad_t);
-  ts_context = sc_mempool_new (element_size);
 }
 
 t8_default_scheme_quad_c::~t8_default_scheme_quad_c ()
diff --git a/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.cxx b/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.cxx
index 1530cc60b2..c2e3f4f22e 100644
--- a/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_tet/t8_default_tet_cxx.cxx
@@ -548,11 +548,8 @@ t8_default_scheme_tet_c::t8_element_init (int length, t8_element_t *elem, int ne
 }
 
 /* Constructor */
-t8_default_scheme_tet_c::t8_default_scheme_tet_c (void)
+t8_default_scheme_tet_c::t8_default_scheme_tet_c (void): t8_default_scheme_common_c (T8_ECLASS_TET, sizeof (t8_dtet_t))
 {
-  eclass = T8_ECLASS_TET;
-  element_size = sizeof (t8_dtet_t);
-  ts_context = sc_mempool_new (element_size);
 }
 
 /* Destructor */
diff --git a/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.cxx b/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.cxx
index a32f57c01d..3d7af278ba 100644
--- a/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_tri/t8_default_tri_cxx.cxx
@@ -558,10 +558,8 @@ t8_default_scheme_tri_c::t8_element_init (int length, t8_element_t *elem, int ne
 
 /* Constructor */
 t8_default_scheme_tri_c::t8_default_scheme_tri_c (void)
+  : t8_default_scheme_common_c (T8_ECLASS_TRIANGLE, sizeof (t8_dtri_t))
 {
-  eclass = T8_ECLASS_TRIANGLE;
-  element_size = sizeof (t8_dtri_t);
-  ts_context = sc_mempool_new (element_size);
 }
 
 /* Destructor */
diff --git a/src/t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.cxx b/src/t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.cxx
index c17d7a6c3a..4479027338 100644
--- a/src/t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.cxx
+++ b/src/t8_schemes/t8_default/t8_default_vertex/t8_default_vertex_cxx.cxx
@@ -339,10 +339,8 @@ t8_default_scheme_vertex_c::t8_element_init (int length, t8_element_t *elem, int
 
 /* Constructor */
 t8_default_scheme_vertex_c::t8_default_scheme_vertex_c (void)
+  : t8_default_scheme_common_c (T8_ECLASS_VERTEX, sizeof (t8_dvertex_t))
 {
-  eclass = T8_ECLASS_VERTEX;
-  element_size = sizeof (t8_dvertex_t);
-  ts_context = sc_mempool_new (element_size);
 }
 
 /* Destructor */
diff --git a/src/t8_schemes/t8_scheme_mempool_cxx.hxx b/src/t8_schemes/t8_scheme_mempool_cxx.hxx
new file mode 100644
index 0000000000..29059c4298
--- /dev/null
+++ b/src/t8_schemes/t8_scheme_mempool_cxx.hxx
@@ -0,0 +1,99 @@
+/*
+  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.
+*/
+
+/** \file t8_default_common_cxx.hxx
+ * We provide some functions that are useful across element classes.
+ */
+
+#ifndef T8_SCHEME_COMMON_CXX
+#define T8_SCHEME_COMMON_CXX
+
+#include <t8_element_cxx.hxx>
+#include <t8_element.h>
+#include <sc_functions.h>
+
+/* Macro to check whether a pointer (VAR) to a base class, comes from an
+ * implementation of a child class (TYPE). */
+#define T8_SCHEME_IS_TYPE(VAR, TYPE) ((dynamic_cast<TYPE> (VAR)) != NULL)
+
+class t8_scheme_mempool_c: public t8_eclass_scheme_c {
+ public:
+  /** Destructor for all default schemes */
+  virtual ~t8_scheme_mempool_c ()
+  {
+    T8_ASSERT (ts_context != NULL);
+    SC_ASSERT (((sc_mempool_t *) ts_context)->elem_count == 0);
+    sc_mempool_destroy ((sc_mempool_t *) ts_context);
+  }
+  t8_scheme_mempool_c (t8_eclass_t eclass_in, int elem_size)
+  {
+    element_size = elem_size;
+    ts_context = sc_mempool_new (element_size);
+    eclass = eclass_in;
+  }
+
+  virtual void
+  t8_element_new (int length, t8_element_t **elem) const
+  {
+    T8_ASSERT (ts_context != NULL);
+    T8_ASSERT (0 <= length);
+    T8_ASSERT (elem != NULL);
+    sc_mempool_t *mempool = (sc_mempool_t *) this->ts_context;
+    for (int i = 0; i < length; ++i) {
+      elem[i] = (t8_element_t *) sc_mempool_alloc (mempool);
+    }
+  }
+
+  virtual void
+  t8_element_destroy (int length, t8_element_t **elem) const
+  {
+    T8_ASSERT (ts_context != NULL);
+    T8_ASSERT (0 <= length);
+    T8_ASSERT (elem != NULL);
+    sc_mempool_t *mempool = (sc_mempool_t *) this->ts_context;
+    for (int i = 0; i < length; ++i) {
+      sc_mempool_free (mempool, elem[i]);
+    }
+  }
+#if T8_ENABLE_DEBUG
+  virtual void
+  t8_element_debug_print (const t8_element_t *elem) const
+  {
+    char debug_string[BUFSIZ];
+    t8_element_to_string (elem, debug_string, BUFSIZ);
+    t8_debugf ("%s\n", debug_string);
+  }
+#endif
+
+  virtual void
+  t8_element_general_function (const t8_element_t *elem, const void *indata, void *outdata) const
+  {
+  }
+
+  virtual t8_eclass_t
+  t8_element_child_eclass (int childid) const
+  {
+    return eclass;
+  }
+};
+
+#endif /* T8_SCHEME_COMMON_CXX */

From af56b77084202b776c9d9aead9640ad12295997d Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Mon, 19 Feb 2024 12:10:06 +0100
Subject: [PATCH 02/15] rename ts_context to mempool in correct class

---
 src/t8_element_cxx.hxx                   |  1 -
 src/t8_schemes/t8_scheme_mempool_cxx.hxx | 17 +++++++++--------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/t8_element_cxx.hxx b/src/t8_element_cxx.hxx
index e2135a701c..d054a66c33 100644
--- a/src/t8_element_cxx.hxx
+++ b/src/t8_element_cxx.hxx
@@ -48,7 +48,6 @@ struct t8_eclass_scheme
   /** This scheme defines the operations for a particular element class. */
  protected:
   size_t element_size; /**< The size in bytes of an element of class \a eclass */
-  void *ts_context;    /**< Anonymous implementation context. */
 
  public:
   t8_eclass_t eclass;
diff --git a/src/t8_schemes/t8_scheme_mempool_cxx.hxx b/src/t8_schemes/t8_scheme_mempool_cxx.hxx
index 29059c4298..0bafa3b186 100644
--- a/src/t8_schemes/t8_scheme_mempool_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_mempool_cxx.hxx
@@ -36,28 +36,30 @@
 #define T8_SCHEME_IS_TYPE(VAR, TYPE) ((dynamic_cast<TYPE> (VAR)) != NULL)
 
 class t8_scheme_mempool_c: public t8_eclass_scheme_c {
+ private:
+  sc_mempool_t *mempool;
+
  public:
   /** Destructor for all default schemes */
   virtual ~t8_scheme_mempool_c ()
   {
-    T8_ASSERT (ts_context != NULL);
-    SC_ASSERT (((sc_mempool_t *) ts_context)->elem_count == 0);
-    sc_mempool_destroy ((sc_mempool_t *) ts_context);
+    T8_ASSERT (mempool != NULL);
+    SC_ASSERT (mempool->elem_count == 0);
+    sc_mempool_destroy (mempool);
   }
   t8_scheme_mempool_c (t8_eclass_t eclass_in, int elem_size)
   {
     element_size = elem_size;
-    ts_context = sc_mempool_new (element_size);
+    mempool = sc_mempool_new (element_size);
     eclass = eclass_in;
   }
 
   virtual void
   t8_element_new (int length, t8_element_t **elem) const
   {
-    T8_ASSERT (ts_context != NULL);
+    T8_ASSERT (mempool != NULL);
     T8_ASSERT (0 <= length);
     T8_ASSERT (elem != NULL);
-    sc_mempool_t *mempool = (sc_mempool_t *) this->ts_context;
     for (int i = 0; i < length; ++i) {
       elem[i] = (t8_element_t *) sc_mempool_alloc (mempool);
     }
@@ -66,10 +68,9 @@ class t8_scheme_mempool_c: public t8_eclass_scheme_c {
   virtual void
   t8_element_destroy (int length, t8_element_t **elem) const
   {
-    T8_ASSERT (ts_context != NULL);
+    T8_ASSERT (mempool != NULL);
     T8_ASSERT (0 <= length);
     T8_ASSERT (elem != NULL);
-    sc_mempool_t *mempool = (sc_mempool_t *) this->ts_context;
     for (int i = 0; i < length; ++i) {
       sc_mempool_free (mempool, elem[i]);
     }

From 45b28efaca284535be5b2416d768e388e3624b9e Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Thu, 22 Feb 2024 14:31:30 +0100
Subject: [PATCH 03/15] Add scheme algorithms base

---
 .../t8_default_common_cxx.hxx                 |   6 +-
 src/t8_schemes/t8_scheme_common_cxx.hxx       | 315 ++++++++++++++++++
 src/t8_schemes/t8_scheme_mempool_cxx.hxx      | 100 ------
 3 files changed, 318 insertions(+), 103 deletions(-)
 create mode 100644 src/t8_schemes/t8_scheme_common_cxx.hxx
 delete mode 100644 src/t8_schemes/t8_scheme_mempool_cxx.hxx

diff --git a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
index bc772e73d3..06ff7b5719 100644
--- a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
@@ -28,16 +28,16 @@
 #define T8_DEFAULT_COMMON_CXX_HXX
 
 #include <t8_element_cxx.hxx>
-#include <t8_schemes/t8_scheme_mempool_cxx.hxx>
+#include <t8_schemes/t8_scheme_common_cxx.hxx>
 
 /* Macro to check whether a pointer (VAR) to a base class, comes from an
  * implementation of a child class (TYPE). */
 #define T8_COMMON_IS_TYPE(VAR, TYPE) ((dynamic_cast<TYPE> (VAR)) != NULL)
 
-class t8_default_scheme_common_c: public t8_scheme_mempool_c {
+class t8_default_scheme_common_c: public t8_scheme_common_c {
  public:
   /* Call parent constructor */
-  t8_default_scheme_common_c (t8_eclass_t eclass, int elem_size): t8_scheme_mempool_c (eclass, elem_size) {};
+  t8_default_scheme_common_c (t8_eclass_t eclass, int elem_size): t8_scheme_common_c (eclass, elem_size) {};
 
   /** Compute the number of corners of a given element. */
   virtual int
diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
new file mode 100644
index 0000000000..987704e474
--- /dev/null
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -0,0 +1,315 @@
+/*
+  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.
+*/
+
+/** \file t8_scheme_common_cxx.hxx
+ * We provide some functions that are useful across schemes.
+ */
+
+#ifndef T8_SCHEME_COMMON_CXX
+#define T8_SCHEME_COMMON_CXX
+
+#include <t8_element_cxx.hxx>
+#include <t8_element.h>
+#include <sc_functions.h>
+
+class t8_scheme_common_c: public t8_eclass_scheme_c {
+ private:
+  sc_mempool_t *mempool;
+
+ public:
+  /** Destructor for all default schemes */
+  virtual ~t8_scheme_common_c ()
+  {
+    T8_ASSERT (mempool != NULL);
+    SC_ASSERT (mempool->elem_count == 0);
+    sc_mempool_destroy (mempool);
+  }
+  t8_scheme_common_c (t8_eclass_t eclass_in, int elem_size)
+  {
+    element_size = elem_size;
+    mempool = sc_mempool_new (element_size);
+    eclass = eclass_in;
+  }
+
+  /** Use a mempool to get allocate */
+  virtual void
+  t8_element_new (int length, t8_element_t **elem) const
+  {
+    T8_ASSERT (mempool != NULL);
+    T8_ASSERT (0 <= length);
+    T8_ASSERT (elem != NULL);
+    for (int i = 0; i < length; ++i) {
+      elem[i] = (t8_element_t *) sc_mempool_alloc (mempool);
+    }
+  }
+
+  virtual void
+  t8_element_destroy (int length, t8_element_t **elem) const
+  {
+    T8_ASSERT (mempool != NULL);
+    T8_ASSERT (0 <= length);
+    T8_ASSERT (elem != NULL);
+    for (int i = 0; i < length; ++i) {
+      sc_mempool_free (mempool, elem[i]);
+    }
+  }
+#if T8_ENABLE_DEBUG
+  virtual void
+  t8_element_debug_print (const t8_element_t *elem) const
+  {
+    char debug_string[BUFSIZ];
+    t8_element_to_string (elem, debug_string, BUFSIZ);
+    t8_debugf ("%s\n", debug_string);
+  }
+#endif
+
+  virtual void
+  t8_element_general_function (const t8_element_t *elem, const void *indata, void *outdata) const
+  {
+  }
+
+  virtual t8_eclass_t
+  t8_element_child_eclass (int childid) const
+  {
+    return eclass;
+  }
+
+  virtual int
+  t8_element_is_family (t8_element_t **fam) const override
+  {
+    if (t8_element_level (fam[0]) == 0)
+      return 0;
+    t8_element_t *parent, *parent_compare;
+    t8_element_new (1, &parent);
+    t8_element_new (1, &parent_compare);
+    t8_element_parent (fam[0], parent);
+    int num_children = t8_element_num_children (parent);
+    bool is_family = true;
+    for (int ichild = 1; ichild < num_children; ichild++) {
+      t8_element_parent (fam[ichild], parent_compare);
+      if (!t8_element_equal (parent, parent_compare)) {
+        is_family = false;
+        break;
+      }
+    }
+    t8_element_destroy (1, &parent);
+    t8_element_destroy (1, &parent_compare);
+    return is_family;
+  }
+
+  t8_linearidx_t
+  t8_element_linear_id_recursive (t8_element_t *elem, const t8_linearidx_t id, const int level) const
+  {
+    if (t8_element_level (elem) == 0)
+      return id;
+
+    const int childid = t8_element_child_id (elem);
+    t8_element_parent (elem, elem);
+
+    t8_linearidx_t parent_id = 0;
+    for (int ichild = 0; ichild < childid; ichild++) {
+      t8_element_child (elem, ichild, elem);
+      t8_linearidx_t num_child_descendants = t8_element_count_leaves (elem, level);
+      t8_element_parent (elem, elem);
+      parent_id += num_child_descendants;
+    }
+    parent_id += id;
+    return t8_element_linear_id_recursive (elem, parent_id, level);
+  }
+
+  void
+  t8_element_init_linear_id_recursive (t8_element_t *elem, const int level, t8_linearidx_t id) const
+  {
+    T8_ASSERT (0 <= id);
+    T8_ASSERT (0 <= t8_element_level (elem) && t8_element_level (elem) <= level);
+
+    if (id == 0) {
+      t8_element_first_descendant (elem, elem, level);
+      return;
+    }
+
+    T8_ASSERT (t8_element_level (elem) < level);
+
+    if (t8_element_level (elem) + 1 == level) {
+      T8_ASSERT (id <= (long unsigned int) t8_element_num_children (elem));
+      t8_element_child (elem, id, elem);
+      return;
+    }
+
+    t8_linearidx_t sum_descendants_of_children_before = 0;
+    t8_linearidx_t num_descendants_of_child = 0;
+    int childindex;
+    for (childindex = 0; childindex < t8_element_num_children (elem); childindex++) {
+      t8_element_child (elem, childindex, elem);
+      num_descendants_of_child = t8_element_count_leaves (elem, level);
+      t8_element_parent (elem, elem);
+
+      sum_descendants_of_children_before += num_descendants_of_child;
+      if (sum_descendants_of_children_before > id) {
+        sum_descendants_of_children_before -= num_descendants_of_child;
+        break;
+      }
+    }
+    t8_element_child (elem, childindex, elem);
+    t8_element_init_linear_id_recursive (elem, level, id - sum_descendants_of_children_before);
+  }
+
+  virtual void
+  t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const override
+  {
+    t8_element_init (1, elem, 0); /* TODO: replace by t8_element_root */
+    t8_element_init_linear_id_recursive (elem, level, id);
+  }
+
+  virtual t8_linearidx_t
+  t8_element_get_linear_id (const t8_element_t *elem, int level) const override
+  {
+    t8_element_t *rec_start;
+    t8_element_new (1, &rec_start);
+    /* Determine desc or anc on level */
+    if (level > t8_element_level (elem)) {
+      t8_element_first_descendant (elem, rec_start, level);
+    }
+    else {
+      t8_element_copy (elem, rec_start);
+      while (t8_element_level (rec_start) > level) {
+        t8_element_parent (rec_start, rec_start);
+      }
+    }
+
+    /* Maybe we can also input p into recursive function and calculate id directly for first desc */
+    t8_linearidx_t id = t8_element_linear_id_recursive (rec_start, 0, t8_element_level (rec_start));
+    T8_ASSERT (id >= 0);
+    t8_element_destroy (1, &rec_start);
+    return id;
+  }
+
+  virtual void
+  t8_element_first_descendant (const t8_element_t *elem, t8_element_t *desc, int level) const override
+  {
+    t8_element_copy (elem, desc);
+    while (t8_element_level (desc) < level) {
+      t8_element_child (desc, 0, desc);
+    }
+  }
+
+  virtual void
+  t8_element_last_descendant (const t8_element_t *elem, t8_element_t *desc, int level) const override
+  {
+    t8_element_copy (elem, desc);
+    while (t8_element_level (desc) < level) {
+      t8_element_child (desc, t8_element_num_children (desc) - 1, desc);
+    }
+  }
+
+  virtual void
+  t8_element_successor (const t8_element_t *elem1, t8_element_t *elem2, int level) const override
+  {
+    T8_ASSERT (level != 0);
+    T8_ASSERT (level == t8_element_level (elem1)); /* TODO: if this is true, do we need level in interface? */
+    int child_id = t8_element_child_id (elem1);
+    if (child_id + 1 == t8_element_num_siblings (elem1)) {
+      t8_element_parent (elem1, elem2);
+      t8_element_successor (elem2, elem2, level - 1);
+      t8_element_child (elem2, 0, elem2);
+    }
+    else {
+      t8_element_sibling (elem1, child_id + 1, elem2);
+    }
+  }
+  /*****/
+  virtual int
+  t8_element_ancestor_id (const t8_element_t *elem, int level) const override
+  {
+    T8_ASSERT (0 < level);
+    T8_ASSERT (level <= t8_element_level (elem));
+    t8_element_t *anc;
+    t8_element_new (1, &anc);
+    t8_element_copy (elem, anc);
+    while (t8_element_level (anc) > level) {
+      t8_element_parent (anc, anc);
+    }
+    int child_id = t8_element_child_id (anc);
+    t8_element_destroy (1, &anc);
+    return child_id;
+  }
+
+  virtual void
+  t8_element_nca (const t8_element_t *elem1, const t8_element_t *elem2, t8_element_t *nca) const override
+  {
+    t8_element_t *anc1;
+    t8_element_t *anc2;
+    t8_element_new (1, &anc1);
+    t8_element_new (1, &anc2);
+    t8_element_copy (elem1, anc1);
+    t8_element_copy (elem2, anc2);
+
+    while (t8_element_level (anc1) > t8_element_level (anc2))
+      t8_element_parent (anc1, anc1);
+    while (t8_element_level (anc1) < t8_element_level (anc2))
+      t8_element_parent (anc2, anc2);
+
+    while (!t8_element_equal (anc1, anc2)) {
+      t8_element_parent (anc1, anc1);
+      t8_element_parent (anc2, anc2);
+    }
+    t8_element_copy (anc1, nca);
+    t8_element_destroy (1, &anc1);
+    t8_element_destroy (1, &anc2);
+  }
+
+  virtual void
+  t8_element_children (const t8_element_t *elem, int length, t8_element_t *children[]) const override
+  {
+    T8_ASSERT (length == t8_element_num_children (elem));
+    for (int ichild = 0; ichild < length; ichild++) {
+      t8_element_child (elem, ichild, children[ichild]);
+    }
+  }
+
+  virtual void
+  t8_element_sibling (const t8_element_t *elem, int sibid, t8_element_t *sibling) const override
+  {
+    T8_ASSERT (t8_element_is_valid (elem));
+    T8_ASSERT (t8_element_is_valid (sibling));
+    t8_element_parent (elem, sibling);
+    t8_element_child (sibling, sibid, sibling);
+  }
+
+  /** compute linear ids of both elems. Compare ids, if they are equal, compare levels*/
+  virtual int
+  t8_element_compare (const t8_element_t *elem1, const t8_element_t *elem2) const override
+  {
+    T8_ASSERT (t8_element_is_valid (elem1));
+    T8_ASSERT (t8_element_is_valid (elem2));
+    int level1 = t8_element_level (elem1);
+    int level2 = t8_element_level (elem2);
+    int maxlevel = SC_MAX (level1, level2);
+    t8_linearidx_t id1 = t8_element_get_linear_id (elem1, maxlevel);
+    t8_linearidx_t id2 = t8_element_get_linear_id (elem2, maxlevel);
+    return id1 < id2 ? -1 : (id1 > id2 ? 1 : (level1 < level2 ? -1 : (level1 > level2 ? 1 : 0)));
+  }
+
+  /** Return SC_ABORT for all */
+};
+
+#endif /* T8_SCHEME_COMMON_CXX */
diff --git a/src/t8_schemes/t8_scheme_mempool_cxx.hxx b/src/t8_schemes/t8_scheme_mempool_cxx.hxx
deleted file mode 100644
index 0bafa3b186..0000000000
--- a/src/t8_schemes/t8_scheme_mempool_cxx.hxx
+++ /dev/null
@@ -1,100 +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) 2015 the developers
-
-  t8code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  t8code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with t8code; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-
-/** \file t8_default_common_cxx.hxx
- * We provide some functions that are useful across element classes.
- */
-
-#ifndef T8_SCHEME_COMMON_CXX
-#define T8_SCHEME_COMMON_CXX
-
-#include <t8_element_cxx.hxx>
-#include <t8_element.h>
-#include <sc_functions.h>
-
-/* Macro to check whether a pointer (VAR) to a base class, comes from an
- * implementation of a child class (TYPE). */
-#define T8_SCHEME_IS_TYPE(VAR, TYPE) ((dynamic_cast<TYPE> (VAR)) != NULL)
-
-class t8_scheme_mempool_c: public t8_eclass_scheme_c {
- private:
-  sc_mempool_t *mempool;
-
- public:
-  /** Destructor for all default schemes */
-  virtual ~t8_scheme_mempool_c ()
-  {
-    T8_ASSERT (mempool != NULL);
-    SC_ASSERT (mempool->elem_count == 0);
-    sc_mempool_destroy (mempool);
-  }
-  t8_scheme_mempool_c (t8_eclass_t eclass_in, int elem_size)
-  {
-    element_size = elem_size;
-    mempool = sc_mempool_new (element_size);
-    eclass = eclass_in;
-  }
-
-  virtual void
-  t8_element_new (int length, t8_element_t **elem) const
-  {
-    T8_ASSERT (mempool != NULL);
-    T8_ASSERT (0 <= length);
-    T8_ASSERT (elem != NULL);
-    for (int i = 0; i < length; ++i) {
-      elem[i] = (t8_element_t *) sc_mempool_alloc (mempool);
-    }
-  }
-
-  virtual void
-  t8_element_destroy (int length, t8_element_t **elem) const
-  {
-    T8_ASSERT (mempool != NULL);
-    T8_ASSERT (0 <= length);
-    T8_ASSERT (elem != NULL);
-    for (int i = 0; i < length; ++i) {
-      sc_mempool_free (mempool, elem[i]);
-    }
-  }
-#if T8_ENABLE_DEBUG
-  virtual void
-  t8_element_debug_print (const t8_element_t *elem) const
-  {
-    char debug_string[BUFSIZ];
-    t8_element_to_string (elem, debug_string, BUFSIZ);
-    t8_debugf ("%s\n", debug_string);
-  }
-#endif
-
-  virtual void
-  t8_element_general_function (const t8_element_t *elem, const void *indata, void *outdata) const
-  {
-  }
-
-  virtual t8_eclass_t
-  t8_element_child_eclass (int childid) const
-  {
-    return eclass;
-  }
-};
-
-#endif /* T8_SCHEME_COMMON_CXX */

From d381f1c739804fcb403be8c07f1d04d6f796a06a Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Thu, 29 Feb 2024 15:44:13 +0100
Subject: [PATCH 04/15] use root function instead of init

---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index 987704e474..e3c39863dc 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -176,7 +176,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual void
   t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const override
   {
-    t8_element_init (1, elem, 0); /* TODO: replace by t8_element_root */
+    t8_element_root (elem);
     t8_element_init_linear_id_recursive (elem, level, id);
   }
 

From bb730c6002f05d72f5954c9498be9a2bf4f0e9f7 Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Thu, 29 Feb 2024 15:58:46 +0100
Subject: [PATCH 05/15] Readd virtual destructor to default scheme baseclass

---
 .../t8_default/t8_default_common/t8_default_common_cxx.hxx   | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
index 06ff7b5719..fe937843ad 100644
--- a/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
+++ b/src/t8_schemes/t8_default/t8_default_common/t8_default_common_cxx.hxx
@@ -39,6 +39,11 @@ class t8_default_scheme_common_c: public t8_scheme_common_c {
   /* Call parent constructor */
   t8_default_scheme_common_c (t8_eclass_t eclass, int elem_size): t8_scheme_common_c (eclass, elem_size) {};
 
+  /* provide empty virtual destructor*/
+  virtual ~t8_default_scheme_common_c ()
+  {
+  }
+
   /** Compute the number of corners of a given element. */
   virtual int
   t8_element_num_corners (const t8_element_t *elem) const;

From 4c122cef02e0fbca3566df6d8e13d7611c6e264a Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Thu, 29 Feb 2024 19:23:56 +0100
Subject: [PATCH 06/15] Add num_siblings and count_leaves_from_root

---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index e3c39863dc..b36bb39bb8 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -286,6 +286,16 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     }
   }
 
+  virtual int
+  t8_element_num_siblings (const t8_element_t *elem) const override
+  {
+    T8_ASSERT (t8_element_is_valid (elem));
+    t8_element_t *parent;
+    t8_element_new (1, &parent);
+    t8_element_parent (elem, parent);
+    return t8_element_num_children (parent);
+  }
+
   virtual void
   t8_element_sibling (const t8_element_t *elem, int sibid, t8_element_t *sibling) const override
   {
@@ -309,6 +319,16 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     return id1 < id2 ? -1 : (id1 > id2 ? 1 : (level1 < level2 ? -1 : (level1 > level2 ? 1 : 0)));
   }
 
+  virtual t8_gloidx_t
+  t8_element_count_leaves_from_root (int level)
+  {
+    t8_element_t *root;
+    t8_element_new (1, &root);
+    t8_element_root (root);
+    t8_gloidx_t num_leaves = t8_element_count_leaves (root, level);
+    t8_element_destroy (1, &root);
+    return num_leaves;
+  }
   /** Return SC_ABORT for all */
 };
 

From 5a3867daaee15001e54e50e3bb04fe20d6f8f9e9 Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Thu, 29 Feb 2024 19:30:55 +0100
Subject: [PATCH 07/15] Add removing of facefunctionality to scheme common

---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 298 +++++++++++++++++++++++-
 1 file changed, 297 insertions(+), 1 deletion(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index b36bb39bb8..5eca543cd7 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -329,7 +329,303 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     t8_element_destroy (1, &root);
     return num_leaves;
   }
-  /** Return SC_ABORT for all */
+  /** Return SC_ABORT for all face functionality */
+
+  /** Compute the number of faces of a given element.
+   * \param [in] elem The element.
+   * \return          The number of faces of \a elem.
+   */
+  virtual int
+  t8_element_num_faces (const t8_element_t *elem) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Compute the maximum number of faces of a given element and all of its
+   *  descendants.
+   * \param [in] elem The element.
+   * \return          The maximum number of faces of \a elem and its descendants.
+   */
+  virtual int
+  t8_element_max_num_faces (const t8_element_t *elem) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Return the number of children of an element's face when the element is refined.
+   * \param [in] elem   The element whose face is considered.
+   * \param [in] face   A face of \a elem.
+   * \return            The number of children of \a face if \a elem is to be refined.
+   */
+  virtual int
+  t8_element_num_face_children (const t8_element_t *elem, int face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Return the corner number of an element's face corner.
+   * Example quad: 2 x --- x 3
+   *                 |     |
+   *                 |     |   face 1
+   *               0 x --- x 1
+   *      Thus for face = 1 the output is: corner=0 : 1, corner=1: 3
+   *
+   * \param [in] element  The element.
+   * \param [in] face     A face index for \a element.
+   * \param [in] corner   A corner index for the face 0 <= \a corner < num_face_corners.
+   * \return              The corner number of the \a corner-th vertex of \a face.
+   *
+   * The order in which the corners must be given is determined by the eclass of \a element:
+   * LINE/QUAD/TRIANGLE:  No specific order.
+   * HEX               :  In Z-order of the face starting with the lowest corner number.
+   * TET               :  Starting with the lowest corner number counterclockwise as seen from
+   *                      'outside' of the element.
+   */
+  /* TODO: Prism order, Pyramid order. */
+  virtual int
+  t8_element_get_face_corner (const t8_element_t *element, int face, int corner) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Return the face numbers of the faces sharing an element's corner.
+   * Example quad: 2 x --- x 3
+   *                 |     |
+   *                 |     |   face 1
+   *               0 x --- x 1
+   *                  face 2
+   *      Thus for corner = 1 the output is: face=0 : 2, face=1: 1
+   * \param [in] element  The element.
+   * \param [in] corner   A corner index for the face.
+   * \param [in] face     A face index for \a corner.
+   * \return              The face number of the \a face-th face at \a corner.
+   */
+  virtual int
+  t8_element_get_corner_face (const t8_element_t *element, int corner, int face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Compute the shape of the face of an element.
+   * \param [in] elem     The element.
+   * \param [in] face     A face of \a elem.
+   * \return              The element shape of the face.
+   * I.e. T8_ECLASS_LINE for quads, T8_ECLASS_TRIANGLE for tets
+   *      and depending on the face number either T8_ECLASS_QUAD or
+   *      T8_ECLASS_TRIANGLE for prisms.
+   */
+  virtual t8_element_shape_t
+  t8_element_face_shape (const t8_element_t *elem, int face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Given an element and a face of the element, compute all children of
+   * the element that touch the face.
+   * \param [in] elem     The element.
+   * \param [in] face     A face of \a elem.
+   * \param [in,out] children Allocated elements, in which the children of \a elem
+   *                      that share a face with \a face are stored.
+   *                      They will be stored in order of their linear id.
+   * \param [in] num_children The number of elements in \a children. Must match
+   *                      the number of children that touch \a face.
+   *                      \ref t8_element_num_face_children
+   * \param [in,out] child_indices If not NULL, an array of num_children integers must be given,
+   *                      on output its i-th entry is the child_id of the i-th face_child.
+   * It is valid to call this function with elem = children[0].
+   */
+  virtual void
+  t8_element_children_at_face (const t8_element_t *elem, int face, t8_element_t *children[], int num_children,
+                               int *child_indices) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Given a face of an element and a child number of a child of that face, return the face number
+   * of the child of the element that matches the child face.
+   * \verbatim
+      x ---- x   x      x           x ---- x
+      |      |   |      |           |   |  | <-- f
+      |      |   |      x           |   x--x
+      |      |   |                  |      |
+      x ---- x   x                  x ---- x
+       elem    face  face_child    Returns the face number f
+     \endverbatim
+   * \param [in]  elem    The element.
+   * \param [in]  face    Then number of the face.
+   * \param [in]  face_child A number 0 <= \a face_child < num_face_children,
+   *                      specifying a child of \a elem that shares a face with \a face.
+   *                      These children are counted in linear order. This coincides with
+   *                      the order of children from a call to \ref t8_element_children_at_face.
+   * \return              The face number of the face of a child of \a elem
+   *                      that coincides with \a face_child.
+   */
+  virtual int
+  t8_element_face_child_face (const t8_element_t *elem, int face, int face_child) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Given a face of an element return the face number
+     * of the parent of the element that matches the element's face. Or return -1 if
+     * no face of the parent matches the face.
+     * \param [in]  elem    The element.
+     * \param [in]  face    Then number of the face.
+     * \return              If \a face of \a elem is also a face of \a elem's parent,
+     *                      the face number of this face. Otherwise -1.
+     * \note For the root element this function always returns \a face.
+     */
+  virtual int
+  t8_element_face_parent_face (const t8_element_t *elem, int face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Given an element and a face of this element. If the face lies on the
+   *  tree boundary, return the face number of the tree face.
+   *  If not the return value is arbitrary.
+   *  You can call \ref t8_element_is_root_boundary to query whether the face is
+   *  at the tree boundary.
+   * \param [in] elem     The element.
+   * \param [in] face     The index of a face of \a elem.
+   * \return The index of the tree face that \a face is a subface of, if
+   *         \a face is on a tree boundary.
+   *         Any arbitrary integer if \a is not at a tree boundary.
+   * \warning The return value may look like a valid face of the tree even if 
+   *   the element does not lie on the root boundary.
+   */
+  virtual int
+  t8_element_tree_face (const t8_element_t *elem, int face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Suppose we have two trees that share a common face f.
+   *  Given an element e that is a subface of f in one of the trees
+   *  and given the orientation of the tree connection, construct the face
+   *  element of the respective tree neighbor that logically coincides with e
+   *  but lies in the coordinate system of the neighbor tree.
+   *  \param [in] elem1     The face element.
+   *  \param [in,out] elem2 On return the face element  \a elem1 with respect
+   *                        to the coordinate system of the other tree.
+   *  \param [in] orientation The orientation of the tree-tree connection.
+   *                        \see t8_cmesh_set_join
+   *  \param [in] sign      Depending on the topological orientation of the two tree faces,
+   *                        either 0 (both faces have opposite orientation)
+   *                        or 1 (both faces have the same top. orientattion).
+   *                        \ref t8_eclass_face_orientation
+   *  \param [in] is_smaller_face Flag to declare whether \a elem1 belongs to
+   *                        the smaller face. A face f of tree T is smaller than
+   *                        f' of T' if either the eclass of T is smaller or if
+   *                        the classes are equal and f<f'. The orientation is
+   *                        defined in relation to the smaller face.
+   * \note \a elem1 and \a elem2 may point to the same element.
+   */
+  virtual void
+  t8_element_transform_face (const t8_element_t *elem1, t8_element_t *elem2, int orientation, int sign,
+                             int is_smaller_face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** 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.
+   * \param [in] face     A face element.
+   * \param [in] face_scheme The scheme for the face element.
+   * \param [in,out] elem An allocated element. The entries will be filled with
+   *                      the data of the element that has \a face as a face and
+   *                      lies within the root tree.
+   * \param [in] root_face The index of the face of the root tree in which \a face
+   *                      lies.
+   * \return              The face number of the face of \a elem that coincides
+   *                      with \a face.
+   */
+  virtual int
+  t8_element_extrude_face (const t8_element_t *face, const t8_eclass_scheme_c *face_scheme, t8_element_t *elem,
+                           int root_face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Construct the boundary element at a specific face.
+   * \param [in] elem     The input element.
+   * \param [in] face     The index of the face of which to construct the
+   *                      boundary element.
+   * \param [in,out] boundary An allocated element of dimension of \a element
+   *                      minus 1. The entries will be filled with the entries
+   *                      of the face of \a element.
+   * \param [in] boundary_scheme The scheme for the eclass of the boundary face.
+   * If \a elem is of class T8_ECLASS_VERTEX, then \a boundary must be NULL
+   * and will not be modified.
+   */
+  virtual void
+  t8_element_boundary_face (const t8_element_t *elem, int face, t8_element_t *boundary,
+                            const t8_eclass_scheme_c *boundary_scheme) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Construct the first descendant of an element at a given level that touches a given face.
+   * \param [in] elem      The input element.
+   * \param [in] face      A face of \a elem.
+   * \param [in, out] first_desc An allocated element. This element's data will be
+   *                       filled with the data of the first descendant of \a elem
+   *                       that shares a face with \a face.
+   * \param [in] level     The level, at which the first descendant is constructed
+   */
+  virtual void
+  t8_element_first_descendant_face (const t8_element_t *elem, int face, t8_element_t *first_desc, int level) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Construct the last descendant of an element at a given level that touches a given face.
+   * \param [in] elem      The input element.
+   * \param [in] face      A face of \a elem.
+   * \param [in, out] last_desc An allocated element. This element's data will be
+   *                       filled with the data of the last descendant of \a elem
+   *                       that shares a face with \a face.
+   * \param [in] level     The level, at which the last descendant is constructed
+   */
+  virtual void
+  t8_element_last_descendant_face (const t8_element_t *elem, int face, t8_element_t *last_desc, int level) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Compute whether a given element shares a given face with its root tree.
+   * \param [in] elem     The input element.
+   * \param [in] face     A face of \a elem.
+   * \return              True if \a face is a subface of the element's root element.
+   * \note You can compute the corresponding face number of the tree via \ref t8_element_tree_face.
+   */
+  virtual int
+  t8_element_is_root_boundary (const t8_element_t *elem, int face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
+
+  /** Construct the face neighbor of a given element if this face neighbor
+   * is inside the root tree. Return 0 otherwise.
+   * \param [in] elem The element to be considered.
+   * \param [in,out] neigh If the face neighbor of \a elem along \a face is inside
+   *                  the root tree, this element's data is filled with the
+   *                  data of the face neighbor. Otherwise the data can be modified
+   *                  arbitrarily.
+   * \param [in] face The number of the face along which the neighbor should be
+   *                  constructed.
+   * \param [out] neigh_face The number of \a face as viewed from \a neigh.
+   *                  An arbitrary value, if the neighbor is not inside the root tree.
+   * \return          True if \a neigh is inside the root tree.
+   *                  False if not. In this case \a neigh's data can be arbitrary
+   *                  on output.
+   */
+  virtual int
+  t8_element_face_neighbor_inside (const t8_element_t *elem, t8_element_t *neigh, int face, int *neigh_face) const
+  {
+    SC_ABORT ("not yet implemented");
+  }
 };
 
 #endif /* T8_SCHEME_COMMON_CXX */

From fb94ba5b397127208b4bbc37ec549e6de84d7d92 Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Thu, 29 Feb 2024 19:41:55 +0100
Subject: [PATCH 08/15] make function const override

---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index 5eca543cd7..e408580888 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -320,7 +320,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual t8_gloidx_t
-  t8_element_count_leaves_from_root (int level)
+  t8_element_count_leaves_from_root (int level) const override
   {
     t8_element_t *root;
     t8_element_new (1, &root);

From 5ad579b5aed96c78a14b2ae221c26ecb38d3f8fc Mon Sep 17 00:00:00 2001
From: lukasdreyer <58432628+lukasdreyer@users.noreply.github.com>
Date: Wed, 6 Mar 2024 12:06:25 +0100
Subject: [PATCH 09/15] Apply suggestions from code review

update copyright

Co-authored-by: David Knapp <david.knapp@dlr.de>
---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index e408580888..4faf3cf2af 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -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) 2024 the developers
 
   t8code is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by

From 259cbe553c81d15b9adde4efd6496144f0b42e76 Mon Sep 17 00:00:00 2001
From: lukasdreyer <58432628+lukasdreyer@users.noreply.github.com>
Date: Wed, 6 Mar 2024 12:07:57 +0100
Subject: [PATCH 10/15] Apply suggestions from code review

small changes and doc

Co-authored-by: David Knapp <david.knapp@dlr.de>
---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index 4faf3cf2af..c58565a8b9 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -40,9 +40,10 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual ~t8_scheme_common_c ()
   {
     T8_ASSERT (mempool != NULL);
-    SC_ASSERT (mempool->elem_count == 0);
+    T8_ASSERT (mempool->elem_count == 0);
     sc_mempool_destroy (mempool);
   }
+  /* Constructor */
   t8_scheme_common_c (t8_eclass_t eclass_in, int elem_size)
   {
     element_size = elem_size;
@@ -57,8 +58,8 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     T8_ASSERT (mempool != NULL);
     T8_ASSERT (0 <= length);
     T8_ASSERT (elem != NULL);
-    for (int i = 0; i < length; ++i) {
-      elem[i] = (t8_element_t *) sc_mempool_alloc (mempool);
+    for (int ielem = 0; ielem < length; ++ielem) {
+      elem[ielem] = (t8_element_t *) sc_mempool_alloc (mempool);
     }
   }
 

From 08ad0c513e698024633af0e4a623ee44bcb8f28c Mon Sep 17 00:00:00 2001
From: lukasdreyer <58432628+lukasdreyer@users.noreply.github.com>
Date: Wed, 6 Mar 2024 12:09:17 +0100
Subject: [PATCH 11/15] Apply suggestions from code review

const

Co-authored-by: David Knapp <david.knapp@dlr.de>
---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 52 ++++++++++++-------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index c58565a8b9..135a371ccc 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -44,7 +44,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     sc_mempool_destroy (mempool);
   }
   /* Constructor */
-  t8_scheme_common_c (t8_eclass_t eclass_in, int elem_size)
+  t8_scheme_common_c (const t8_eclass_t eclass_in, const int elem_size)
   {
     element_size = elem_size;
     mempool = sc_mempool_new (element_size);
@@ -53,7 +53,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
 
   /** Use a mempool to get allocate */
   virtual void
-  t8_element_new (int length, t8_element_t **elem) const
+  t8_element_new (const t8_locidx_t length, t8_element_t **elem) const
   {
     T8_ASSERT (mempool != NULL);
     T8_ASSERT (0 <= length);
@@ -64,13 +64,13 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual void
-  t8_element_destroy (int length, t8_element_t **elem) const
+  t8_element_destroy (const t8_locidx_t length, t8_element_t **elem) const
   {
     T8_ASSERT (mempool != NULL);
     T8_ASSERT (0 <= length);
     T8_ASSERT (elem != NULL);
-    for (int i = 0; i < length; ++i) {
-      sc_mempool_free (mempool, elem[i]);
+    for (int ielem = 0; ielem < length; ++ielem) {
+      sc_mempool_free (mempool, elem[ielem]);
     }
   }
 #if T8_ENABLE_DEBUG
@@ -89,13 +89,13 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual t8_eclass_t
-  t8_element_child_eclass (int childid) const
+  t8_element_child_eclass (const int childid) const
   {
     return eclass;
   }
 
   virtual int
-  t8_element_is_family (t8_element_t **fam) const override
+  t8_element_is_family (const t8_element_t **fam) const override
   {
     if (t8_element_level (fam[0]) == 0)
       return 0;
@@ -103,7 +103,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     t8_element_new (1, &parent);
     t8_element_new (1, &parent_compare);
     t8_element_parent (fam[0], parent);
-    int num_children = t8_element_num_children (parent);
+    const int num_children = t8_element_num_children (parent);
     bool is_family = true;
     for (int ichild = 1; ichild < num_children; ichild++) {
       t8_element_parent (fam[ichild], parent_compare);
@@ -129,7 +129,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     t8_linearidx_t parent_id = 0;
     for (int ichild = 0; ichild < childid; ichild++) {
       t8_element_child (elem, ichild, elem);
-      t8_linearidx_t num_child_descendants = t8_element_count_leaves (elem, level);
+     const t8_linearidx_t num_child_descendants = t8_element_count_leaves (elem, level);
       t8_element_parent (elem, elem);
       parent_id += num_child_descendants;
     }
@@ -175,14 +175,14 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual void
-  t8_element_set_linear_id (t8_element_t *elem, int level, t8_linearidx_t id) const override
+  t8_element_set_linear_id (t8_element_t *elem, const int level, const t8_linearidx_t id) const override
   {
     t8_element_root (elem);
     t8_element_init_linear_id_recursive (elem, level, id);
   }
 
   virtual t8_linearidx_t
-  t8_element_get_linear_id (const t8_element_t *elem, int level) const override
+  t8_element_get_linear_id (const t8_element_t *elem, const int level) const override
   {
     t8_element_t *rec_start;
     t8_element_new (1, &rec_start);
@@ -205,7 +205,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual void
-  t8_element_first_descendant (const t8_element_t *elem, t8_element_t *desc, int level) const override
+  t8_element_first_descendant (const t8_element_t *elem, t8_element_t *desc, const int level) const override
   {
     t8_element_copy (elem, desc);
     while (t8_element_level (desc) < level) {
@@ -214,7 +214,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual void
-  t8_element_last_descendant (const t8_element_t *elem, t8_element_t *desc, int level) const override
+  t8_element_last_descendant (const t8_element_t *elem, t8_element_t *desc, const int level) const override
   {
     t8_element_copy (elem, desc);
     while (t8_element_level (desc) < level) {
@@ -223,11 +223,11 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual void
-  t8_element_successor (const t8_element_t *elem1, t8_element_t *elem2, int level) const override
+  t8_element_successor (const t8_element_t *elem1, t8_element_t *elem2, const int level) const override
   {
     T8_ASSERT (level != 0);
     T8_ASSERT (level == t8_element_level (elem1)); /* TODO: if this is true, do we need level in interface? */
-    int child_id = t8_element_child_id (elem1);
+    const int child_id = t8_element_child_id (elem1);
     if (child_id + 1 == t8_element_num_siblings (elem1)) {
       t8_element_parent (elem1, elem2);
       t8_element_successor (elem2, elem2, level - 1);
@@ -239,7 +239,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
   /*****/
   virtual int
-  t8_element_ancestor_id (const t8_element_t *elem, int level) const override
+  t8_element_ancestor_id (const t8_element_t *elem, const int level) const override
   {
     T8_ASSERT (0 < level);
     T8_ASSERT (level <= t8_element_level (elem));
@@ -249,7 +249,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     while (t8_element_level (anc) > level) {
       t8_element_parent (anc, anc);
     }
-    int child_id = t8_element_child_id (anc);
+    const int child_id = t8_element_child_id (anc);
     t8_element_destroy (1, &anc);
     return child_id;
   }
@@ -279,7 +279,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual void
-  t8_element_children (const t8_element_t *elem, int length, t8_element_t *children[]) const override
+  t8_element_children (const t8_element_t *elem, const int length, t8_element_t *children[]) const override
   {
     T8_ASSERT (length == t8_element_num_children (elem));
     for (int ichild = 0; ichild < length; ichild++) {
@@ -298,7 +298,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual void
-  t8_element_sibling (const t8_element_t *elem, int sibid, t8_element_t *sibling) const override
+  t8_element_sibling (const t8_element_t *elem, const int sibid, t8_element_t *sibling) const override
   {
     T8_ASSERT (t8_element_is_valid (elem));
     T8_ASSERT (t8_element_is_valid (sibling));
@@ -312,21 +312,21 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   {
     T8_ASSERT (t8_element_is_valid (elem1));
     T8_ASSERT (t8_element_is_valid (elem2));
-    int level1 = t8_element_level (elem1);
-    int level2 = t8_element_level (elem2);
-    int maxlevel = SC_MAX (level1, level2);
-    t8_linearidx_t id1 = t8_element_get_linear_id (elem1, maxlevel);
-    t8_linearidx_t id2 = t8_element_get_linear_id (elem2, maxlevel);
+    const int level1 = t8_element_level (elem1);
+    const int level2 = t8_element_level (elem2);
+    const int maxlevel = SC_MAX (level1, level2);
+    const t8_linearidx_t id1 = t8_element_get_linear_id (elem1, maxlevel);
+    const t8_linearidx_t id2 = t8_element_get_linear_id (elem2, maxlevel);
     return id1 < id2 ? -1 : (id1 > id2 ? 1 : (level1 < level2 ? -1 : (level1 > level2 ? 1 : 0)));
   }
 
   virtual t8_gloidx_t
-  t8_element_count_leaves_from_root (int level) const override
+  t8_element_count_leaves_from_root (const int level) const override
   {
     t8_element_t *root;
     t8_element_new (1, &root);
     t8_element_root (root);
-    t8_gloidx_t num_leaves = t8_element_count_leaves (root, level);
+    const t8_gloidx_t num_leaves = t8_element_count_leaves (root, level);
     t8_element_destroy (1, &root);
     return num_leaves;
   }

From 54267ddf13275eb2810e838b70d7f1ee7859a19c Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Wed, 6 Mar 2024 13:03:57 +0100
Subject: [PATCH 12/15] indent

---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index 135a371ccc..8300c455ba 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -129,7 +129,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     t8_linearidx_t parent_id = 0;
     for (int ichild = 0; ichild < childid; ichild++) {
       t8_element_child (elem, ichild, elem);
-     const t8_linearidx_t num_child_descendants = t8_element_count_leaves (elem, level);
+      const t8_linearidx_t num_child_descendants = t8_element_count_leaves (elem, level);
       t8_element_parent (elem, elem);
       parent_id += num_child_descendants;
     }

From 99a48d793aec609a563275db294be59b4e845b55 Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Wed, 6 Mar 2024 13:04:26 +0100
Subject: [PATCH 13/15] revert const for is_family, is not const in interface
 yet

---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index 8300c455ba..321e0ea0b4 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -95,7 +95,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual int
-  t8_element_is_family (const t8_element_t **fam) const override
+  t8_element_is_family (t8_element_t **fam) const override
   {
     if (t8_element_level (fam[0]) == 0)
       return 0;

From ad5f6cdf644b192545117cf62df314ee6874ea7f Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Thu, 7 Mar 2024 12:00:42 +0100
Subject: [PATCH 14/15] Add some comments

---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 65 +++++++++++++++++--------
 1 file changed, 45 insertions(+), 20 deletions(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index 321e0ea0b4..797eaec81d 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -21,7 +21,26 @@
 */
 
 /** \file t8_scheme_common_cxx.hxx
- * We provide some functions that are useful across schemes.
+ * This class is a helper class for implementing new schemes.
+ * It provides the following functionalities:
+ * - Mempool allocator for t8_element_new/destroy
+ * - standard implementation of dependent interface functionality.
+ *   These can be overridden by derived schemes with a more efficient implementation.
+ *   Additionally, the pure virtual face connectivity functions are implemented by an 
+ *   SC_ABORT
+ *
+ * The user basically needs to implement the following functions, to obtain a scheme that can
+ * be used to construct (NEW), refine and coarsen (ADAPT), distribute onto multiple ranks (PARTITION),
+ * and (SEARCH) a refinement tree or a forest of those:
+ * - num_children/child/parent/childid
+ * - level / maxlevel
+ * - is_regular/shape/count_leaves ()
+ * - valid/equal/to_string/copy/init
+ * 
+ * In order to use geometry information for (ADAPT), (SEARCH) and (VISUALIZE),
+ * these functions need to be implemented
+ *   - num_corners
+ *   - t8_element_vertex_reference_coords, t8_element_reference_coords
  */
 
 #ifndef T8_SCHEME_COMMON_CXX
@@ -237,7 +256,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
       t8_element_sibling (elem1, child_id + 1, elem2);
     }
   }
-  /*****/
+
   virtual int
   t8_element_ancestor_id (const t8_element_t *elem, const int level) const override
   {
@@ -264,11 +283,13 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
     t8_element_copy (elem1, anc1);
     t8_element_copy (elem2, anc2);
 
+    /* bring both elements on the same level */
     while (t8_element_level (anc1) > t8_element_level (anc2))
       t8_element_parent (anc1, anc1);
     while (t8_element_level (anc1) < t8_element_level (anc2))
       t8_element_parent (anc2, anc2);
 
+    /* Replace both elements by their parent until they are equal. */
     while (!t8_element_equal (anc1, anc2)) {
       t8_element_parent (anc1, anc1);
       t8_element_parent (anc2, anc2);
@@ -281,6 +302,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual void
   t8_element_children (const t8_element_t *elem, const int length, t8_element_t *children[]) const override
   {
+    /* iterate over all childids */
     T8_ASSERT (length == t8_element_num_children (elem));
     for (int ichild = 0; ichild < length; ichild++) {
       t8_element_child (elem, ichild, children[ichild]);
@@ -290,11 +312,14 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_num_siblings (const t8_element_t *elem) const override
   {
+    /* return the number of children of the parent element */
     T8_ASSERT (t8_element_is_valid (elem));
     t8_element_t *parent;
     t8_element_new (1, &parent);
     t8_element_parent (elem, parent);
-    return t8_element_num_children (parent);
+    int num_children = t8_element_num_children (parent);
+    t8_element_destroy (1, &parent);
+    return num_children;
   }
 
   virtual void
@@ -339,7 +364,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_num_faces (const t8_element_t *elem) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Compute the maximum number of faces of a given element and all of its
@@ -350,7 +375,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_max_num_faces (const t8_element_t *elem) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Return the number of children of an element's face when the element is refined.
@@ -361,7 +386,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_num_face_children (const t8_element_t *elem, int face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Return the corner number of an element's face corner.
@@ -386,7 +411,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_get_face_corner (const t8_element_t *element, int face, int corner) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Return the face numbers of the faces sharing an element's corner.
@@ -404,7 +429,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_get_corner_face (const t8_element_t *element, int corner, int face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Compute the shape of the face of an element.
@@ -418,7 +443,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual t8_element_shape_t
   t8_element_face_shape (const t8_element_t *elem, int face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Given an element and a face of the element, compute all children of
@@ -439,7 +464,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   t8_element_children_at_face (const t8_element_t *elem, int face, t8_element_t *children[], int num_children,
                                int *child_indices) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Given a face of an element and a child number of a child of that face, return the face number
@@ -464,7 +489,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_face_child_face (const t8_element_t *elem, int face, int face_child) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Given a face of an element return the face number
@@ -479,7 +504,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_face_parent_face (const t8_element_t *elem, int face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Given an element and a face of this element. If the face lies on the
@@ -498,7 +523,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_tree_face (const t8_element_t *elem, int face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Suppose we have two trees that share a common face f.
@@ -526,7 +551,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   t8_element_transform_face (const t8_element_t *elem1, t8_element_t *elem2, int orientation, int sign,
                              int is_smaller_face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Given a boundary face inside a root tree's face construct
@@ -546,7 +571,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   t8_element_extrude_face (const t8_element_t *face, const t8_eclass_scheme_c *face_scheme, t8_element_t *elem,
                            int root_face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Construct the boundary element at a specific face.
@@ -564,7 +589,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   t8_element_boundary_face (const t8_element_t *elem, int face, t8_element_t *boundary,
                             const t8_eclass_scheme_c *boundary_scheme) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Construct the first descendant of an element at a given level that touches a given face.
@@ -578,7 +603,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual void
   t8_element_first_descendant_face (const t8_element_t *elem, int face, t8_element_t *first_desc, int level) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Construct the last descendant of an element at a given level that touches a given face.
@@ -592,7 +617,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual void
   t8_element_last_descendant_face (const t8_element_t *elem, int face, t8_element_t *last_desc, int level) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Compute whether a given element shares a given face with its root tree.
@@ -604,7 +629,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_is_root_boundary (const t8_element_t *elem, int face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 
   /** Construct the face neighbor of a given element if this face neighbor
@@ -625,7 +650,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   virtual int
   t8_element_face_neighbor_inside (const t8_element_t *elem, t8_element_t *neigh, int face, int *neigh_face) const
   {
-    SC_ABORT ("not yet implemented");
+    SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
 };
 

From 2b59cd1a51e4bf32b27ab7e84ab72a2a5159efa1 Mon Sep 17 00:00:00 2001
From: "Dreyer, Lukas" <Lukas.Dreyer@dlr.de>
Date: Wed, 13 Mar 2024 15:01:57 +0100
Subject: [PATCH 15/15] Add override to all functions and remove those that are
 no longer part of the interface

---
 src/t8_schemes/t8_scheme_common_cxx.hxx | 54 +++++++++++--------------
 1 file changed, 23 insertions(+), 31 deletions(-)

diff --git a/src/t8_schemes/t8_scheme_common_cxx.hxx b/src/t8_schemes/t8_scheme_common_cxx.hxx
index f559b9eb44..8de165ef55 100644
--- a/src/t8_schemes/t8_scheme_common_cxx.hxx
+++ b/src/t8_schemes/t8_scheme_common_cxx.hxx
@@ -72,7 +72,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
 
   /** Use a mempool to get allocate */
   virtual void
-  t8_element_new (const t8_locidx_t length, t8_element_t **elem) const
+  t8_element_new (const t8_locidx_t length, t8_element_t **elem) const override
   {
     T8_ASSERT (mempool != NULL);
     T8_ASSERT (0 <= length);
@@ -83,7 +83,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 
   virtual void
-  t8_element_destroy (const t8_locidx_t length, t8_element_t **elem) const
+  t8_element_destroy (const t8_locidx_t length, t8_element_t **elem) const override
   {
     T8_ASSERT (mempool != NULL);
     T8_ASSERT (0 <= length);
@@ -105,7 +105,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
 
 #if T8_ENABLE_DEBUG
   virtual void
-  t8_element_debug_print (const t8_element_t *elem) const
+  t8_element_debug_print (const t8_element_t *elem) const override
   {
     char debug_string[BUFSIZ];
     t8_element_to_string (elem, debug_string, BUFSIZ);
@@ -113,17 +113,6 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
   }
 #endif
 
-  virtual void
-  t8_element_general_function (const t8_element_t *elem, const void *indata, void *outdata) const
-  {
-  }
-
-  virtual t8_eclass_t
-  t8_element_child_eclass (const int childid) const
-  {
-    return eclass;
-  }
-
   virtual int
   t8_element_is_family (t8_element_t *const *fam) const override
   {
@@ -372,7 +361,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    * \return          The number of faces of \a elem.
    */
   virtual int
-  t8_element_num_faces (const t8_element_t *elem) const
+  t8_element_num_faces (const t8_element_t *elem) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -383,7 +372,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    * \return          The maximum number of faces of \a elem and its descendants.
    */
   virtual int
-  t8_element_max_num_faces (const t8_element_t *elem) const
+  t8_element_max_num_faces (const t8_element_t *elem) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -394,7 +383,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    * \return            The number of children of \a face if \a elem is to be refined.
    */
   virtual int
-  t8_element_num_face_children (const t8_element_t *elem, int face) const
+  t8_element_num_face_children (const t8_element_t *elem, int face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -419,7 +408,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    */
   /* TODO: Prism order, Pyramid order. */
   virtual int
-  t8_element_get_face_corner (const t8_element_t *element, int face, int corner) const
+  t8_element_get_face_corner (const t8_element_t *element, int face, int corner) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -437,7 +426,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    * \return              The face number of the \a face-th face at \a corner.
    */
   virtual int
-  t8_element_get_corner_face (const t8_element_t *element, int corner, int face) const
+  t8_element_get_corner_face (const t8_element_t *element, int corner, int face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -451,7 +440,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    *      T8_ECLASS_TRIANGLE for prisms.
    */
   virtual t8_element_shape_t
-  t8_element_face_shape (const t8_element_t *elem, int face) const
+  t8_element_face_shape (const t8_element_t *elem, int face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -472,7 +461,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    */
   virtual void
   t8_element_children_at_face (const t8_element_t *elem, int face, t8_element_t *children[], int num_children,
-                               int *child_indices) const
+                               int *child_indices) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -497,7 +486,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    *                      that coincides with \a face_child.
    */
   virtual int
-  t8_element_face_child_face (const t8_element_t *elem, int face, int face_child) const
+  t8_element_face_child_face (const t8_element_t *elem, int face, int face_child) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -512,7 +501,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
      * \note For the root element this function always returns \a face.
      */
   virtual int
-  t8_element_face_parent_face (const t8_element_t *elem, int face) const
+  t8_element_face_parent_face (const t8_element_t *elem, int face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -531,7 +520,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    *   the element does not lie on the root boundary.
    */
   virtual int
-  t8_element_tree_face (const t8_element_t *elem, int face) const
+  t8_element_tree_face (const t8_element_t *elem, int face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -559,7 +548,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    */
   virtual void
   t8_element_transform_face (const t8_element_t *elem1, t8_element_t *elem2, int orientation, int sign,
-                             int is_smaller_face) const
+                             int is_smaller_face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -579,7 +568,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    */
   virtual int
   t8_element_extrude_face (const t8_element_t *face, const t8_eclass_scheme_c *face_scheme, t8_element_t *elem,
-                           int root_face) const
+                           int root_face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -597,7 +586,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    */
   virtual void
   t8_element_boundary_face (const t8_element_t *elem, int face, t8_element_t *boundary,
-                            const t8_eclass_scheme_c *boundary_scheme) const
+                            const t8_eclass_scheme_c *boundary_scheme) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -611,7 +600,8 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    * \param [in] level     The level, at which the first descendant is constructed
    */
   virtual void
-  t8_element_first_descendant_face (const t8_element_t *elem, int face, t8_element_t *first_desc, int level) const
+  t8_element_first_descendant_face (const t8_element_t *elem, int face, t8_element_t *first_desc,
+                                    int level) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -625,7 +615,8 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    * \param [in] level     The level, at which the last descendant is constructed
    */
   virtual void
-  t8_element_last_descendant_face (const t8_element_t *elem, int face, t8_element_t *last_desc, int level) const
+  t8_element_last_descendant_face (const t8_element_t *elem, int face, t8_element_t *last_desc,
+                                   int level) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -637,7 +628,7 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    * \note You can compute the corresponding face number of the tree via \ref t8_element_tree_face.
    */
   virtual int
-  t8_element_is_root_boundary (const t8_element_t *elem, int face) const
+  t8_element_is_root_boundary (const t8_element_t *elem, int face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }
@@ -658,7 +649,8 @@ class t8_scheme_common_c: public t8_eclass_scheme_c {
    *                  on output.
    */
   virtual int
-  t8_element_face_neighbor_inside (const t8_element_t *elem, t8_element_t *neigh, int face, int *neigh_face) const
+  t8_element_face_neighbor_inside (const t8_element_t *elem, t8_element_t *neigh, int face,
+                                   int *neigh_face) const override
   {
     SC_ABORT ("Not implemented in baseclass. Needs to be implemented in derived class.");
   }