deal.II version GIT relicensing-2291-g668cd86249 2024-12-24 11:30:00+00:00
\(\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// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2021 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_cell_id_translator_h
16#define dealii_cell_id_translator_h
17
20
23
24#include <cstdint>
25#include <limits>
26
28
29namespace internal
30{
53 template <int dim>
55 {
56 public:
63
69 size() const;
70
75 template <typename Accessor>
77 translate(const TriaIterator<Accessor> &cell) const;
78
83 template <typename Accessor>
86
90 template <typename Accessor>
93 const types::global_cell_index i) const;
94
98 CellId
100
101 private:
107 const typename CellId::binary_type &binary_representation);
108
113
118
122 std::vector<types::global_cell_index> tree_sizes;
123 };
124
125
126
127 template <int dim>
129 const types::global_cell_index n_coarse_cells,
130 const types::global_cell_index n_global_levels)
131 : n_coarse_cells(n_coarse_cells)
132 , n_global_levels(n_global_levels)
133 {
134 // The class stores indices as types::global_cell_index variables,
135 // but when configuring deal.II with default flags, this is a 32-bit
136 // data type and it is possible with highly (locally) refined meshes
137 // that we exceed the maximal 32-bit numbers even with relatively
138 // modest numbers of cells. Check for this by first calculating
139 // the maximal index we will get in 64-bit arithmetic and testing
140 // that it is representable in 32-bit arithmetic:
141 std::uint64_t max_cell_index = 0;
142
143 for (unsigned int i = 0; i < n_global_levels; ++i)
144 max_cell_index +=
145 Utilities::pow<std::uint64_t>(GeometryInfo<dim>::max_children_per_cell,
146 i) *
148
149 max_cell_index -= 1;
150
152 max_cell_index <= std::numeric_limits<types::global_cell_index>::max(),
154 "You have exceeded the maximal number of possible indices this function "
155 "can handle. The current setup (n_coarse_cells=" +
156 std::to_string(n_coarse_cells) +
157 ", n_global_levels=" + std::to_string(n_global_levels) + ") requires " +
158 std::to_string(max_cell_index + 1) +
159 " indices but the current deal.II configuration only supports " +
160 std::to_string(std::numeric_limits<types::global_cell_index>::max()) +
161 " indices. You may want to consider to build deal.II with 64bit "
162 "indices (-D DEAL_II_WITH_64BIT_INDICES=\"ON\") to increase the limit "
163 "of indices."));
164
165 // Now do the whole computation again, but for real:
166 tree_sizes.reserve(n_global_levels + 1);
167 tree_sizes.push_back(0);
168 for (unsigned int i = 0; i < n_global_levels; ++i)
169 tree_sizes.push_back(tree_sizes.back() +
170 Utilities::pow<types::global_cell_index>(
173 }
174
175
176
177 template <int dim>
180 {
181 return n_coarse_cells *
182 (Utilities::pow<types::global_cell_index>(
184 1);
185 }
186
187
188
189 template <int dim>
190 template <typename Accessor>
193 {
194 static_assert(dim == Accessor::dimension &&
195 dim == Accessor::structure_dimension,
196 "The information can only be queried for cells.");
197
198 return translate_level(cell) + tree_sizes[cell->level()];
199 }
200
201
202
203 template <int dim>
204 template <typename Accessor>
207 {
208 static_assert(dim == Accessor::dimension &&
209 dim == Accessor::structure_dimension,
210 "The information can only be queried for cells.");
211
212 return convert_cell_id_binary_type_to_level_coarse_cell_id(
214 .id()
215 .template to_binary<dim>());
216 }
217
218
219
220 template <int dim>
221 template <typename Accessor>
224 const types::global_cell_index i) const
225 {
226 static_assert(dim == Accessor::dimension &&
227 dim == Accessor::structure_dimension,
228 "The information can only be queried for cells.");
229
230 return (translate(cell) - tree_sizes[cell->level()]) *
232 i + tree_sizes[cell->level() + 1];
233 }
234
235
236
237 template <int dim>
238 CellId
240 {
241 std::vector<std::uint8_t> child_indices;
242
243 types::global_cell_index id_temp = id;
244
246
247 for (; level < n_global_levels; ++level)
248 if (id < tree_sizes[level])
249 break;
250 level -= 1;
251
252 id_temp -= tree_sizes[level];
253
254 for (types::global_cell_index l = 0; l < level; ++l)
255 {
256 child_indices.push_back(id_temp %
259 }
260
261 std::reverse(child_indices.begin(), child_indices.end());
262
263 return {id_temp, child_indices};
264 }
265
266
267
268 template <int dim>
271 const typename CellId::binary_type &binary_representation)
272 {
273 // exploiting the structure of CellId::binary_type
274 // see also the documentation of CellId
275
276 // actual coarse-grid id
277 const unsigned int coarse_cell_id = binary_representation[0];
278 const unsigned int n_child_indices = binary_representation[1] >> 2;
279
280 const unsigned int children_per_value =
281 sizeof(CellId::binary_type::value_type) * 8 / dim;
282 unsigned int child_level = 0;
283 unsigned int binary_entry = 2;
284
285 // compute new coarse-grid id: c_{i+1} = c_{i}*2^dim + q on path to cell
286 types::global_cell_index level_coarse_cell_id = coarse_cell_id;
287 while (child_level < n_child_indices)
288 {
289 Assert(binary_entry < binary_representation.size(), ExcInternalError());
290
291 for (unsigned int j = 0; j < children_per_value; ++j)
292 {
293 unsigned int cell_index =
294 (((binary_representation[binary_entry] >> (j * dim))) &
296 level_coarse_cell_id =
297 level_coarse_cell_id * GeometryInfo<dim>::max_children_per_cell +
299 ++child_level;
300 if (child_level == n_child_indices)
301 break;
302 }
303 ++binary_entry;
304 }
305
306 return level_coarse_cell_id;
307 }
308
309} // namespace internal
310
312
313#endif
std::array< unsigned int, 4 > binary_type
Definition cell_id.h:80
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
static types::global_cell_index translate_level(const TriaIterator< Accessor > &cell)
const types::global_cell_index n_coarse_cells
types::global_cell_index size() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
unsigned int level
Definition grid_out.cc:4632
unsigned int cell_index
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)