deal.II version GIT relicensing-1991-gec5bc16adb 2024-10-14 08:00: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
82 template <typename Accessor>
85 const types::global_cell_index i) const;
86
90 CellId
92
93 private:
99 const typename CellId::binary_type &binary_representation);
100
105
110
114 std::vector<types::global_cell_index> tree_sizes;
115 };
116
117
118
119 template <int dim>
121 const types::global_cell_index n_coarse_cells,
122 const types::global_cell_index n_global_levels)
123 : n_coarse_cells(n_coarse_cells)
124 , n_global_levels(n_global_levels)
125 {
126 // The class stores indices as types::global_cell_index variables,
127 // but when configuring deal.II with default flags, this is a 32-bit
128 // data type and it is possible with highly (locally) refined meshes
129 // that we exceed the maximal 32-bit numbers even with relatively
130 // modest numbers of cells. Check for this by first calculating
131 // the maximal index we will get in 64-bit arithmetic and testing
132 // that it is representable in 32-bit arithmetic:
133 std::uint64_t max_cell_index = 0;
134
135 for (unsigned int i = 0; i < n_global_levels; ++i)
136 max_cell_index +=
137 Utilities::pow<std::uint64_t>(GeometryInfo<dim>::max_children_per_cell,
138 i) *
140
141 max_cell_index -= 1;
142
144 max_cell_index <= std::numeric_limits<types::global_cell_index>::max(),
146 "You have exceeded the maximal number of possible indices this function "
147 "can handle. The current setup (n_coarse_cells=" +
148 std::to_string(n_coarse_cells) +
149 ", n_global_levels=" + std::to_string(n_global_levels) + ") requires " +
150 std::to_string(max_cell_index + 1) +
151 " indices but the current deal.II configuration only supports " +
152 std::to_string(std::numeric_limits<types::global_cell_index>::max()) +
153 " indices. You may want to consider to build deal.II with 64bit "
154 "indices (-D DEAL_II_WITH_64BIT_INDICES=\"ON\") to increase the limit "
155 "of indices."));
156
157 // Now do the whole computation again, but for real:
158 tree_sizes.reserve(n_global_levels + 1);
159 tree_sizes.push_back(0);
160 for (unsigned int i = 0; i < n_global_levels; ++i)
161 tree_sizes.push_back(tree_sizes.back() +
162 Utilities::pow<types::global_cell_index>(
165 }
166
167
168
169 template <int dim>
172 {
173 return n_coarse_cells *
174 (Utilities::pow<types::global_cell_index>(
176 1);
177 }
178
179
180
181 template <int dim>
182 template <typename Accessor>
185 {
186 static_assert(dim == Accessor::dimension &&
187 dim == Accessor::structure_dimension,
188 "The information can only be queried for cells.");
189
191
192 id += convert_cell_id_binary_type_to_level_coarse_cell_id(
194 .id()
195 .template to_binary<dim>());
196
197 id += tree_sizes[cell->level()];
198
199 return id;
200 }
201
202
203
204 template <int dim>
205 template <typename Accessor>
208 const types::global_cell_index i) const
209 {
210 static_assert(dim == Accessor::dimension &&
211 dim == Accessor::structure_dimension,
212 "The information can only be queried for cells.");
213
214 return (translate(cell) - tree_sizes[cell->level()]) *
216 i + tree_sizes[cell->level() + 1];
217 }
218
219
220
221 template <int dim>
222 CellId
224 {
225 std::vector<std::uint8_t> child_indices;
226
227 types::global_cell_index id_temp = id;
228
230
231 for (; level < n_global_levels; ++level)
232 if (id < tree_sizes[level])
233 break;
234 level -= 1;
235
236 id_temp -= tree_sizes[level];
237
238 for (types::global_cell_index l = 0; l < level; ++l)
239 {
240 child_indices.push_back(id_temp %
243 }
244
245 std::reverse(child_indices.begin(), child_indices.end());
246
247 return {id_temp, child_indices}; // TODO
248 }
249
250
251
252 template <int dim>
255 const typename CellId::binary_type &binary_representation)
256 {
257 // exploiting the structure of CellId::binary_type
258 // see also the documentation of CellId
259
260 // actual coarse-grid id
261 const unsigned int coarse_cell_id = binary_representation[0];
262 const unsigned int n_child_indices = binary_representation[1] >> 2;
263
264 const unsigned int children_per_value =
265 sizeof(CellId::binary_type::value_type) * 8 / dim;
266 unsigned int child_level = 0;
267 unsigned int binary_entry = 2;
268
269 // compute new coarse-grid id: c_{i+1} = c_{i}*2^dim + q on path to cell
270 types::global_cell_index level_coarse_cell_id = coarse_cell_id;
271 while (child_level < n_child_indices)
272 {
273 Assert(binary_entry < binary_representation.size(), ExcInternalError());
274
275 for (unsigned int j = 0; j < children_per_value; ++j)
276 {
277 unsigned int cell_index =
278 (((binary_representation[binary_entry] >> (j * dim))) &
280 level_coarse_cell_id =
281 level_coarse_cell_id * GeometryInfo<dim>::max_children_per_cell +
283 ++child_level;
284 if (child_level == n_child_indices)
285 break;
286 }
287 ++binary_entry;
288 }
289
290 return level_coarse_cell_id;
291 }
292
293} // namespace internal
294
296
297#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
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:4626
unsigned int cell_index
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)