15#ifndef dealii_mpi_mpi_remote_point_evaluation_h
16#define dealii_mpi_mpi_remote_point_evaluation_h
25#include <boost/signals2/connection.hpp>
33 template <
int dim,
int spacedim>
38 template <
int dim,
int spacedim>
57 template <
int dim,
int spacedim = dim>
132 "Use the constructor with AdditionalData struct.")
134 const
double tolerance,
135 const
bool enforce_unique_mapping = false,
136 const
unsigned int rtree_level = 0,
137 const
std::function<
std::vector<
bool>()> &marked_vertices = {});
185 DistributedComputePointLocationsInternal<dim, spacedim> &
data,
246 template <
typename T>
254 std::vector<std::pair<int, int>>
cells;
302 template <
typename T,
unsigned int n_components = 1>
305 std::vector<T> &output,
306 std::vector<T> &buffer,
308 &evaluation_function,
309 const bool sort_data =
true)
const;
315 template <
typename T,
unsigned int n_components = 1>
319 &evaluation_function,
320 const bool sort_data =
true)
const;
336 template <
typename T,
unsigned int n_components = 1>
339 const std::vector<T> &input,
340 std::vector<T> &buffer,
342 &evaluation_function,
343 const bool sort_data =
true)
const;
349 template <
typename T,
unsigned int n_components = 1>
352 const std::vector<T> &input,
354 &evaluation_function,
355 const bool sort_data =
true)
const;
361 const std::vector<unsigned int> &
410 const std::vector<unsigned int> &
419 const std::vector<unsigned int> &
540#ifdef DEAL_II_WITH_MPI
544 template <
typename T>
545 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
false,
void>
547 const unsigned int rank,
548 const unsigned int tag,
550 std::vector<std::vector<char>> &buffers,
551 std::vector<MPI_Request> &requests)
553 requests.emplace_back(MPI_Request());
556 std::vector<T>(
data.data(),
data.data() +
data.size()),
false));
558 const int ierr = MPI_Isend(buffers.back().data(),
559 buffers.back().size(),
574 template <
typename T>
575 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
577 const unsigned int rank,
578 const unsigned int tag,
580 std::vector<std::vector<char>> & ,
581 std::vector<MPI_Request> &requests)
583 requests.emplace_back(MPI_Request());
585 const int ierr = MPI_Isend(
data.data(),
587 Utilities::MPI::mpi_type_id_for_type<T>,
601 template <
int rank_,
int dim,
typename T>
602 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
604 const unsigned int rank,
605 const unsigned int tag,
607 std::vector<std::vector<char>> &buffers,
608 std::vector<MPI_Request> &requests)
620 template <
typename T>
621 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
false,
void>
624 const MPI_Status &status,
625 std::vector<char> &buffer)
628 int ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
631 buffer.resize(message_length);
633 ierr = MPI_Recv(buffer.data(),
643 const auto temp = Utilities::unpack<std::vector<T>>(buffer,
false);
645 for (
unsigned int i = 0; i <
data.size(); ++i)
655 template <
typename T>
656 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
659 const MPI_Status &status,
660 std::vector<char> & )
662 const auto ierr = MPI_Recv(
data.data(),
664 Utilities::MPI::mpi_type_id_for_type<T>,
678 template <
int rank_,
int dim,
typename T>
679 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
682 const MPI_Status &status,
683 std::vector<char> &buffer)
695 template <
int dim,
int spacedim>
696 template <
typename T>
699 const unsigned int cell,
709 template <
int dim,
int spacedim>
710 template <
typename T,
unsigned int n_components>
713 std::vector<T> &output,
714 std::vector<T> &buffer,
716 &evaluation_function,
717 const bool sort_data)
const
719#ifndef DEAL_II_WITH_MPI
723 (void)evaluation_function;
733 output.resize(
point_ptrs.back() * n_components);
751 std::vector<MPI_Request> send_requests;
752 std::vector<std::vector<char>> send_buffers_packed;
753 std::vector<char> recv_buffer_packed;
756 evaluation_function(buffer_eval, *
cell_data);
761 const auto my_rank_local_recv_ptr =
764 if (my_rank_local_recv_ptr !=
recv_ranks.end())
766 const unsigned int my_rank_local_recv =
767 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
768 const unsigned int my_rank_local_send = std::distance(
771 const unsigned int start =
send_ptrs[my_rank_local_send];
772 const unsigned int end =
send_ptrs[my_rank_local_send + 1];
773 const unsigned int *recv_ptr =
779 if (start <= send_index && send_index < end)
781 for (
unsigned int c = 0; c < n_components; ++c)
782 output[recv_ptr[send_index - start] * n_components + c] =
783 buffer_eval[i * n_components + c];
786 for (
unsigned int c = 0; c < n_components; ++c)
787 buffer_send[send_index * n_components + c] =
788 buffer_eval[i * n_components + c];
794 for (
unsigned int c = 0; c < n_components; ++c)
796 buffer_eval[i * n_components + c];
801 send_buffers_packed.reserve(
send_ranks.size());
804 for (
unsigned int i = 0; i <
send_ranks.size(); ++i)
823 const auto my_rank_local_recv_ptr =
826 if (my_rank_local_recv_ptr !=
recv_ranks.end())
828 const unsigned int my_rank_local_recv =
829 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
830 const unsigned int my_rank_local_send = std::distance(
834 for (
unsigned int j =
recv_ptrs[my_rank_local_recv],
838 for (
unsigned int c = 0; c < n_components; ++c)
839 output[j * n_components + c] =
840 buffer_eval[k * n_components + c];
845 for (
unsigned int i = 0; i <
recv_ranks.size(); ++i)
852 int ierr = MPI_Probe(MPI_ANY_SOURCE,
863 const unsigned int j = std::distance(
recv_ranks.begin(), ptr);
869 (output.data() +
recv_ptrs[j] * n_components),
882 for (
unsigned int c = 0; c < n_components; ++c)
884 recv_buffer[k * n_components + c];
889 if (!send_requests.
empty())
891 const int ierr = MPI_Waitall(send_requests.
size(),
892 send_requests.
data(),
893 MPI_STATUSES_IGNORE);
900 template <
int dim,
int spacedim>
901 template <
typename T,
unsigned int n_components>
905 &evaluation_function,
906 const bool sort_data)
const
908 std::vector<T> output;
909 std::vector<T> buffer;
911 this->evaluate_and_process<T, n_components>(output,
921 template <
int dim,
int spacedim>
922 template <
typename T,
unsigned int n_components>
925 const std::vector<T> &input,
926 std::vector<T> &buffer,
928 &evaluation_function,
929 const bool sort_data)
const
931#ifndef DEAL_II_WITH_MPI
935 (void)evaluation_function;
948 sort_data ? ((
point_ptrs.size() - 1) * n_components) :
962 const_cast<T *
>(input.data()),
966 std::vector<MPI_Request> send_requests;
967 std::vector<std::vector<char>> send_buffers_packed;
968 std::vector<char> recv_buffer_packed;
974 const auto my_rank_local_recv_ptr =
977 if (my_rank_local_recv_ptr !=
recv_ranks.end())
981 const unsigned int my_rank_local_recv =
982 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
983 const unsigned int my_rank_local_send = std::distance(
987 const unsigned int start =
recv_ptrs[my_rank_local_recv];
988 const unsigned int end =
recv_ptrs[my_rank_local_recv + 1];
989 const unsigned int *send_ptr =
991 for (
unsigned int i = 0, k = 0; i <
point_ptrs.size() - 1; ++i)
994 for (
unsigned int j =
point_ptrs[i]; j < next; ++j, ++k)
999 if (start <= recv_index && recv_index < end)
1000 for (
unsigned int c = 0; c < n_components; ++c)
1001 buffer_eval[send_ptr[recv_index - start] *
1003 c] = input[i * n_components + c];
1005 for (
unsigned int c = 0; c < n_components; ++c)
1006 buffer_send[recv_index * n_components + c] =
1007 input[i * n_components + c];
1013 for (
unsigned int i = 0, k = 0; i <
point_ptrs.size() - 1; ++i)
1016 for (
unsigned int c = 0; c < n_components; ++c)
1018 input[i * n_components + c];
1023 send_buffers_packed.reserve(
recv_ranks.size());
1026 for (
unsigned int i = 0; i <
recv_ranks.size(); ++i)
1038 send_buffers_packed,
1045 const auto my_rank_local_recv_ptr =
1048 if (my_rank_local_recv_ptr !=
recv_ranks.end())
1050 const unsigned int my_rank_local_recv =
1051 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
1052 const unsigned int my_rank_local_send = std::distance(
1056 for (
unsigned int j =
recv_ptrs[my_rank_local_recv],
1060 for (
unsigned int c = 0; c < n_components; ++c)
1061 buffer_eval[k * n_components + c] =
1062 input[j * n_components + c];
1066 for (
unsigned int i = 0; i <
send_ranks.size(); ++i)
1073 int ierr = MPI_Probe(MPI_ANY_SOURCE,
1085 const unsigned int j = std::distance(
send_ranks.begin(), ptr);
1091 (buffer.data() +
send_ptrs[j] * n_components),
1097 recv_buffer_packed);
1103 for (
unsigned int c = 0; c < n_components; ++c)
1105 recv_buffer[k * n_components + c];
1109 if (!send_requests.
empty())
1111 const int ierr = MPI_Waitall(send_requests.
size(),
1112 send_requests.
data(),
1113 MPI_STATUSES_IGNORE);
1118 evaluation_function(buffer_eval, *
cell_data);
1124 template <
int dim,
int spacedim>
1125 template <
typename T,
unsigned int n_components>
1128 const std::vector<T> &input,
1130 &evaluation_function,
1131 const bool sort_data)
const
1133 std::vector<T> buffer;
1134 this->process_and_evaluate<T, n_components>(input,
1136 evaluation_function,
value_type * data() const noexcept
Abstract base class for mapping classes.
virtual MPI_Comm get_mpi_communicator() const
ArrayView< T > get_data_view(const unsigned int cell, const ArrayView< T > &values) const
std::vector< std::pair< int, int > > cells
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
const Triangulation< dim, spacedim > & triangulation
std::vector< unsigned int > reference_point_ptrs
std::vector< Point< dim > > reference_point_values
const std::vector< unsigned int > & get_send_permutation() const
std::vector< unsigned int > send_ptrs
std::unique_ptr< CellData > cell_data
bool all_points_found() const
unsigned int buffer_size_without_sorting
ObserverPointer< const Mapping< dim, spacedim > > 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
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 bool sort_data=true) const
ObserverPointer< const Triangulation< dim, spacedim > > tria
const std::vector< unsigned int > & get_point_ptrs() const
std::vector< T > evaluate_and_process(const std::function< void(const ArrayView< T > &, const CellData &)> &evaluation_function, const bool sort_data=true) const
const std::vector< unsigned int > & get_inverse_recv_permutation() const
std::vector< unsigned int > send_permutation_inv
const AdditionalData additional_data
bool is_map_unique() const
std::vector< unsigned int > recv_ranks
std::vector< unsigned int > recv_permutation_inv
std::vector< unsigned int > recv_ptrs
void evaluate_and_process(std::vector< T > &output, std::vector< T > &buffer, const std::function< void(const ArrayView< T > &, const CellData &)> &evaluation_function, const bool sort_data=true) const
const Mapping< dim, spacedim > & get_mapping() const
const CellData & get_cell_data() const
std::vector< unsigned int > send_ranks
void process_and_evaluate(const std::vector< T > &input, const std::function< void(const ArrayView< const T > &, const CellData &)> &evaluation_function, const bool sort_data=true) const
bool all_points_found_flag
unsigned int buffer_size_with_sorting
void reinit(const std::vector< Point< spacedim > > &points, const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping)
bool point_found(const unsigned int i) const
std::vector< unsigned int > send_permutation
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DEPRECATED_WITH_COMMENT(comment)
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcNeedsMPI()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
const unsigned int my_rank
std::vector< index_type > data
std::enable_if_t< Utilities::MPI::is_mpi_type< T >==false, void > recv_and_unpack(const ArrayView< T > &data, const MPI_Comm comm, const MPI_Status &status, std::vector< char > &buffer)
std::enable_if_t< Utilities::MPI::is_mpi_type< T >==false, void > pack_and_isend(const ArrayView< const T > &data, const unsigned int rank, const unsigned int tag, const MPI_Comm comm, std::vector< std::vector< char > > &buffers, std::vector< MPI_Request > &requests)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
std::size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
constexpr T pow(const T base, const int iexp)
boost::integer_range< IncrementableType > iota_view
std::function< std::vector< bool >()> marked_vertices
bool enforce_unique_mapping