deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00: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
tria_objects.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) 2006 - 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
14
15#include <deal.II/grid/tria.h>
19
20#include <algorithm>
21#include <functional>
22
23
24
26
27namespace internal
28{
29 namespace TriangulationImplementation
30 {
31 template <int dim, int spacedim>
32 typename ::Triangulation<dim, spacedim>::raw_hex_iterator
33 TriaObjects::next_free_hex(const ::Triangulation<dim, spacedim> &tria,
34 const unsigned int level)
35 {
36 AssertDimension(this->structdim, 3);
37
38 // TODO: Think of a way to ensure that we are using the correct
39 // triangulation, i.e. the one containing *this.
40
41 int pos = next_free_pair, last = used.size() - 1;
42 for (; pos < last; ++pos)
43 if (!used[pos])
44 {
45 // this should be a pair slot
46 Assert(!used[pos + 1], ExcInternalError());
47 break;
48 }
49 if (pos >= last)
50 // no free slot
51 return tria.end_hex();
52 else
53 next_free_pair = pos + 2;
54
55 return
56 typename ::Triangulation<dim, spacedim>::raw_hex_iterator(&tria,
57 level,
58 pos);
59 }
60
61
62
63 void
64 TriaObjects::allocate(const std::size_t n_objects)
65 {
66 used.assign(n_objects, true);
68 manifold_id.assign(n_objects, -1);
69 user_flags.assign(n_objects, false);
70 user_data.resize(n_objects);
71
72 // Lines can only be refined in one way so, in that case, we don't need to
73 // store a field indicating which type of refinement to use per object
74 if (structdim > 1)
75 refinement_cases.assign(n_objects, 0);
76
78 children.assign(children_per_object / 2 * n_objects, -1);
79
81
82 if (structdim <= 2)
83 {
87 }
88 else
89 {
91 }
92 }
93
94
95
96 void
97 TriaObjects::allocate_end(const std::size_t new_objects_in_pairs,
98 const std::size_t new_objects_single)
99 {
100 if (structdim <= 2)
101 {
102 Assert(new_objects_in_pairs % 2 == 0, ExcInternalError());
103
105 next_free_pair = 0;
107
108 // count the number of objects, of unused single objects and of
109 // unused pairs of objects
110 std::size_t n_objects = 0;
111 std::size_t n_unused_pairs = 0;
112 std::size_t n_unused_singles = 0;
113 for (std::size_t i = 0; i < used.size(); ++i)
114 {
115 if (used[i])
116 ++n_objects;
117 else if (i + 1 < used.size())
118 {
119 if (used[i + 1])
120 {
121 ++n_unused_singles;
122 if (next_free_single == 0)
124 }
125 else
126 {
127 ++n_unused_pairs;
128 if (next_free_pair == 0)
129 next_free_pair = i;
130 ++i;
131 }
132 }
133 else
134 ++n_unused_singles;
135 }
136 Assert(n_objects + 2 * n_unused_pairs + n_unused_singles ==
137 used.size(),
139
140 // how many single objects are needed in addition to
141 // n_unused_objects?
142 const std::ptrdiff_t additional_single_objects =
143 new_objects_single - n_unused_singles;
144
145 Assert(used.size() + new_objects_in_pairs >= 2 * n_unused_pairs,
147 std::size_t new_size =
148 used.size() + new_objects_in_pairs - 2 * n_unused_pairs;
149 if (additional_single_objects > 0)
150 new_size += additional_single_objects;
151
152 // only allocate space if necessary
153 if (new_size > this->n_objects())
154 {
155 bounding_objects.reserve(new_size * faces_per_object);
157 (new_size - this->n_objects()) *
159 -1);
160
161 used.reserve(new_size);
162 used.insert(used.end(), new_size - used.size(), false);
163
164 user_flags.reserve(new_size);
165 user_flags.insert(user_flags.end(),
166 new_size - user_flags.size(),
167 false);
168
169 const auto factor = children_per_object / 2;
170 children.reserve(factor * new_size);
171 children.insert(children.end(),
172 factor * new_size - children.size(),
173 -1);
174
175 if (structdim > 1)
176 {
177 refinement_cases.reserve(new_size);
179 new_size - refinement_cases.size(),
180 /*RefinementCase::no_refinement=*/0);
181 }
182
183 // first reserve, then resize. Otherwise the std library can
184 // decide to allocate more entries.
185 boundary_or_material_id.reserve(new_size);
186 boundary_or_material_id.resize(new_size);
187
188 user_data.reserve(new_size);
189 user_data.resize(new_size);
190
191 manifold_id.reserve(new_size);
192 manifold_id.insert(manifold_id.end(),
193 new_size - manifold_id.size(),
195 }
196
197 if (n_unused_singles == 0)
198 {
199 next_free_single = new_size - 1;
201 }
202 }
203 else
204 {
205 const auto new_hexes = new_objects_in_pairs;
206
207 const auto new_size =
208 new_hexes + std::count(used.begin(), used.end(), true);
209
210 // see above...
211 if (new_size > this->n_objects())
212 {
213 bounding_objects.reserve(new_size * faces_per_object);
215 (new_size - this->n_objects()) *
217 -1);
218
219 used.reserve(new_size);
220 used.insert(used.end(), new_size - used.size(), false);
221
222 user_flags.reserve(new_size);
223 user_flags.insert(user_flags.end(),
224 new_size - user_flags.size(),
225 false);
226
227 const auto factor = children_per_object / 2;
228 children.reserve(factor * new_size);
229 children.insert(children.end(),
230 factor * new_size - children.size(),
231 -1);
232
233 // for the following fields, we know exactly how many elements
234 // we need, so first reserve then resize (resize itself, at least
235 // with some compiler libraries, appears to round up the size it
236 // actually reserves)
237 boundary_or_material_id.reserve(new_size);
238 boundary_or_material_id.resize(new_size);
239
240 manifold_id.reserve(new_size);
241 manifold_id.insert(manifold_id.end(),
242 new_size - manifold_id.size(),
244
245 user_data.reserve(new_size);
246 user_data.resize(new_size);
247
248 refinement_cases.reserve(new_size);
250 new_size - refinement_cases.size(),
251 /*RefinementCase::no_refinement=*/0);
252 }
254 }
255 }
256
257
258
259 std::size_t
271
272
273
274 // explicit instantiations
275#ifndef DOXYGEN
276# include "grid/tria_objects.inst"
277#endif
278 } // namespace TriangulationImplementation
279} // namespace internal
280
std::vector< types::manifold_id > manifold_id
void allocate_end(const std::size_t new_objects_in_pairs, const std::size_t new_objects_single)
Triangulation< dim, spacedim >::raw_hex_iterator next_free_hex(const Triangulation< dim, spacedim > &tria, const unsigned int level)
void allocate(const std::size_t n_objects)
std::vector< BoundaryOrMaterialId > boundary_or_material_id
#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)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
constexpr types::manifold_id flat_manifold_id
Definition types.h:332