|
| 1 | +/* |
| 2 | + This file is part of t8code. |
| 3 | + t8code is a C library to manage a collection (a forest) of multiple |
| 4 | + connected adaptive space-trees of general element classes in parallel. |
| 5 | +
|
| 6 | + Copyright (C) 2025 the developers |
| 7 | +
|
| 8 | + t8code is free software; you can redistribute it and/or modify |
| 9 | + it under the terms of the GNU General Public License as published by |
| 10 | + the Free Software Foundation; either version 2 of the License, or |
| 11 | + (at your option) any later version. |
| 12 | +
|
| 13 | + t8code is distributed in the hope that it will be useful, |
| 14 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | + GNU General Public License for more details. |
| 17 | +
|
| 18 | + You should have received a copy of the GNU General Public License |
| 19 | + along with t8code; if not, write to the Free Software Foundation, Inc., |
| 20 | + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 21 | +*/ |
| 22 | + |
| 23 | +/** \file t8_cmesh_vertex_conn_tree_to_vertex.hxx |
| 24 | + * Class to save data structure for tree_to_vertex_lists of the cmesh. |
| 25 | + * When the cmesh stores global vertex numbers, we require a lookup that |
| 26 | + * matches a tree and its local vertex to a global vertex id. |
| 27 | + * This lookup is encoded in the t8_cmesh_vertex_conn_tree_to_vertex struct. |
| 28 | + */ |
| 29 | + |
| 30 | +/* TODO: |
| 31 | + * It is probably best to set all global ids of a single tree as one attribute. |
| 32 | + * That way we can store it as a single arrays of id's. |
| 33 | + * We will probably most often want to access all ids of one tree, so a function returning an array of ids |
| 34 | + * is a good idea anyway and if we already store them as such then we do not need to do any data movement |
| 35 | + * when accessing. |
| 36 | + * |
| 37 | + * On the downside we will only have a "set all ids of a tree" function and no "set this single id for this tree and this vertex" function. |
| 38 | + */ |
| 39 | + |
| 40 | +#ifndef T8_CMESH_VERTEX_CONN_TREE_TO_VERTEX_HXX |
| 41 | +#define T8_CMESH_VERTEX_CONN_TREE_TO_VERTEX_HXX |
| 42 | + |
| 43 | +#include <algorithm> |
| 44 | +#include <t8_cmesh.h> |
| 45 | +#include <t8_cmesh/t8_cmesh_types.h> |
| 46 | +#include <t8_cmesh/t8_cmesh_vertex_connectivity/t8_cmesh_vertex_conn_vertex_to_tree.hxx> |
| 47 | + |
| 48 | +/* forward declaration of ttv class needed since the two class headers include each other. */ |
| 49 | +class t8_cmesh_vertex_conn_vertex_to_tree; |
| 50 | + |
| 51 | +class t8_cmesh_vertex_conn_tree_to_vertex { |
| 52 | + public: |
| 53 | + /** Standard constructor. Does nothing. */ |
| 54 | + t8_cmesh_vertex_conn_tree_to_vertex (): state (EMPTY) |
| 55 | + { |
| 56 | + } |
| 57 | + |
| 58 | + /** Constructor from a cmesh where all the attributes are set. |
| 59 | + * Currently unclear if we implement this eventually. |
| 60 | + * If we do so: Should the cmesh be already committed, or in pre-commit state but attributes set? |
| 61 | + * |
| 62 | + * \note This function is not implemented yet. |
| 63 | + */ |
| 64 | + t8_cmesh_vertex_conn_tree_to_vertex ([[maybe_unused]] const t8_cmesh_t cmesh) |
| 65 | + { |
| 66 | + // TODO: Remove the [[maybe unused]] qualifier when implemented |
| 67 | + SC_ABORT ("not implemented."); |
| 68 | + } |
| 69 | + |
| 70 | + /** Constructor from a cmesh and a given vertex to tree connectivity. |
| 71 | + * |
| 72 | + * \param [in] cmesh_from A committed cmesh. |
| 73 | + * \param [in] cmesh An initialized but not committed cmesh that is to be derived from \a cmesh_from. |
| 74 | + * \param [in] vtt A committed vertex to tree connectivity for \a cmesh_from. |
| 75 | + * |
| 76 | + * As a result a tree to vertec connectivity for \a cmesh will be constructed. |
| 77 | + * \note \a cmesh_from must be committed. |
| 78 | + * \note \a cmesh must not be committed. |
| 79 | + * \note \a vtt must be committed. |
| 80 | + * \note This does not work until issue #923 https://github.com/DLR-AMR/t8code/issues/923 is resolved. |
| 81 | + */ |
| 82 | + t8_cmesh_vertex_conn_tree_to_vertex (const t8_cmesh_t cmesh_from, const t8_cmesh_t cmesh, |
| 83 | + const struct t8_cmesh_vertex_conn_vertex_to_tree &vtt); |
| 84 | + |
| 85 | + /* Setter functions */ |
| 86 | + /** Set all global vertex ids of a local tree. |
| 87 | + * \param [in] cmesh The considered cmesh |
| 88 | + * \param [in] local_tree A local tree id of \a cmesh |
| 89 | + * \param [in] global_vertex_id The ids of the global vertices in order of \a local_tree's vertices. |
| 90 | + * \param [in] num_vertices Must match the number of vertices of \a local_tree |
| 91 | + * |
| 92 | + * \note \a cmesh must not be committed. |
| 93 | + */ |
| 94 | + inline void |
| 95 | + set_global_vertex_ids_of_tree_vertices (const t8_cmesh_t cmesh, const t8_gloidx_t global_tree, |
| 96 | + const t8_gloidx_t *global_tree_vertices, const int num_vertices) |
| 97 | + { |
| 98 | + T8_ASSERT (t8_cmesh_is_initialized (cmesh)); |
| 99 | + T8_ASSERT (num_vertices >= 0); |
| 100 | + T8_ASSERT (global_tree_vertices != NULL); |
| 101 | + |
| 102 | + /* TODO: we currently do not check whether the num_vertices argument |
| 103 | + * matches the number of vertices of the tree. |
| 104 | + * We cannot do it here, since this function call happens before commit, |
| 105 | + * thus we might not even know the eclass of the tree. |
| 106 | + * Maybe it is possible to check this during t8_cmesh_add_attributes? |
| 107 | + */ |
| 108 | + |
| 109 | + /* We copy the data directly, hence set data_persiss to 0 */ |
| 110 | + const int data_persists = 0; |
| 111 | + t8_debugf ("Setting %i global vertices for global tree %li.\n", num_vertices, global_tree); |
| 112 | + t8_cmesh_set_attribute_gloidx_array (cmesh, global_tree, t8_get_package_id (), |
| 113 | + T8_CMESH_GLOBAL_VERTICES_ATTRIBUTE_KEY, global_tree_vertices, num_vertices, |
| 114 | + data_persists); |
| 115 | + state = FILLED; |
| 116 | + } |
| 117 | + |
| 118 | + /* TODO: What if the attribute is not set? error handling */ |
| 119 | + /** Return the global vertex indices of a local tree. |
| 120 | + * \param [in] cmesh A committed cmesh. |
| 121 | + * \param [in] local_tree A local tree in \a cmesh. |
| 122 | + * \param [in] num_vertices The count of local vertices of \a local_tree |
| 123 | + * \return An array of length \a num_vertices containing the global vertex ids of \a local_tree's vertices. |
| 124 | + */ |
| 125 | + inline const t8_gloidx_t * |
| 126 | + get_global_vertices (const t8_cmesh_t cmesh, const t8_locidx_t local_tree, const int num_vertices) const |
| 127 | + { |
| 128 | + T8_ASSERT (t8_cmesh_is_committed (cmesh)); |
| 129 | + |
| 130 | +#if T8_ENABLE_DEBUG |
| 131 | + /* Verify that num_vertices matches the number of tree vertices */ |
| 132 | + const t8_eclass_t tree_class = t8_cmesh_get_tree_class (cmesh, local_tree); |
| 133 | + const int num_tree_vertices = t8_eclass_num_vertices[tree_class]; |
| 134 | + |
| 135 | + T8_ASSERT (num_vertices == num_tree_vertices); |
| 136 | +#endif |
| 137 | + |
| 138 | + t8_debugf ("Getting %i global vertices for local tree %i.\n", num_vertices, local_tree); |
| 139 | + const t8_gloidx_t *global_vertices = t8_cmesh_get_attribute_gloidx_array ( |
| 140 | + cmesh, t8_get_package_id (), T8_CMESH_GLOBAL_VERTICES_ATTRIBUTE_KEY, local_tree, num_vertices); |
| 141 | + T8_ASSERT (global_vertices != NULL); |
| 142 | + return global_vertices; |
| 143 | + } |
| 144 | + |
| 145 | + /* TODO: What if the attribute is not set? error handling */ |
| 146 | + /** Return a single global vertex id of a single local vertex. |
| 147 | + * |
| 148 | + * |
| 149 | + * \param [in] cmesh A committed cmesh. |
| 150 | + * \param [in] local_tree A local tree of \a cmesh. |
| 151 | + * \param [in] local_tree_vertex A local vertex of \a local_tree |
| 152 | + * \param [in] num_tree_vertices The count of vertices of \a local_tree |
| 153 | + * \return The global id of the local vertex \a local_tree_vertex of \a local_tree. |
| 154 | + */ |
| 155 | + t8_gloidx_t |
| 156 | + get_global_vertex (const t8_cmesh_t cmesh, const t8_locidx_t local_tree, const int local_tree_vertex, |
| 157 | + const int num_tree_vertices) const |
| 158 | + { |
| 159 | + T8_ASSERT (t8_cmesh_is_committed (cmesh)); |
| 160 | + |
| 161 | + /* Verify that local_tree_vertex is in fact a local vertex of the tree */ |
| 162 | + /* Note: We only perform this check in debugging mode. |
| 163 | + * In non-debugging mode, using a vertex index beyond the trees index allows |
| 164 | + * for a potential attacker to gain access to memory possibly not owned by the caller. |
| 165 | + * We do not check in non-debugging mode for (obvious) performance reasons. */ |
| 166 | + T8_ASSERT (0 <= local_tree_vertex); |
| 167 | + T8_ASSERT (local_tree_vertex < num_tree_vertices); |
| 168 | + |
| 169 | + return get_global_vertices (cmesh, local_tree, num_tree_vertices)[local_tree_vertex]; |
| 170 | + } |
| 171 | + |
| 172 | + friend struct t8_cmesh_vertex_connectivity; |
| 173 | + |
| 174 | + private: |
| 175 | + enum state { |
| 176 | + EMPTY, /*< Is initialized but empty. */ |
| 177 | + FILLED /*< Is filled with at least one entry. */ |
| 178 | + } state; |
| 179 | + |
| 180 | + /** Return the state of this object. */ |
| 181 | + inline enum state |
| 182 | + get_state () |
| 183 | + { |
| 184 | + return state; |
| 185 | + } |
| 186 | +}; |
| 187 | + |
| 188 | +#endif /* !T8_CMESH_VERTEX_CONN_TREE_TO_VERTEX_HXX */ |
0 commit comments