deal.II version 9.8.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
grid_tools_cache.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) 2017 - 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
15
19
21
22namespace GridTools
23{
24 template <int dim, int spacedim>
34
35
36
37 template <int dim, int spacedim>
40 , tria(&tria)
41 {
43 tria.signals.any_change.connect([&]() { mark_for_update(update_all); });
44
45 // Allow users to set this class up with an empty Triangulation and no
46 // Mapping argument by deferring Mapping assignment until after the
47 // Triangulation exists.
48 if (tria.get_reference_cells().size() == 0)
49 {
50 tria_create_signal = tria.signals.create.connect([&]() {
51 Assert(tria.get_reference_cells().size() > 0, ExcInternalError());
52 Assert(tria.get_reference_cells().size() == 1, ExcNotImplemented());
53 mapping = &tria.get_reference_cells()[0]
54 .template get_default_linear_mapping<spacedim>();
55 });
56 }
57 else
58 {
59 Assert(tria.get_reference_cells().size() == 1, ExcNotImplemented());
60 mapping = &tria.get_reference_cells()[0]
62 }
63 }
64
65 template <int dim, int spacedim>
67 {
68 if (tria_change_signal.connected())
69 tria_change_signal.disconnect();
70 if (tria_create_signal.connected())
71 tria_create_signal.disconnect();
72 }
73
74
75
76 template <int dim, int spacedim>
77 void
82
83
84
85 template <int dim, int spacedim>
86 const std::vector<
87 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>> &
89 {
90 // In the following, we will first check whether the data structure
91 // in question needs to be updated (in which case we update it, and
92 // reset the flag that indices that this needs to happen to zero), and
93 // then return it. Make this thread-safe by using a mutex to guard
94 // all of this:
95 std::scoped_lock lock(vertex_to_cells_mutex);
96
98 {
100
101 // Atomically clear the flag that indicates that this data member
102 // needs to be updated:
105 return vertex_to_cells;
106 }
107
108
109
110 template <int dim, int spacedim>
111 const std::vector<std::vector<Tensor<1, spacedim>>> &
114 // In the following, we will first check whether the data structure
115 // in question needs to be updated (in which case we update it, and
116 // reset the flag that indices that this needs to happen to zero), and
117 // then return it. Make this thread-safe by using a mutex to guard
118 // all of this:
119 std::scoped_lock lock(vertex_to_cell_centers_mutex);
122 {
125
126 // Atomically clear the flag that indicates that this data member
127 // needs to be updated:
129 }
130 return vertex_to_cell_centers;
131 }
132
133
135 template <int dim, int spacedim>
136 const std::map<unsigned int, Point<spacedim>> &
138 {
139 // In the following, we will first check whether the data structure
140 // in question needs to be updated (in which case we update it, and
141 // reset the flag that indices that this needs to happen to zero), and
142 // then return it. Make this thread-safe by using a mutex to guard
143 // all of this:
144 std::scoped_lock lock(used_vertices_mutex);
147 {
149
150 // Atomically clear the flag that indicates that this data member
151 // needs to be updated:
153 }
154 return used_vertices;
155 }
156
157
158
159 template <int dim, int spacedim>
160 const RTree<std::pair<Point<spacedim>, unsigned int>> &
162 {
163 // In the following, we will first check whether the data structure
164 // in question needs to be updated (in which case we update it, and
165 // reset the flag that indices that this needs to happen to zero), and
166 // then return it. Make this thread-safe by using a mutex to guard
167 // all of this:
168 std::scoped_lock lock(used_vertices_rtree_mutex);
169
171 {
172 const auto &used_vertices = get_used_vertices();
173 std::vector<std::pair<Point<spacedim>, unsigned int>> vertices(
174 used_vertices.size());
175 unsigned int i = 0;
176 for (const auto &it : used_vertices)
177 vertices[i++] = std::make_pair(it.second, it.first);
179
180 // Atomically clear the flag that indicates that this data member
181 // needs to be updated:
183 }
184 return used_vertices_rtree;
185 }
186
187
188
189 template <int dim, int spacedim>
190 const RTree<
191 std::pair<BoundingBox<spacedim>,
194 {
195 // In the following, we will first check whether the data structure
196 // in question needs to be updated (in which case we update it, and
197 // reset the flag that indices that this needs to happen to zero), and
198 // then return it. Make this thread-safe by using a mutex to guard
199 // all of this:
200 std::scoped_lock lock(cell_bounding_boxes_rtree_mutex);
201
203 {
204 std::vector<std::pair<
207 boxes;
208 boxes.reserve(tria->n_active_cells());
209 for (const auto &cell : tria->active_cell_iterators())
210 boxes.emplace_back(mapping->get_bounding_box(cell), cell);
211
213
214 // Atomically clear the flag that indicates that this data member
215 // needs to be updated:
217 }
219 }
220
222
223 template <int dim, int spacedim>
224 const RTree<
225 std::pair<BoundingBox<spacedim>,
228 {
229 // In the following, we will first check whether the data structure
230 // in question needs to be updated (in which case we update it, and
231 // reset the flag that indices that this needs to happen to zero), and
232 // then return it. Make this thread-safe by using a mutex to guard
233 // all of this:
235
237 {
238 std::vector<std::pair<
241 boxes;
242 if (const parallel::TriangulationBase<dim, spacedim> *parallel_tria =
243 dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(
244 &*tria))
245 boxes.reserve(parallel_tria->n_locally_owned_active_cells());
246 else
247 boxes.reserve(tria->n_active_cells());
248 for (const auto &cell : tria->active_cell_iterators() |
250 boxes.emplace_back(mapping->get_bounding_box(cell), cell);
251
253
254 // Atomically clear the flag that indicates that this data member
255 // needs to be updated:
257 }
259 }
260
261
262
263 template <int dim, int spacedim>
264 const RTree<std::pair<BoundingBox<spacedim>, unsigned int>> &
265 Cache<dim, spacedim>::get_covering_rtree(const unsigned int level) const
266 {
267 // In the following, we will first check whether the data structure
268 // in question needs to be updated (in which case we update it, and
269 // reset the flag that indices that this needs to happen to zero), and
270 // then return it. Make this thread-safe by using a mutex to guard
271 // all of this:
272 std::scoped_lock lock(covering_rtree_mutex);
273
275 covering_rtree.find(level) == covering_rtree.end())
276 {
277 const auto boxes =
279 level);
280
281 if (const auto tria_mpi =
282 dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(
283 &(*tria)))
284 {
286 boxes, tria_mpi->get_mpi_communicator());
287 }
288 else
289 {
290 covering_rtree[level] =
291 GridTools::build_global_description_tree(boxes, MPI_COMM_SELF);
292 }
293
294 // Atomically clear the flag that indicates that this data member
295 // needs to be updated:
297 }
298
299 return covering_rtree[level];
300 }
301
302
303
304 template <int dim, int spacedim>
305 const std::vector<std::set<unsigned int>> &
307 {
308 // In the following, we will first check whether the data structure
309 // in question needs to be updated (in which case we update it, and
310 // reset the flag that indices that this needs to happen to zero), and
311 // then return it. Make this thread-safe by using a mutex to guard
312 // all of this:
313 std::scoped_lock lock(vertex_to_neighbor_subdomain_mutex);
314
316 {
318 vertex_to_neighbor_subdomain.resize(tria->n_vertices());
319 for (const auto &cell : tria->active_cell_iterators())
320 {
321 if (cell->is_ghost())
322 for (const unsigned int v : cell->vertex_indices())
323 vertex_to_neighbor_subdomain[cell->vertex_index(v)].insert(
324 cell->subdomain_id());
325 }
326 // Atomically clear the flag that indicates that this data member
327 // needs to be updated:
329 }
331 }
332
333
334
335 template <int dim, int spacedim>
336 const std::map<unsigned int, std::set<types::subdomain_id>> &
338 {
339 // In the following, we will first check whether the data structure
340 // in question needs to be updated (in which case we update it, and
341 // reset the flag that indices that this needs to happen to zero), and
342 // then return it. Make this thread-safe by using a mutex to guard
343 // all of this:
344 std::scoped_lock lock(vertices_with_ghost_neighbors_mutex);
345
347 {
350
351 // Atomically clear the flag that indicates that this data member
352 // needs to be updated:
354 }
355
357 }
358
359#include "grid/grid_tools_cache.inst"
360
361} // namespace GridTools
362
const std::vector< std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > > & get_vertex_to_cell_map() const
std::vector< std::vector< Tensor< 1, spacedim > > > vertex_to_cell_centers
std::mutex cell_bounding_boxes_rtree_mutex
std::mutex covering_rtree_mutex
const RTree< std::pair< BoundingBox< spacedim >, unsigned int > > & get_covering_rtree(const unsigned int level=0) const
ObserverPointer< const Mapping< dim, spacedim >, Cache< dim, spacedim > > mapping
std::vector< std::set< unsigned int > > vertex_to_neighbor_subdomain
const std::vector< std::vector< Tensor< 1, spacedim > > > & get_vertex_to_cell_centers_directions() const
boost::signals2::connection tria_change_signal
Cache(const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping)
boost::signals2::connection tria_create_signal
RTree< std::pair< BoundingBox< spacedim >, typename Triangulation< dim, spacedim >::active_cell_iterator > > cell_bounding_boxes_rtree
RTree< std::pair< BoundingBox< spacedim >, typename Triangulation< dim, spacedim >::active_cell_iterator > > locally_owned_cell_bounding_boxes_rtree
const std::vector< std::set< unsigned int > > & get_vertex_to_neighbor_subdomain() const
std::mutex vertex_to_neighbor_subdomain_mutex
std::map< unsigned int, Point< spacedim > > used_vertices
const std::map< unsigned int, std::set< types::subdomain_id > > & get_vertices_with_ghost_neighbors() const
const RTree< std::pair< BoundingBox< spacedim >, typename Triangulation< dim, spacedim >::active_cell_iterator > > & get_locally_owned_cell_bounding_boxes_rtree() const
RTree< std::pair< Point< spacedim >, unsigned int > > used_vertices_rtree
std::mutex used_vertices_rtree_mutex
std::atomic< std::underlying_type_t< CacheUpdateFlags > > update_flags
const RTree< std::pair< Point< spacedim >, unsigned int > > & get_used_vertices_rtree() const
std::map< unsigned int, std::set<::types::subdomain_id > > vertices_with_ghost_neighbors
const RTree< std::pair< BoundingBox< spacedim >, typename Triangulation< dim, spacedim >::active_cell_iterator > > & get_cell_bounding_boxes_rtree() const
std::vector< std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > > vertex_to_cells
std::mutex locally_owned_cell_bounding_boxes_rtree_mutex
const std::map< unsigned int, Point< spacedim > > & get_used_vertices() const
std::mutex vertices_with_ghost_neighbors_mutex
std::map< unsigned int, RTree< std::pair< BoundingBox< spacedim >, unsigned int > > > covering_rtree
ObserverPointer< const Triangulation< dim, spacedim >, Cache< dim, spacedim > > tria
void mark_for_update(const CacheUpdateFlags &flags=update_all)
std::mutex used_vertices_mutex
Abstract base class for mapping classes.
Definition mapping.h:318
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
TriaActiveIterator< CellAccessor< dim, spacedim > > active_cell_iterator
Definition tria.h:1648
const Mapping< dim, spacedim > & get_default_linear_mapping(const Triangulation< dim, spacedim > &triangulation)
Definition mapping.cc:314
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
Definition mapping_q1.h:101
RTree< std::pair< BoundingBox< spacedim >, unsigned int > > build_global_description_tree(const std::vector< BoundingBox< spacedim > > &local_description, const MPI_Comm mpi_communicator)
std::map< unsigned int, std::set<::types::subdomain_id > > compute_vertices_with_ghost_neighbors(const Triangulation< dim, spacedim > &tria)
std::vector< std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > > vertex_to_cell_map(const Triangulation< dim, spacedim > &triangulation)
std::vector< std::vector< Tensor< 1, spacedim > > > vertex_to_cell_centers_directions(const Triangulation< dim, spacedim > &mesh, const std::vector< std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > > &vertex_to_cells)
std::map< unsigned int, Point< spacedim > > extract_used_vertices(const Triangulation< dim, spacedim > &container, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< spacedim >()))
std::vector< BoundingBox< boost::geometry::dimension< typename Rtree::indexable_type >::value > > extract_rtree_level(const Rtree &tree, const unsigned int level)
boost::geometry::index::rtree< LeafType, IndexType, IndexableGetter > RTree
Definition rtree.h:158
RTree< typename LeafTypeIterator::value_type, IndexType, IndexableGetter > pack_rtree(const LeafTypeIterator &begin, const LeafTypeIterator &end)