deal.II version GIT relicensing-6839-g338455934c 2026-10-02 12:10:01+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.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2021 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
16
18#include <deal.II/grid/tria.h>
20
21#include <algorithm>
22#include <cstdint>
23#include <limits>
24
26
27namespace internal
28{
29 template <int dim>
30 template <int spacedim>
33 : has_pyramids(dim == 3 && std::find(tria.get_reference_cells().begin(),
34 tria.get_reference_cells().end(),
35 ReferenceCells::Pyramid) !=
36 tria.get_reference_cells().end())
37 , max_children_per_cell(
38 has_pyramids ?
39 ReferenceCells::max_n_children<dim>() :
40 ReferenceCells::get_hypercube<dim>().n_isotropic_children())
41 , n_coarse_cells(tria.n_global_coarse_cells())
42 , n_global_levels(tria.n_global_levels())
43 {
44 // The class stores indices as types::global_cell_index variables,
45 // but when configuring deal.II with default flags, this is a 32-bit
46 // data type and it is possible with highly (locally) refined meshes
47 // that we exceed the maximal 32-bit numbers even with relatively
48 // modest numbers of cells. Check for this by first calculating
49 // the maximal index we will get in 64-bit arithmetic and testing
50 // that it is representable in 32-bit arithmetic:
51 std::uint64_t max_cell_index = 0;
52
53 for (unsigned int i = 0; i < n_global_levels; ++i)
54 max_cell_index +=
55 Utilities::pow<std::uint64_t>(max_children_per_cell, i) *
57
58 max_cell_index -= 1;
59
61 max_cell_index <= std::numeric_limits<types::global_cell_index>::max(),
63 "You have exceeded the maximal number of possible indices this function "
64 "can handle. The current setup (n_coarse_cells=" +
65 std::to_string(n_coarse_cells) +
66 ", n_global_levels=" + std::to_string(n_global_levels) + ") requires " +
67 std::to_string(max_cell_index + 1) +
68 " indices but the current deal.II configuration only supports " +
69 std::to_string(std::numeric_limits<types::global_cell_index>::max()) +
70 " indices. You may want to consider to build deal.II with 64bit "
71 "indices (-D DEAL_II_WITH_64BIT_INDICES=\"ON\") to increase the limit "
72 "of indices."));
73
74 // Now do the whole computation again, but for real:
75 tree_sizes.reserve(n_global_levels + 1);
76 tree_sizes.push_back(0);
77 for (unsigned int i = 0; i < n_global_levels; ++i)
78 tree_sizes.push_back(
79 tree_sizes.back() +
80 Utilities::pow<types::global_cell_index>(max_children_per_cell, i) *
82 }
83
84
85
86 template <int dim>
87 CellId
89 {
91 child_indices;
92
93 std::uint8_t level = 0;
94 for (; level < n_global_levels; ++level)
95 if (id < tree_sizes[level])
96 break;
98 level -= 1;
99
100 types::coarse_cell_id id_temp = id - tree_sizes[level];
101 for (std::uint8_t l = 0; l < level; ++l)
102 {
103 // Dividing by a known constant is much more efficient than diving by an
104 // arbitrary integer, so special case Pyramids and non-Pyramids:
105 if (has_pyramids)
106 {
107 constexpr unsigned int pyramid_max_children_per_cell =
108 ReferenceCells::Pyramid.n_isotropic_children();
109 Assert(max_children_per_cell <= pyramid_max_children_per_cell,
111 child_indices.push_back(id_temp % pyramid_max_children_per_cell);
112 id_temp /= pyramid_max_children_per_cell;
113 }
114 else
115 {
116 constexpr unsigned int hypercube_max_children_per_cell =
117 ReferenceCells::get_hypercube<dim>().n_isotropic_children();
118 // this value is equal for simplices and wedges (i.e., not pyramids)
119 // but we only need it to bound the actual maximum number of
120 // children per cell for this to work
121 Assert(max_children_per_cell <= hypercube_max_children_per_cell,
123 child_indices.push_back(id_temp % hypercube_max_children_per_cell);
124 id_temp /= hypercube_max_children_per_cell;
125 }
126 }
127
128 std::reverse(child_indices.begin(), child_indices.end());
129
130 return CellId(id_temp,
131 static_cast<unsigned int>(child_indices.size()),
132 child_indices.data());
133 }
134
135
136
137 template <int dim>
140 {
141 // compute level id: c_{i+1} = c_{i}*(max_n_children) + q on path to cell
142 auto level_cell_id = cell_id.get_coarse_cell_id();
143 for (const auto &child_index : cell_id.get_child_indices())
144 level_cell_id = level_cell_id * max_children_per_cell + child_index;
145
146 return level_cell_id;
147 }
148
149} // namespace internal
150
151
152// explicit instantiations
153#include "grid/cell_id_translator.inst"
154
*  iterator end()
*  *  iterator begin()
ArrayView< const std::uint8_t > get_child_indices() const
Definition cell_id.h:393
types::coarse_cell_id get_coarse_cell_id() const
Definition cell_id.h:385
const types::global_cell_index n_global_levels
const unsigned int max_children_per_cell
CellIDTranslator(const Triangulation< dim, spacedim > &tria)
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 to_level_cell_index(const CellId &cell_id) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
unsigned int level
Definition grid_out.cc:4642
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
constexpr ReferenceCell< 3 > Pyramid
constexpr std::uint8_t max_n_levels
Definition types.h:415
STL namespace.