From 1fdb864b4bdb9b7c224353743287667751e11596 Mon Sep 17 00:00:00 2001 From: David Knapp Date: Wed, 10 Dec 2025 16:36:59 +0100 Subject: [PATCH 1/6] Startet implementation of an adaption-class to simplify the addition of different adaptation styles --- .../t8_forest_adapt/t8_forest_adapt.cxx | 76 +++++++++ .../t8_forest_adapt/t8_forest_adapt.hxx | 148 ++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx create mode 100644 src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx diff --git a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx new file mode 100644 index 0000000000..f981227cd5 --- /dev/null +++ b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx @@ -0,0 +1,76 @@ +/* + 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. +*/ + +/** + * \file t8_forest_adapt/t8_forest_adapt.cxx + * Implementation of the adaptation routine to refine and coarsen a forest of trees. + */ + + #include + + + + void + t8_forest_adapt::basic_adaptation::adapt() + { + T8_ASSERT (forest != nullptr); + + if (profiling) { + profile_adaptation(); + } + T8_ASSERT (forest_from != nullptr); + + collect_adapt_actions(); + + t8_locidx_t el_offset = 0; + const t8_locidx_t num_trees = t8_forest_get_num_trees (forest_from); + + for (t8_locidx_t ltree_id = 0; ltree_id < num_trees; ltree_id++) { + t8_tree_t tree = t8_forest_get_tree (forest, ltree_id); + const t8_tree_t tree_from = t8_forest_get_tree (forest_from, ltree_id); + t8_element_array_t elements = &tree->leaf_elements; + const t8_element_array_t tree_elements_from = &tree_from->leaf_elements; + const t8_locidx_t num_el_from = (t8_locidx_t) t8_element_array_get_count (tree_elements_from); + T8_ASSERT (num_el_from == t8_forest_get_tree_num_leaf_elements (forest_from, ltree_id)); + const t8_eclass_t tree_class = tree_from->tree_class; + /* Continue only if tree_from is not empty */ + if (num_el_from < 0){ + const t8_element_t *first_element_from = t8_element_array_index_locidx (tree_elements_from, 0); + t8_locidx_t curr_size_elements_from = scheme->element_get_num_siblings (tree_class, first_element_from); + t8_locidx_t el_considered = 0; + std::vector elements_from; + + while (el_considered < num_el_from) { + const t8_locidx_t num_siblings = scheme->element_get_num_siblings (tree_class, t8_element_array_index_locidx (tree_elements_from, el_considered)); + if (num_siblings > curr_size_elements_from) { + elements_from.resize (num_siblings); + curr_size_elements_from = num_siblings; + } + const bool is_family = family_check (tree_elements_from, elements_from, el_considered, scheme, tree_class); + const adapt_action action = adapt_actions[el_offset + el_considered]; + + } + } + el_offset += num_el_from; + } + + } \ No newline at end of file diff --git a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx new file mode 100644 index 0000000000..eb9ce99aa9 --- /dev/null +++ b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx @@ -0,0 +1,148 @@ +/* + 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. +*/ + +/** \file t8_forest_adapt.hxx + * Definition of a C++ class for the adaptation routine to provide a flexible way of implementing + * different kinds of adaptation strategies. + */ + +#ifndef T8_FOREST_ADAPT_HXX +#define T8_FOREST_ADAPT_HXX + +#include +#include +/** + * Namespace for adaptation related classes and functions. + */ +namespace t8_forest_adapt{ + /** The action to be taken on an element during adaptation. + * COARSEN: The element should be coarsened. + * KEEP: The element should remain as is. + * REFINE: The element should be refined. + */ + enum int8_t AdaptAction { + COARSEN = -1, + KEEP = 0, + REFINE = 1 + }; + + /** + * Callback function type for element adaptation. + */ + using element_callback = std::function; + +class basic_adaptation { + public: + /** Constructor for basic_adaptation class. + * \param [in] forest_in The forest to be adapted. + * \param [in] callback_in The callback function to determine adaptation actions. + */ + basic_adaptation (t8_forest_t forest, t8_forest_t forest_from, element_callback callback_in) + : forest (forest), forest_from (forest_from), callback (callback_in) + { + T8_ASSERT (forest != nullptr); + T8_ASSERT (callback); + if (forest_from != nullptr) { + t8_forest_ref (forest_from); + } + T8_ASSERT (forest != nullptr); + if (forest != nullptr) { + t8_forest_ref (forest); + } + } + + /** Destructor for basic_adaptation class. */ + ~basic_adaptation () { + if (forest_from != nullptr) { + t8_forest_unref (forest_from); + } + if (forest != nullptr) { + t8_forest_unref (forest); + } + } + + /** Perform the adaptation process on the forest. */ + void adapt(); + + element_callback callback; /**< The callback function to determine adaptation actions. */ + private: + /** + * Profile the adaptation process. + */ + inline void + profile_adaptation(){ + T8_ASSERT(forest->profile != nullptr); + forest->profile->adapt_runtime = -sc_MPI_Wtime(); + } + + /** + * Collect adaptation actions for all elements in the source forest. + */ + inline void + collect_adapt_actions(){ + t8_locidx_t el_offset = 0; + const t8_locidx_t num_trees = t8_forest_get_num_trees (forest_from); + const t8_locidx_t local_num_elements = t8_forest_get_num_local_elements (forest_from); + adapt_actions.resize (local_num_elements); + + const t8_scheme *scheme = t8_forest_get_scheme (forest_from); + + /* For each element get the adaptation action */ + for (t8_locidx_t ltree_id = 0; ltree_id < num_trees; ltree_id++) { + const t8_tree_t tree_from = t8_forest_get_tree (forest_from, ltree_id); + const t8_eclass_t tree_class = tree_from->tree_class; + const t8_element_array_t elements_from = &tree_from->leaf_elements; + const t8_locidx_t num_el_from = (t8_locidx_t) t8_element_array_get_count (elements_from); + for (t8_locidx_t i = 0; i < num_el_from; i++) { + const t8_element_t *element = (t8_element_t *) t8_element_array_get_element (elements_from, i); + adapt_actions[el_offset + i] = element_callback (forest_from, ltree_id, element, scheme); + } + el_offset += num_el_from; + } + }; + + inline bool + family_check(const t8_element_array_t *telements_from, const t8_locidx_t offset, const t8_scheme *scheme, const t8_eclass_t tree_class){ + const int num_siblings = scheme->element_get_num_siblings (tree_class, t8_element_array_index_locidx (telements_from, offset)); + t8_element_t **elements_from = T8_ALLOC (t8_element_t *, num_siblings); + for (int isibling = 0; isibling < num_siblings; isibling++) { + elements_from[isibling] = (t8_element_t *) t8_element_array_index_locidx_mutable (telements_from, offset + (t8_locidx_t )isibling); + if (scheme->element_get_child_id (tree_class, elements_from[isibling]) != isibling) { + T8_FREE (elements_from); + return false; + } + } + const bool is_family = scheme->elements_are_family (tree_class, elements_from); + T8_FREE (elements_from); + return is_family; + } + + t8_forest_t forest; /**< The target forest */ + t8_forest_t forest_from; /**< The source forest to adapt from. */ + std::vector adapt_actions; /**< The adaptation actions for each element in the source forest. */ + bool profiling = false; /**< Flag to indicate if profiling is enabled. */ +} + +}; + +#endif /* T8_FOREST_ADAPT_HXX */ \ No newline at end of file From 5c65516f9b7292ef03793e2b6714789332690e25 Mon Sep 17 00:00:00 2001 From: David Knapp Date: Fri, 12 Dec 2025 14:00:40 +0100 Subject: [PATCH 2/6] Started Implementation of the manipulation-functions a templated function to describe how the new forest is based on the old forest depending on the return value of the adaptation cb --- .../t8_forest_adapt/t8_forest_adapt.cxx | 43 ++++++++-- .../t8_forest_adapt/t8_forest_adapt.hxx | 80 +++++++++++++++++-- 2 files changed, 108 insertions(+), 15 deletions(-) diff --git a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx index f981227cd5..9893750a12 100644 --- a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx +++ b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx @@ -25,7 +25,7 @@ * Implementation of the adaptation routine to refine and coarsen a forest of trees. */ - #include +#include @@ -45,10 +45,13 @@ const t8_locidx_t num_trees = t8_forest_get_num_trees (forest_from); for (t8_locidx_t ltree_id = 0; ltree_id < num_trees; ltree_id++) { + /* get the trees from both forests. */ t8_tree_t tree = t8_forest_get_tree (forest, ltree_id); const t8_tree_t tree_from = t8_forest_get_tree (forest_from, ltree_id); + /* get the leaf arrays from both forests */ t8_element_array_t elements = &tree->leaf_elements; const t8_element_array_t tree_elements_from = &tree_from->leaf_elements; + /* Get the number of elements in the source tree */ const t8_locidx_t num_el_from = (t8_locidx_t) t8_element_array_get_count (tree_elements_from); T8_ASSERT (num_el_from == t8_forest_get_tree_num_leaf_elements (forest_from, ltree_id)); const t8_eclass_t tree_class = tree_from->tree_class; @@ -56,21 +59,47 @@ if (num_el_from < 0){ const t8_element_t *first_element_from = t8_element_array_index_locidx (tree_elements_from, 0); t8_locidx_t curr_size_elements_from = scheme->element_get_num_siblings (tree_class, first_element_from); + /* index of the elements in source tree */ t8_locidx_t el_considered = 0; - std::vector elements_from; + /* index of the elements in target tree */ + t8_locidx_t el_inserted = 0; + std::vector elements_temp; while (el_considered < num_el_from) { const t8_locidx_t num_siblings = scheme->element_get_num_siblings (tree_class, t8_element_array_index_locidx (tree_elements_from, el_considered)); if (num_siblings > curr_size_elements_from) { - elements_from.resize (num_siblings); + elements_temp.resize (num_siblings); curr_size_elements_from = num_siblings; } - const bool is_family = family_check (tree_elements_from, elements_from, el_considered, scheme, tree_class); - const adapt_action action = adapt_actions[el_offset + el_considered]; - + for (int isibling = 0; isibling < num_siblings && el_considered + isibling < num_el_from; isibling++) { + elements_temp[isibling] = (t8_element_t *) t8_element_array_index_locidx_mutable (tree_elements_from, el_considered + (t8_locidx_t )isibling); + if (scheme->element_get_child_id (tree_class, elements_temp[isibling]) != isibling) { + break; + } + } + const bool is_family = family_check (tree_elements_from, elements_temp, el_considered, scheme, tree_class); + adapt_action action = adapt_actions[el_offset + el_considered]; + + if (!is_family && action == COARSEN) { + action = KEEP; + } + /* Check that all siblings want to be coarsened */ + if (is_family && action == COARSEN) { + const auto start = adapt_actions.begin() + static_cast(el_offset + el_considered); + const auto end = start + static_cast(num_siblings); + if (!std::all_of(start, end, [](const adapt_action &a){ return a == COARSEN; })) { + action = KEEP; + } + } + + el_inserted += manipulate_elements (elements, tree_elements_from,el_considered ); + el_considered++; } } + tree->elements_offset = el_offset; el_offset += num_el_from; - } + + + } } \ No newline at end of file diff --git a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx index eb9ce99aa9..28e33039fe 100644 --- a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx +++ b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx @@ -39,7 +39,7 @@ namespace t8_forest_adapt{ * KEEP: The element should remain as is. * REFINE: The element should be refined. */ - enum int8_t AdaptAction { + enum adapt_action { COARSEN = -1, KEEP = 0, REFINE = 1 @@ -48,9 +48,76 @@ namespace t8_forest_adapt{ /** * Callback function type for element adaptation. */ - using element_callback = std::function; + using element_callback = std::function; + + /** * Function to manipulate elements based on the specified adaptation action. + * \tparam action The adaptation action to be performed. + * \param [in, out] elements The element array to be modified. + * \param [in] elements_from The source element array. + * \param [in] scheme The element scheme. + * \param [in] tree_class The eclass of the tree used by the scheme + * \param [in] elements_index The index in the target element array. + * \param [in] elements_from_index The index in the source element array. + * \return The number of elements created in the target array. + */ + template + int manipulate_elements (t8_element_array_t *elements, + const t8_element_array_t *elements_from, + const t8_scheme *scheme, + const t8_eclass_t tree_class + const t8_locidx_t elements_index, + const t8_locidx_t elements_from_index); + + template <> + int manipulate_elements (t8_element_array_t *elements, + const t8_element_array_t *elements_from, + const t8_scheme *scheme, + const t8_eclass_t tree_class + const t8_locidx_t elements_index, + const t8_locidx_t elements_from_index) + { + t8_element_t *element = t8_element_array_push (elements); + scheme->element_copy (tree_class, elements_from[elements_from_index], element); + return 1; + }; + template <> + int manipulate_elements (t8_element_array_t *elements, + const t8_element_array_t *elements_from, + const t8_scheme *scheme, + const t8_eclass_t tree_class, + const t8_locidx_t elements_index, + const t8_locidx_t elements_from_index) + { + t8_element_t *element = t8_element_array_push (elements); + T8_ASSERT (scheme->element_get_level (tree_class, elements_from[elements_from_index]) > 0); + scheme->element_get_parent (tree_class, elements_from[elements_from_index], element); + + /* Hier eventuell noch was mit num_children = num_siblings*/ + return 1; + }; + + template <> + int manipulate_elements (t8_element_array_t *elements, + const t8_element_array_t *elements_from, + const t8_scheme *scheme, + const t8_eclass_t tree_class, + const t8_locidx_t elements_index, + const t8_locidx_t elements_from_index) + { + const int num_children = scheme->element_get_num_children (tree_class, elements_from[elements_from_index]); + /* CONTINUE WORK HERE */ + (void) t8_element_array_push_count (elements, num_children); + for (int ichildren = 0; ichildren < num_children; ichildren++) { + elements[ichildren + elements_index] = t8_element_array_index_locidx_mutable (elements, *el_inserted + ichildren); + } + return num_children; + }; + + + /** * Class implementing a basic adaptation strategy for a forest of trees. + */ class basic_adaptation { public: /** Constructor for basic_adaptation class. @@ -122,24 +189,21 @@ class basic_adaptation { }; inline bool - family_check(const t8_element_array_t *telements_from, const t8_locidx_t offset, const t8_scheme *scheme, const t8_eclass_t tree_class){ + family_check(const t8_element_array_t *tree_elements_from, std::vector &elements_from, const t8_locidx_t offset, const t8_scheme *scheme, const t8_eclass_t tree_class){ const int num_siblings = scheme->element_get_num_siblings (tree_class, t8_element_array_index_locidx (telements_from, offset)); - t8_element_t **elements_from = T8_ALLOC (t8_element_t *, num_siblings); for (int isibling = 0; isibling < num_siblings; isibling++) { elements_from[isibling] = (t8_element_t *) t8_element_array_index_locidx_mutable (telements_from, offset + (t8_locidx_t )isibling); if (scheme->element_get_child_id (tree_class, elements_from[isibling]) != isibling) { - T8_FREE (elements_from); return false; } } const bool is_family = scheme->elements_are_family (tree_class, elements_from); - T8_FREE (elements_from); return is_family; } t8_forest_t forest; /**< The target forest */ t8_forest_t forest_from; /**< The source forest to adapt from. */ - std::vector adapt_actions; /**< The adaptation actions for each element in the source forest. */ + std::vector adapt_actions; /**< The adaptation actions for each element in the source forest. */ bool profiling = false; /**< Flag to indicate if profiling is enabled. */ } From 60e93a10030095e22868721e9e012838d5c0ffeb Mon Sep 17 00:00:00 2001 From: David Knapp Date: Mon, 15 Dec 2025 13:53:27 +0100 Subject: [PATCH 3/6] fix compiler errors --- src/CMakeLists.txt | 1 + .../t8_forest_adapt/t8_forest_adapt.cxx | 39 +++++++--- .../t8_forest_adapt/t8_forest_adapt.hxx | 74 +++++++++++-------- .../t8_default_hex/t8_default_hex.cxx | 2 +- .../t8_default_hex/t8_default_hex.hxx | 2 +- src/t8_schemes/t8_scheme.cxx | 2 +- src/t8_schemes/t8_scheme.h | 2 +- src/t8_schemes/t8_scheme.hxx | 2 +- 8 files changed, 81 insertions(+), 43 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7f1f44b9dd..10fff05fdd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -171,6 +171,7 @@ target_sources( T8 PRIVATE t8_data/t8_shmem.c t8_data/t8_containers.cxx t8_forest/t8_forest_adapt.cxx + t8_forest/t8_forest_adapt/t8_forest_adapt.cxx t8_forest/t8_forest_partition.cxx t8_forest/t8_forest.cxx t8_forest/t8_forest_private.cxx diff --git a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx index 9893750a12..1a299c5807 100644 --- a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx +++ b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.cxx @@ -28,9 +28,8 @@ #include - void - t8_forest_adapt::basic_adaptation::adapt() + t8_forest_adapt_namespace::basic_adaptation::adapt() { T8_ASSERT (forest != nullptr); @@ -41,20 +40,23 @@ collect_adapt_actions(); + /* Offset per tree in the source forest */ t8_locidx_t el_offset = 0; - const t8_locidx_t num_trees = t8_forest_get_num_trees (forest_from); + const t8_locidx_t num_trees = t8_forest_get_num_local_trees (forest_from); + /* Get the scheme used by the forest */ + const t8_scheme *scheme = t8_forest_get_scheme (forest_from); for (t8_locidx_t ltree_id = 0; ltree_id < num_trees; ltree_id++) { /* get the trees from both forests. */ t8_tree_t tree = t8_forest_get_tree (forest, ltree_id); const t8_tree_t tree_from = t8_forest_get_tree (forest_from, ltree_id); /* get the leaf arrays from both forests */ - t8_element_array_t elements = &tree->leaf_elements; - const t8_element_array_t tree_elements_from = &tree_from->leaf_elements; + t8_element_array_t *elements = &tree->leaf_elements; + const t8_element_array_t *tree_elements_from = &tree_from->leaf_elements; /* Get the number of elements in the source tree */ const t8_locidx_t num_el_from = (t8_locidx_t) t8_element_array_get_count (tree_elements_from); T8_ASSERT (num_el_from == t8_forest_get_tree_num_leaf_elements (forest_from, ltree_id)); - const t8_eclass_t tree_class = tree_from->tree_class; + const t8_eclass_t tree_class = tree_from->eclass; /* Continue only if tree_from is not empty */ if (num_el_from < 0){ const t8_element_t *first_element_from = t8_element_array_index_locidx (tree_elements_from, 0); @@ -63,7 +65,7 @@ t8_locidx_t el_considered = 0; /* index of the elements in target tree */ t8_locidx_t el_inserted = 0; - std::vector elements_temp; + std::vector elements_temp; while (el_considered < num_el_from) { const t8_locidx_t num_siblings = scheme->element_get_num_siblings (tree_class, t8_element_array_index_locidx (tree_elements_from, el_considered)); @@ -72,7 +74,7 @@ curr_size_elements_from = num_siblings; } for (int isibling = 0; isibling < num_siblings && el_considered + isibling < num_el_from; isibling++) { - elements_temp[isibling] = (t8_element_t *) t8_element_array_index_locidx_mutable (tree_elements_from, el_considered + (t8_locidx_t )isibling); + elements_temp[isibling] = (const t8_element_t *) t8_element_array_index_locidx (tree_elements_from, el_considered + (t8_locidx_t )isibling); if (scheme->element_get_child_id (tree_class, elements_temp[isibling]) != isibling) { break; } @@ -92,7 +94,26 @@ } } - el_inserted += manipulate_elements (elements, tree_elements_from,el_considered ); + switch (action) { + case COARSEN: + el_inserted += manipulate_elements (elements, tree_elements_from, scheme, tree_class, + el_inserted, el_offset + el_considered); + break; + case KEEP: + el_inserted += manipulate_elements (elements, tree_elements_from, scheme, tree_class, + el_inserted, el_offset + el_considered); + break; + case REFINE: + el_inserted += manipulate_elements (elements, tree_elements_from, scheme, tree_class, + el_inserted, el_offset + el_considered); + break; + default: + { + t8_errorf ("Unknown adapt action.\n"); + SC_ABORT_NOT_REACHED (); + break; + } + } el_considered++; } } diff --git a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx index 28e33039fe..fc4cf5cd36 100644 --- a/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx +++ b/src/t8_forest/t8_forest_adapt/t8_forest_adapt.hxx @@ -30,10 +30,17 @@ #include #include +#include +#include + +#include + /** * Namespace for adaptation related classes and functions. */ -namespace t8_forest_adapt{ + + /* TODO rename to t8_forest_adapt as soon as it is not used as function name anymore. */ +namespace t8_forest_adapt_namespace { /** The action to be taken on an element during adaptation. * COARSEN: The element should be coarsened. * KEEP: The element should remain as is. @@ -62,56 +69,61 @@ namespace t8_forest_adapt{ * \return The number of elements created in the target array. */ template - int manipulate_elements (t8_element_array_t *elements, - const t8_element_array_t *elements_from, + t8_locidx_t manipulate_elements (t8_element_array_t *elements, + const t8_element_array_t *const elements_from, const t8_scheme *scheme, - const t8_eclass_t tree_class + const t8_eclass_t tree_class, const t8_locidx_t elements_index, const t8_locidx_t elements_from_index); template <> - int manipulate_elements (t8_element_array_t *elements, - const t8_element_array_t *elements_from, + t8_locidx_t manipulate_elements (t8_element_array_t *elements, + const t8_element_array_t *const elements_from, const t8_scheme *scheme, - const t8_eclass_t tree_class + const t8_eclass_t tree_class, const t8_locidx_t elements_index, const t8_locidx_t elements_from_index) { t8_element_t *element = t8_element_array_push (elements); - scheme->element_copy (tree_class, elements_from[elements_from_index], element); + const t8_element_t * element_from = t8_element_array_index_locidx (elements, elements_index); + scheme->element_copy (tree_class, element_from, element); return 1; }; template <> - int manipulate_elements (t8_element_array_t *elements, - const t8_element_array_t *elements_from, + t8_locidx_t manipulate_elements (t8_element_array_t *elements, + const t8_element_array_t *const elements_from, const t8_scheme *scheme, const t8_eclass_t tree_class, const t8_locidx_t elements_index, const t8_locidx_t elements_from_index) { t8_element_t *element = t8_element_array_push (elements); - T8_ASSERT (scheme->element_get_level (tree_class, elements_from[elements_from_index]) > 0); - scheme->element_get_parent (tree_class, elements_from[elements_from_index], element); + const t8_element_t * element_from = t8_element_array_index_locidx (elements, elements_index); + T8_ASSERT (scheme->element_get_level (tree_class, element_from) > 0); + scheme->element_get_parent (tree_class, element_from, element); /* Hier eventuell noch was mit num_children = num_siblings*/ return 1; }; template <> - int manipulate_elements (t8_element_array_t *elements, - const t8_element_array_t *elements_from, + t8_locidx_t manipulate_elements (t8_element_array_t *elements, + const t8_element_array_t *const elements_from, const t8_scheme *scheme, const t8_eclass_t tree_class, const t8_locidx_t elements_index, const t8_locidx_t elements_from_index) { - const int num_children = scheme->element_get_num_children (tree_class, elements_from[elements_from_index]); + const t8_element_t * element_from = t8_element_array_index_locidx (elements_from, elements_from_index); + const int num_children = scheme->element_get_num_children (tree_class, element_from); /* CONTINUE WORK HERE */ (void) t8_element_array_push_count (elements, num_children); + std::vector children(num_children); for (int ichildren = 0; ichildren < num_children; ichildren++) { - elements[ichildren + elements_index] = t8_element_array_index_locidx_mutable (elements, *el_inserted + ichildren); + children[ichildren] = t8_element_array_index_locidx_mutable (elements, elements_index + ichildren); } + scheme->element_get_children (tree_class, element_from, num_children, children.data()); return num_children; }; @@ -141,10 +153,10 @@ class basic_adaptation { /** Destructor for basic_adaptation class. */ ~basic_adaptation () { if (forest_from != nullptr) { - t8_forest_unref (forest_from); + t8_forest_unref (&forest_from); } if (forest != nullptr) { - t8_forest_unref (forest); + t8_forest_unref (&forest); } } @@ -168,8 +180,8 @@ class basic_adaptation { inline void collect_adapt_actions(){ t8_locidx_t el_offset = 0; - const t8_locidx_t num_trees = t8_forest_get_num_trees (forest_from); - const t8_locidx_t local_num_elements = t8_forest_get_num_local_elements (forest_from); + const t8_locidx_t num_trees = t8_forest_get_num_local_trees (forest_from); + const t8_locidx_t local_num_elements = t8_forest_get_local_num_leaf_elements (forest_from); adapt_actions.resize (local_num_elements); const t8_scheme *scheme = t8_forest_get_scheme (forest_from); @@ -177,27 +189,31 @@ class basic_adaptation { /* For each element get the adaptation action */ for (t8_locidx_t ltree_id = 0; ltree_id < num_trees; ltree_id++) { const t8_tree_t tree_from = t8_forest_get_tree (forest_from, ltree_id); - const t8_eclass_t tree_class = tree_from->tree_class; - const t8_element_array_t elements_from = &tree_from->leaf_elements; + const t8_eclass_t tree_class = tree_from->eclass; + const t8_element_array_t *elements_from = &tree_from->leaf_elements; const t8_locidx_t num_el_from = (t8_locidx_t) t8_element_array_get_count (elements_from); for (t8_locidx_t i = 0; i < num_el_from; i++) { - const t8_element_t *element = (t8_element_t *) t8_element_array_get_element (elements_from, i); - adapt_actions[el_offset + i] = element_callback (forest_from, ltree_id, element, scheme); + const t8_element_t * element = t8_element_array_index_locidx (elements_from, i); + adapt_actions[el_offset + i] = callback (forest_from, ltree_id, element, scheme, tree_class); } el_offset += num_el_from; } }; inline bool - family_check(const t8_element_array_t *tree_elements_from, std::vector &elements_from, const t8_locidx_t offset, const t8_scheme *scheme, const t8_eclass_t tree_class){ - const int num_siblings = scheme->element_get_num_siblings (tree_class, t8_element_array_index_locidx (telements_from, offset)); + family_check(const t8_element_array_t *tree_elements_from, std::vector &elements_from, const t8_locidx_t offset, const t8_scheme *scheme, const t8_eclass_t tree_class){ + const int num_siblings = scheme->element_get_num_siblings (tree_class, elements_from[offset]); for (int isibling = 0; isibling < num_siblings; isibling++) { - elements_from[isibling] = (t8_element_t *) t8_element_array_index_locidx_mutable (telements_from, offset + (t8_locidx_t )isibling); + elements_from[isibling] = (const t8_element_t *) t8_element_array_index_locidx (tree_elements_from, offset + (t8_locidx_t )isibling); if (scheme->element_get_child_id (tree_class, elements_from[isibling]) != isibling) { return false; } } - const bool is_family = scheme->elements_are_family (tree_class, elements_from); + /* elements_are_family expects t8_element_t *const *; build a non-const pointer array */ + std::vector children_nonconst(num_siblings); + for (int i = 0; i < num_siblings; ++i) + children_nonconst[i] = const_cast(elements_from[i]); + const bool is_family = scheme->elements_are_family (tree_class, children_nonconst.data()); return is_family; } @@ -205,7 +221,7 @@ class basic_adaptation { t8_forest_t forest_from; /**< The source forest to adapt from. */ std::vector adapt_actions; /**< The adaptation actions for each element in the source forest. */ bool profiling = false; /**< Flag to indicate if profiling is enabled. */ -} +}; }; diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx index a63ab50dfd..8f2af4711b 100644 --- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx +++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx @@ -639,6 +639,7 @@ t8_default_scheme_hex::element_is_valid (const t8_element_t *element) const && T8_QUAD_GET_TDIM ((const p8est_quadrant_t *) element) == 3; } +#endif void t8_default_scheme_hex::element_to_string (const t8_element_t *elem, char *debug_string, const int string_size) const { @@ -647,7 +648,6 @@ t8_default_scheme_hex::element_to_string (const t8_element_t *elem, char *debug_ p8est_quadrant_t *hex = (p8est_quadrant_t *) elem; snprintf (debug_string, string_size, "x: %i, y: %i, z: %i, level: %i", hex->x, hex->y, hex->z, hex->level); } -#endif void t8_default_scheme_hex::set_to_root (t8_element_t *elem) const diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx index 11715252ae..f86b5d2d7e 100644 --- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx +++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx @@ -574,6 +574,7 @@ class t8_default_scheme_hex: public t8_default_scheme_commonelement_debug_print (tree_class, elem); } +#endif void t8_element_to_string (const t8_scheme_c *scheme, const t8_eclass_t tree_class, const t8_element_t *elem, char *debug_string, const int string_size) @@ -378,7 +379,6 @@ t8_element_to_string (const t8_scheme_c *scheme, const t8_eclass_t tree_class, c return scheme->element_to_string (tree_class, elem, debug_string, string_size); } -#endif void t8_element_new (const t8_scheme_c *scheme, const t8_eclass_t tree_class, const int length, t8_element_t **elems) diff --git a/src/t8_schemes/t8_scheme.h b/src/t8_schemes/t8_scheme.h index 324d6e368f..fc6da52564 100644 --- a/src/t8_schemes/t8_scheme.h +++ b/src/t8_schemes/t8_scheme.h @@ -721,6 +721,7 @@ t8_element_is_valid (const t8_scheme_c *scheme, const t8_eclass_t tree_class, co void t8_element_debug_print (const t8_scheme_c *scheme, const t8_eclass_t tree_class, const t8_element_t *element); +#endif /** * \brief Fill a string with readable information about the element * @@ -733,7 +734,6 @@ t8_element_debug_print (const t8_scheme_c *scheme, const t8_eclass_t tree_class, void t8_element_to_string (const t8_scheme_c *scheme, const t8_eclass_t tree_class, const t8_element_t *element, char *debug_string, const int string_size); -#endif /** Allocate memory for an array of elements of a given class and initialize them. * \param [in] scheme The scheme of the forest. diff --git a/src/t8_schemes/t8_scheme.hxx b/src/t8_schemes/t8_scheme.hxx index 1bbd23087b..1854fe07eb 100644 --- a/src/t8_schemes/t8_scheme.hxx +++ b/src/t8_schemes/t8_scheme.hxx @@ -991,6 +991,7 @@ class t8_scheme { eclass_schemes[tree_class]); }; + #endif /** * Fill a string with readable information about the element * \param [in] tree_class The eclass of the current tree. @@ -1005,7 +1006,6 @@ class t8_scheme { return std::visit ([&] (auto &&scheme) { return scheme.element_to_string (element, debug_string, string_size); }, eclass_schemes[tree_class]); }; -#endif /** Allocate memory for \a length many elements of a given class and initialize them, * and put pointers to the elements in the provided array. From 99c16c2c7aa59c962c9e309494b3445b19faf52e Mon Sep 17 00:00:00 2001 From: David Knapp Date: Mon, 15 Dec 2025 14:03:57 +0100 Subject: [PATCH 4/6] fix macro changes --- src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx | 2 +- src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx | 2 +- src/t8_schemes/t8_scheme.cxx | 2 +- src/t8_schemes/t8_scheme.h | 2 +- src/t8_schemes/t8_scheme.hxx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx index 8f2af4711b..eea846f1ef 100644 --- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx +++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx @@ -638,8 +638,8 @@ t8_default_scheme_hex::element_is_valid (const t8_element_t *element) const return p8est_quadrant_is_extended ((const p8est_quadrant_t *) element) && T8_QUAD_GET_TDIM ((const p8est_quadrant_t *) element) == 3; } - #endif + void t8_default_scheme_hex::element_to_string (const t8_element_t *elem, char *debug_string, const int string_size) const { diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx index f86b5d2d7e..11715252ae 100644 --- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx +++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.hxx @@ -574,7 +574,6 @@ class t8_default_scheme_hex: public t8_default_scheme_commonelement_debug_print (tree_class, elem); } -#endif void t8_element_to_string (const t8_scheme_c *scheme, const t8_eclass_t tree_class, const t8_element_t *elem, char *debug_string, const int string_size) @@ -383,6 +382,7 @@ t8_element_to_string (const t8_scheme_c *scheme, const t8_eclass_t tree_class, c return scheme->element_to_string (tree_class, elem, debug_string, string_size); } +#endif void t8_element_new (const t8_scheme_c *scheme, const t8_eclass_t tree_class, const int length, t8_element_t **elems) diff --git a/src/t8_schemes/t8_scheme.h b/src/t8_schemes/t8_scheme.h index 3b36bc4f4a..130c3287eb 100644 --- a/src/t8_schemes/t8_scheme.h +++ b/src/t8_schemes/t8_scheme.h @@ -736,7 +736,6 @@ t8_element_is_valid (const t8_scheme_c *scheme, const t8_eclass_t tree_class, co void t8_element_debug_print (const t8_scheme_c *scheme, const t8_eclass_t tree_class, const t8_element_t *element); -#endif /** * \brief Fill a string with readable information about the element * @@ -749,6 +748,7 @@ t8_element_debug_print (const t8_scheme_c *scheme, const t8_eclass_t tree_class, void t8_element_to_string (const t8_scheme_c *scheme, const t8_eclass_t tree_class, const t8_element_t *element, char *debug_string, const int string_size); +#endif /** Allocate memory for an array of elements of a given class and initialize them. * \param [in] scheme The scheme of the forest. diff --git a/src/t8_schemes/t8_scheme.hxx b/src/t8_schemes/t8_scheme.hxx index 1854fe07eb..1bbd23087b 100644 --- a/src/t8_schemes/t8_scheme.hxx +++ b/src/t8_schemes/t8_scheme.hxx @@ -991,7 +991,6 @@ class t8_scheme { eclass_schemes[tree_class]); }; - #endif /** * Fill a string with readable information about the element * \param [in] tree_class The eclass of the current tree. @@ -1006,6 +1005,7 @@ class t8_scheme { return std::visit ([&] (auto &&scheme) { return scheme.element_to_string (element, debug_string, string_size); }, eclass_schemes[tree_class]); }; +#endif /** Allocate memory for \a length many elements of a given class and initialize them, * and put pointers to the elements in the provided array. From a7878222a6e9d97973e9c513657096e14b05dc72 Mon Sep 17 00:00:00 2001 From: David Knapp Date: Mon, 15 Dec 2025 14:04:54 +0100 Subject: [PATCH 5/6] fix last macro change --- src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx index eea846f1ef..b9b2af379e 100644 --- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx +++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx @@ -638,7 +638,7 @@ t8_default_scheme_hex::element_is_valid (const t8_element_t *element) const return p8est_quadrant_is_extended ((const p8est_quadrant_t *) element) && T8_QUAD_GET_TDIM ((const p8est_quadrant_t *) element) == 3; } -#endif + void t8_default_scheme_hex::element_to_string (const t8_element_t *elem, char *debug_string, const int string_size) const @@ -648,6 +648,7 @@ t8_default_scheme_hex::element_to_string (const t8_element_t *elem, char *debug_ p8est_quadrant_t *hex = (p8est_quadrant_t *) elem; snprintf (debug_string, string_size, "x: %i, y: %i, z: %i, level: %i", hex->x, hex->y, hex->z, hex->level); } +#endif void t8_default_scheme_hex::set_to_root (t8_element_t *elem) const From b96d5cd0e33f03b9ce1fa9dc7f4501ea62234296 Mon Sep 17 00:00:00 2001 From: David Knapp Date: Mon, 15 Dec 2025 14:05:19 +0100 Subject: [PATCH 6/6] fix empty space --- src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx index b9b2af379e..a63ab50dfd 100644 --- a/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx +++ b/src/t8_schemes/t8_default/t8_default_hex/t8_default_hex.cxx @@ -639,7 +639,6 @@ t8_default_scheme_hex::element_is_valid (const t8_element_t *element) const && T8_QUAD_GET_TDIM ((const p8est_quadrant_t *) element) == 3; } - void t8_default_scheme_hex::element_to_string (const t8_element_t *elem, char *debug_string, const int string_size) const {