16 #ifndef dealii_mpi_mpi_remote_point_evaluation_h
17 #define dealii_mpi_mpi_remote_point_evaluation_h
43 template <
int dim,
int spacedim = dim>
97 std::vector<std::pair<int, int>>
cells;
125 template <
typename T>
128 std::vector<T> &output,
129 std::vector<T> &buffer,
131 &evaluation_function)
const;
141 template <
typename T>
144 const std::vector<T> &input,
145 std::vector<T> & buffer,
147 &evaluation_function)
const;
153 const std::vector<unsigned int> &
300 template <
int dim,
int spacedim>
301 template <
typename T>
304 std::vector<T> &output,
305 std::vector<T> &buffer,
307 &evaluation_function)
const
309 #ifndef DEAL_II_WITH_MPI
313 (void)evaluation_function;
318 output.resize(point_ptrs.back());
319 buffer.resize(send_permutation.size() * 2);
320 ArrayView<T> buffer_1(buffer.data(), buffer.size() / 2);
321 ArrayView<T> buffer_2(buffer.data() + buffer.size() / 2,
325 evaluation_function(buffer_1, cell_data);
328 for (
unsigned int i = 0; i < send_permutation.size(); ++i)
329 buffer_2[send_permutation[i]] = buffer_1[i];
332 std::map<unsigned int, std::vector<char>> temp_map;
334 std::vector<MPI_Request> requests;
335 requests.reserve(send_ranks.size());
337 const unsigned int my_rank =
340 std::map<unsigned int, std::vector<T>> temp_recv_map;
342 for (
unsigned int i = 0; i < send_ranks.size(); ++i)
344 if (send_ranks[i] == my_rank)
347 temp_recv_map[my_rank] =
348 std::vector<T>(buffer_2.
begin() + send_ptrs[i],
349 buffer_2.
begin() + send_ptrs[i + 1]);
353 temp_map[send_ranks[i]] =
355 buffer_2.
begin() + send_ptrs[i + 1]),
358 auto &buffer = temp_map[send_ranks[i]];
360 requests.push_back(MPI_Request());
362 const int ierr = MPI_Isend(buffer.data(),
372 for (
const auto recv_rank : recv_ranks)
374 if (recv_rank == my_rank)
378 int ierr = MPI_Probe(MPI_ANY_SOURCE,
385 ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
388 std::vector<char> buffer(message_length);
390 ierr = MPI_Recv(buffer.data(),
399 temp_recv_map[status.MPI_SOURCE] =
400 Utilities::unpack<std::vector<T>>(buffer,
false);
405 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
409 auto it = recv_permutation.begin();
410 for (
const auto &j : temp_recv_map)
411 for (
const auto &i : j.second)
420 template <
int dim,
int spacedim>
421 template <
typename T>
424 const std::vector<T> &input,
425 std::vector<T> & buffer,
427 &evaluation_function)
const
429 #ifndef DEAL_II_WITH_MPI
433 (void)evaluation_function;
438 const auto &ptr = this->get_point_ptrs();
440 std::map<unsigned int, std::vector<T>> temp_recv_map;
442 for (
unsigned int i = 0; i < recv_ranks.size(); ++i)
443 temp_recv_map[recv_ranks[i]].resize(recv_ptrs[i + 1] - recv_ptrs[i]);
445 const unsigned int my_rank =
452 for (
auto &j : temp_recv_map)
453 i += j.second.size();
461 std::vector<T> buffer_(ptr.back());
462 for (
unsigned int i = 0, c = 0; i < ptr.size() - 1; ++i)
464 const auto n_entries = ptr[i + 1] - ptr[i];
466 for (
unsigned int j = 0; j < n_entries; ++j, ++c)
467 buffer_[c] = input[i];
471 auto it = recv_permutation.begin();
472 for (
auto &j : temp_recv_map)
473 for (
auto &i : j.second)
481 buffer.resize(send_permutation.size() * 2);
482 ArrayView<T> buffer_1(buffer.data(), buffer.size() / 2);
483 ArrayView<T> buffer_2(buffer.data() + buffer.size() / 2,
487 std::map<unsigned int, std::vector<char>> temp_map;
489 std::vector<MPI_Request> requests;
490 requests.reserve(recv_ranks.size());
492 for (
const auto recv_rank : recv_ranks)
494 if (recv_rank == my_rank)
497 temp_map[recv_rank] =
500 auto &buffer_send = temp_map[recv_rank];
502 requests.push_back(MPI_Request());
504 const int ierr = MPI_Isend(buffer_send.data(),
514 for (
unsigned int i = 0; i < send_ranks.size(); ++i)
516 if (send_ranks[i] == my_rank)
518 const auto &buffer_send = temp_recv_map[send_ranks[i]];
520 const unsigned int j = std::distance(send_ranks.begin(),
521 std::find(send_ranks.begin(),
526 send_ptrs[j + 1] - send_ptrs[j]);
528 for (
unsigned int i = send_ptrs[j], c = 0; i < send_ptrs[j + 1];
530 buffer_1[i] = buffer_send[c];
536 int ierr = MPI_Probe(MPI_ANY_SOURCE,
543 ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
546 std::vector<char> recv_buffer(message_length);
548 ierr = MPI_Recv(recv_buffer.data(),
557 const auto recv_buffer_unpacked =
558 Utilities::unpack<std::vector<T>>(recv_buffer,
false);
561 std::find(send_ranks.begin(), send_ranks.end(), status.MPI_SOURCE);
565 const unsigned int j = std::distance(send_ranks.begin(), ptr);
568 send_ptrs[j + 1] - send_ptrs[j]);
570 for (
unsigned int i = send_ptrs[j], c = 0; i < send_ptrs[j + 1];
575 buffer_1[i] = recv_buffer_unpacked[c];
580 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
584 for (
unsigned int i = 0; i < send_permutation.size(); ++i)
585 buffer_2[i] = buffer_1[send_permutation[i]];
588 evaluation_function(buffer_2, cell_data);
virtual MPI_Comm get_communicator() const
RemotePointEvaluation(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={})
const std::function< std::vector< bool >)> marked_vertices
void evaluate_and_process(std::vector< T > &output, std::vector< T > &buffer, const std::function< void(const ArrayView< T > &, const CellData &)> &evaluation_function) const
std::vector< unsigned int > send_ptrs
bool all_points_found() const
const bool enforce_unique_mapping
boost::signals2::connection tria_signal
std::vector< unsigned int > point_ptrs
std::vector< unsigned int > recv_permutation
const Triangulation< dim, spacedim > & get_triangulation() const
SmartPointer< const Mapping< dim, spacedim > > mapping
void process_and_evaluate(const std::vector< T > &input, std::vector< T > &buffer, const std::function< void(const ArrayView< const T > &, const CellData &)> &evaluation_function) const
const std::vector< unsigned int > & get_point_ptrs() const
const unsigned int rtree_level
bool is_map_unique() const
std::vector< unsigned int > recv_ranks
std::vector< unsigned int > recv_ptrs
const Mapping< dim, spacedim > & get_mapping() const
std::vector< unsigned int > send_ranks
bool all_points_found_flag
SmartPointer< const Triangulation< dim, spacedim > > tria
bool point_found(const unsigned int i) const
std::vector< unsigned int > send_permutation
void reinit(const std::vector< Point< spacedim >> &points, const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNeedsMPI()
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotImplemented()
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
std::vector< std::pair< int, int > > cells
std::vector< unsigned int > reference_point_ptrs
std::vector< Point< dim > > reference_point_values
const ::Triangulation< dim, spacedim > & tria