deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20: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
mpi_remote_point_evaluation.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 - 2025 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
13#include <deal.II/base/config.h>
14
18
20
21#include <deal.II/fe/mapping.h>
22
26#include <deal.II/grid/tria.h>
27
29
30
31namespace Utilities
32{
33 namespace MPI
34 {
35 template <int dim, int spacedim>
37 const double tolerance,
38 const bool enforce_unique_mapping,
39 const unsigned int rtree_level,
40 const std::function<std::vector<bool>()> &marked_vertices)
41 : tolerance(tolerance)
42 , enforce_unique_mapping(enforce_unique_mapping)
43 , rtree_level(rtree_level)
44 , marked_vertices(marked_vertices)
45 {}
46
47
48
49 template <int dim, int spacedim>
55
56
57
58 template <int dim, int spacedim>
60 const double tolerance,
61 const bool enforce_unique_mapping,
62 const unsigned int rtree_level,
63 const std::function<std::vector<bool>()> &marked_vertices)
64 : additional_data(tolerance,
65 enforce_unique_mapping,
66 rtree_level,
67 marked_vertices)
68 , ready_flag(false)
69 {}
70
71
72
73 template <int dim, int spacedim>
75 {
76 if (tria_signal.connected())
77 tria_signal.disconnect();
78 }
79
80
81
82 template <int dim, int spacedim>
83 void
85 const std::vector<Point<spacedim>> &points,
87 const Mapping<dim, spacedim> &mapping)
88 {
89 const GridTools::Cache<dim, spacedim> cache(tria, mapping);
90
91 this->reinit(cache, points);
92 }
93
95
96 template <int dim, int spacedim>
97 void
100 const std::vector<Point<spacedim>> &points)
101 {
102#ifndef DEAL_II_WITH_MPI
103 Assert(false, ExcNeedsMPI());
104 (void)cache;
105 (void)points;
106#else
107 if (tria_signal.connected())
108 tria_signal.disconnect();
109
110 tria_signal = cache.get_triangulation().signals.any_change.connect(
111 [&]() { this->ready_flag = false; });
112
113 // compress r-tree to a minimal set of bounding boxes
114 std::vector<std::vector<BoundingBox<spacedim>>> global_bboxes;
115 global_bboxes.emplace_back(
117 additional_data.rtree_level));
118
119 const auto data =
121 cache,
122 points,
123 global_bboxes,
124 additional_data.marked_vertices ? additional_data.marked_vertices() :
125 std::vector<bool>(),
126 additional_data.tolerance,
127 true,
128 additional_data.enforce_unique_mapping);
129
130 this->reinit(data, cache.get_triangulation(), cache.get_mapping());
131#endif
132 }
134
135
136 template <int dim, int spacedim>
137 void
139 const GridTools::internal::
140 DistributedComputePointLocationsInternal<dim, spacedim> &data,
141 const Triangulation<dim, spacedim> &tria,
142 const Mapping<dim, spacedim> &mapping)
143 {
144 this->tria = &tria;
145 this->mapping = &mapping;
146
147 this->recv_ranks = data.recv_ranks;
148 this->recv_ptrs = data.recv_ptrs;
149
150 this->send_ranks = data.send_ranks;
151 this->send_ptrs = data.send_ptrs;
152
153 this->recv_permutation = {};
154 this->recv_permutation.resize(data.recv_components.size());
155 this->point_ptrs.assign(data.n_searched_points + 1, 0);
156 for (unsigned int i = 0; i < data.recv_components.size(); ++i)
157 {
158 AssertIndexRange(std::get<2>(data.recv_components[i]),
159 this->recv_permutation.size());
160 this->recv_permutation[std::get<2>(data.recv_components[i])] = i;
161
162 AssertIndexRange(std::get<1>(data.recv_components[i]) + 1,
163 this->point_ptrs.size());
164 this->point_ptrs[std::get<1>(data.recv_components[i]) + 1]++;
166
167 std::pair<unsigned int, unsigned int> n_owning_processes_default{
169 std::pair<unsigned int, unsigned int> n_owning_processes_local =
170 n_owning_processes_default;
171
172 for (unsigned int i = 0; i < data.n_searched_points; ++i)
173 {
174 std::get<0>(n_owning_processes_local) =
175 std::min(std::get<0>(n_owning_processes_local),
176 this->point_ptrs[i + 1]);
177 std::get<1>(n_owning_processes_local) =
178 std::max(std::get<1>(n_owning_processes_local),
179 this->point_ptrs[i + 1]);
180
181 this->point_ptrs[i + 1] += this->point_ptrs[i];
182 }
183
184 const auto n_owning_processes_global =
185 Utilities::MPI::all_reduce<std::pair<unsigned int, unsigned int>>(
186 n_owning_processes_local,
187 tria.get_mpi_communicator(),
188 [&](const auto &a,
189 const auto &b) -> std::pair<unsigned int, unsigned int> {
190 if (a == n_owning_processes_default)
191 return b;
192
193 if (b == n_owning_processes_default)
194 return a;
195
196 return std::pair<unsigned int, unsigned int>{
197 std::min(std::get<0>(a), std::get<0>(b)),
198 std::max(std::get<1>(a), std::get<1>(b))};
199 });
200
201 if (n_owning_processes_global == n_owning_processes_default)
202 {
203 unique_mapping = true;
205 }
206 else
208 unique_mapping = (std::get<0>(n_owning_processes_global) == 1) &&
209 (std::get<1>(n_owning_processes_global) == 1);
210 all_points_found_flag = std::get<0>(n_owning_processes_global) > 0;
211 }
212
215
216 cell_data = std::make_unique<CellData>(tria);
217 send_permutation = {};
218
219 std::pair<int, int> dummy{-1, -1};
220 for (const auto &i : data.send_components)
221 {
222 if (dummy != std::get<0>(i))
223 {
224 dummy = std::get<0>(i);
225 cell_data->cells.emplace_back(dummy);
226 cell_data->reference_point_ptrs.emplace_back(
227 cell_data->reference_point_values.size());
228 }
229
230 cell_data->reference_point_values.emplace_back(std::get<3>(i));
231 send_permutation.emplace_back(std::get<5>(i));
232 }
233
234 cell_data->reference_point_ptrs.emplace_back(
235 cell_data->reference_point_values.size());
236
237 unsigned int max_size_recv = 0;
238 for (unsigned int i = 0; i < recv_ranks.size(); ++i)
239 max_size_recv =
240 std::max(max_size_recv, recv_ptrs[i + 1] - recv_ptrs[i]);
241
242 unsigned int max_size_send = 0;
243 for (unsigned int i = 0; i < send_ranks.size(); ++i)
244 max_size_send =
245 std::max(max_size_send, send_ptrs[i + 1] - send_ptrs[i]);
246
248 std::max(send_permutation.size() * 2 + max_size_recv,
249 point_ptrs.back() + send_permutation.size() + max_size_send);
250
253 // invert permutation matrices
255 for (unsigned int c = 0; c < recv_permutation.size(); ++c)
257
259 for (unsigned int c = 0; c < send_permutation.size(); ++c)
261
262 this->ready_flag = true;
263 }
265
266
267 template <int dim, int spacedim>
269 const Triangulation<dim, spacedim> &triangulation)
270 : triangulation(triangulation)
271 {}
272
273
274
275 template <int dim, int spacedim>
278 {
280 0, static_cast<unsigned int>(cells.size()));
281 }
282
283
284
285 template <int dim, int spacedim>
288 const unsigned int cell) const
289 {
290 AssertIndexRange(cell, cells.size());
291 return {&triangulation, cells[cell].first, cells[cell].second};
292 }
293
294
295
296 template <int dim, int spacedim>
299 const unsigned int cell) const
300 {
301 AssertIndexRange(cell, cells.size());
302 return {reference_point_values.data() + reference_point_ptrs[cell],
303 reference_point_ptrs[cell + 1] - reference_point_ptrs[cell]};
304 }
305
306
307
308 template <int dim, int spacedim>
314
315
316
317 template <int dim, int spacedim>
318 const std::vector<unsigned int> &
323
324
325
326 template <int dim, int spacedim>
327 bool
332
333
334
335 template <int dim, int spacedim>
336 bool
341
342
343
344 template <int dim, int spacedim>
345 bool
347 const unsigned int i) const
348 {
349 AssertIndexRange(i, point_ptrs.size() - 1);
350
352 return true;
353 else
354 return (point_ptrs[i + 1] - point_ptrs[i]) > 0;
355 }
356
357
358
359 template <int dim, int spacedim>
365
366
367
368 template <int dim, int spacedim>
374
375
376
377 template <int dim, int spacedim>
378 bool
383
384
385
386 template <int dim, int spacedim>
387 const std::vector<unsigned int> &
392
393
394
395 template <int dim, int spacedim>
396 const std::vector<unsigned int> &
401
402 } // end of namespace MPI
403} // end of namespace Utilities
404
405#include "base/mpi_remote_point_evaluation.inst"
406
const RTree< std::pair< BoundingBox< spacedim >, typename Triangulation< dim, spacedim >::active_cell_iterator > > & get_locally_owned_cell_bounding_boxes_rtree() const
const Mapping< dim, spacedim > & get_mapping() const
const Triangulation< dim, spacedim > & get_triangulation() const
Abstract base class for mapping classes.
Definition mapping.h:318
Definition point.h:111
Signals signals
Definition tria.h:2588
std_cxx20::ranges::iota_view< unsigned int, unsigned int > cell_indices() const
ArrayView< const Point< dim > > get_unit_points(const unsigned int cell) const
Triangulation< dim, spacedim >::active_cell_iterator get_active_cell_iterator(const unsigned int cell) const
CellData(const Triangulation< dim, spacedim > &triangulation)
const std::vector< unsigned int > & get_send_permutation() const
ObserverPointer< const Mapping< dim, spacedim > > mapping
RemotePointEvaluation(const AdditionalData &additional_data=AdditionalData())
const Triangulation< dim, spacedim > & get_triangulation() const
ObserverPointer< const Triangulation< dim, spacedim > > tria
const std::vector< unsigned int > & get_point_ptrs() const
const std::vector< unsigned int > & get_inverse_recv_permutation() const
const Mapping< dim, spacedim > & get_mapping() const
void reinit(const std::vector< Point< spacedim > > &points, const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcNeedsMPI()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
std::vector< index_type > data
Definition mpi.cc:734
DistributedComputePointLocationsInternal< dim, spacedim > distributed_compute_point_locations(const GridTools::Cache< dim, spacedim > &cache, const std::vector< Point< spacedim > > &points, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bboxes, const std::vector< bool > &marked_vertices, const double tolerance, const bool perform_handshake, const bool enforce_unique_mapping=false)
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:43
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
std::vector< BoundingBox< boost::geometry::dimension< typename Rtree::indexable_type >::value > > extract_rtree_level(const Rtree &tree, const unsigned int level)
AdditionalData(const double tolerance=1e-6, const bool enforce_unique_mapping=false, const unsigned int rtree_level=0, const std::function< std::vector< bool >()> &marked_vertices={})