Reference documentation for deal.II version 9.5.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
cell_id_translator.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2021 - 2023 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_cell_id_translator_h
17#define dealii_cell_id_translator_h
18
21
24
25#include <cstdint>
26#include <limits>
27
29
30namespace internal
31{
54 template <int dim>
56 {
57 public:
64
70 size() const;
71
76 template <typename Accessor>
78 translate(const TriaIterator<Accessor> &cell) const;
79
83 template <typename Accessor>
86 const types::global_cell_index i) const;
87
91 CellId
93
94 private:
100 const typename CellId::binary_type &binary_representation);
101
106
111
115 std::vector<types::global_cell_index> tree_sizes;
116 };
117
118
119
120 template <int dim>
122 const types::global_cell_index n_coarse_cells,
123 const types::global_cell_index n_global_levels)
124 : n_coarse_cells(n_coarse_cells)
125 , n_global_levels(n_global_levels)
126 {
127 // The class stores indices as types::global_cell_index variables,
128 // but when configuring deal.II with default flags, this is a 32-bit
129 // data type and it is possible with highly (locally) refined meshes
130 // that we exceed the maximal 32-bit numbers even with relatively
131 // modest numbers of cells. Check for this by first calculating
132 // the maximal index we will get in 64-bit arithmetic and testing
133 // that it is representable in 32-bit arithmetic:
134#ifdef DEBUG
135 std::uint64_t max_cell_index = 0;
136
137 for (unsigned int i = 0; i < n_global_levels; ++i)
138 max_cell_index +=
139 Utilities::pow<std::uint64_t>(GeometryInfo<dim>::max_children_per_cell,
140 i) *
142
143 max_cell_index -= 1;
144
145 Assert(
146 max_cell_index <= std::numeric_limits<types::global_cell_index>::max(),
148 "You have exceeded the maximal number of possible indices this function "
149 "can handle. The current setup (n_coarse_cells=" +
150 std::to_string(n_coarse_cells) +
151 ", n_global_levels=" + std::to_string(n_global_levels) + ") requires " +
152 std::to_string(max_cell_index + 1) +
153 " indices but the current deal.II configuration only supports " +
154 std::to_string(std::numeric_limits<types::global_cell_index>::max()) +
155 " indices. You may want to consider to build deal.II with 64bit "
156 "indices (-D DEAL_II_WITH_64BIT_INDICES=\"ON\") to increase the limit "
157 "of indices."));
158#endif
159
160 // Now do the whole computation again, but for real:
161 tree_sizes.reserve(n_global_levels + 1);
162 tree_sizes.push_back(0);
163 for (unsigned int i = 0; i < n_global_levels; ++i)
164 tree_sizes.push_back(tree_sizes.back() +
165 Utilities::pow<types::global_cell_index>(
168 }
169
170
171
172 template <int dim>
175 {
176 return n_coarse_cells *
177 (Utilities::pow<types::global_cell_index>(
179 1);
180 }
181
182
183
184 template <int dim>
185 template <typename Accessor>
188 {
189 static_assert(dim == Accessor::dimension &&
190 dim == Accessor::structure_dimension,
191 "The information can only be queried for cells.");
192
194
195 id += convert_cell_id_binary_type_to_level_coarse_cell_id(
197 .id()
198 .template to_binary<dim>());
199
200 id += tree_sizes[cell->level()];
201
202 return id;
203 }
204
205
206
207 template <int dim>
208 template <typename Accessor>
211 const types::global_cell_index i) const
212 {
213 static_assert(dim == Accessor::dimension &&
214 dim == Accessor::structure_dimension,
215 "The information can only be queried for cells.");
216
217 return (translate(cell) - tree_sizes[cell->level()]) *
219 i + tree_sizes[cell->level() + 1];
220 }
221
222
223
224 template <int dim>
225 CellId
227 {
228 std::vector<std::uint8_t> child_indices;
229
230 types::global_cell_index id_temp = id;
231
233
234 for (; level < n_global_levels; ++level)
235 if (id < tree_sizes[level])
236 break;
237 level -= 1;
238
239 id_temp -= tree_sizes[level];
240
241 for (types::global_cell_index l = 0; l < level; ++l)
242 {
243 child_indices.push_back(id_temp %
246 }
247
248 std::reverse(child_indices.begin(), child_indices.end());
249
250 return {id_temp, child_indices}; // TODO
251 }
252
253
254
255 template <int dim>
258 const typename CellId::binary_type &binary_representation)
259 {
260 // exploiting the structure of CellId::binary_type
261 // see also the documentation of CellId
262
263 // actual coarse-grid id
264 const unsigned int coarse_cell_id = binary_representation[0];
265 const unsigned int n_child_indices = binary_representation[1] >> 2;
266
267 const unsigned int children_per_value =
268 sizeof(CellId::binary_type::value_type) * 8 / dim;
269 unsigned int child_level = 0;
270 unsigned int binary_entry = 2;
271
272 // path to the get to the cell
273 std::vector<unsigned int> cell_indices;
274 while (child_level < n_child_indices)
275 {
276 Assert(binary_entry < binary_representation.size(), ExcInternalError());
277
278 for (unsigned int j = 0; j < children_per_value; ++j)
279 {
280 unsigned int cell_index =
281 (((binary_representation[binary_entry] >> (j * dim))) &
283 cell_indices.push_back(cell_index);
284 ++child_level;
285 if (child_level == n_child_indices)
286 break;
287 }
288 ++binary_entry;
289 }
290
291 // compute new coarse-grid id: c_{i+1} = c_{i}*2^dim + q;
292 types::global_cell_index level_coarse_cell_id = coarse_cell_id;
293 for (auto i : cell_indices)
294 level_coarse_cell_id =
295 level_coarse_cell_id * GeometryInfo<dim>::max_children_per_cell + i;
296
297 return level_coarse_cell_id;
298 }
299
300} // namespace internal
301
303
304#endif
std::array< unsigned int, 4 > binary_type
Definition cell_id.h:81
const types::global_cell_index n_global_levels
types::global_cell_index translate(const TriaIterator< Accessor > &cell) const
static types::global_cell_index convert_cell_id_binary_type_to_level_coarse_cell_id(const typename CellId::binary_type &binary_representation)
CellIDTranslator(const types::global_cell_index n_coarse_cells, const types::global_cell_index n_global_levels)
std::vector< types::global_cell_index > tree_sizes
CellId to_cell_id(const types::global_cell_index id) const
const types::global_cell_index n_coarse_cells
types::global_cell_index size() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
unsigned int level
Definition grid_out.cc:4618
unsigned int cell_index
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)