13#ifndef dealii_mpi_mpi_remote_point_evaluation_h
14#define dealii_mpi_mpi_remote_point_evaluation_h
23#include <boost/signals2/connection.hpp>
31 template <
int dim,
int spacedim>
36 template <
int dim,
int spacedim>
80 template <
int dim,
int spacedim = dim>
155 "Use the constructor with AdditionalData struct.")
157 const
double tolerance,
158 const
bool enforce_unique_mapping = false,
159 const
unsigned int rtree_level = 0,
160 const
std::function<
std::vector<
bool>()> &marked_vertices = {});
208 DistributedComputePointLocationsInternal<dim, spacedim> &
data,
276 template <
typename DataType>
280 const unsigned int n_components = 1)
const;
285 std::vector<std::pair<int, int>>
cells;
339 template <
typename DataType,
unsigned int n_components = 1>
342 std::vector<DataType> &output,
343 std::vector<DataType> &buffer,
345 &evaluation_function,
346 const bool sort_data =
true)
const;
352 template <
typename DataType,
unsigned int n_components = 1>
353 std::vector<DataType>
356 &evaluation_function,
357 const bool sort_data =
true)
const;
376 template <
typename DataType,
unsigned int n_components = 1>
379 const std::vector<DataType> &input,
380 std::vector<DataType> &buffer,
382 const CellData &)> &evaluation_function,
383 const bool sort_data =
true)
const;
389 template <
typename DataType,
unsigned int n_components = 1>
392 const std::vector<DataType> &input,
394 const CellData &)> &evaluation_function,
395 const bool sort_data =
true)
const;
401 const std::vector<unsigned int> &
450 const std::vector<unsigned int> &
459 const std::vector<unsigned int> &
580#ifdef DEAL_II_WITH_MPI
584 template <
typename T>
585 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
false,
void>
587 const unsigned int rank,
588 const unsigned int tag,
590 std::vector<std::vector<char>> &buffers,
591 std::vector<MPI_Request> &requests)
593 requests.emplace_back(MPI_Request());
596 std::vector<T>(
data.data(),
data.data() +
data.size()),
false));
598 const int ierr = MPI_Isend(buffers.back().data(),
599 buffers.back().size(),
614 template <
typename T>
615 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
617 const unsigned int rank,
618 const unsigned int tag,
620 std::vector<std::vector<char>> & ,
621 std::vector<MPI_Request> &requests)
623 requests.emplace_back(MPI_Request());
625 const int ierr = MPI_Isend(
data.data(),
627 Utilities::MPI::mpi_type_id_for_type<T>,
641 template <
int rank_,
int dim,
typename T>
642 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
644 const unsigned int rank,
645 const unsigned int tag,
647 std::vector<std::vector<char>> &buffers,
648 std::vector<MPI_Request> &requests)
660 template <
typename T>
661 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
false,
void>
664 const MPI_Status &status,
665 std::vector<char> &buffer)
668 int ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
671 buffer.resize(message_length);
673 ierr = MPI_Recv(buffer.data(),
683 const auto temp = Utilities::unpack<std::vector<T>>(buffer,
false);
685 for (
unsigned int i = 0; i <
data.size(); ++i)
695 template <
typename T>
696 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
699 const MPI_Status &status,
700 std::vector<char> & )
702 const auto ierr = MPI_Recv(
data.data(),
704 Utilities::MPI::mpi_type_id_for_type<T>,
718 template <
int rank_,
int dim,
typename T>
719 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
722 const MPI_Status &status,
723 std::vector<char> &buffer)
735 template <
int dim,
int spacedim>
736 template <
typename DataType>
739 const unsigned int cell,
741 const unsigned int n_components)
const
745 ExcMessage(
"The number of components needs to be positive!"));
750 "The size of values is incorrect. One value per component needs to be provided!"));
759 template <
int dim,
int spacedim>
760 template <
typename DataType,
unsigned int n_components>
763 std::vector<DataType> &output,
764 std::vector<DataType> &buffer,
766 &evaluation_function,
767 const bool sort_data)
const
769#ifndef DEAL_II_WITH_MPI
773 (void)evaluation_function;
783 output.resize(
point_ptrs.back() * n_components);
800 std::vector<MPI_Request> send_requests;
801 std::vector<std::vector<char>> send_buffers_packed;
802 std::vector<char> recv_buffer_packed;
805 evaluation_function(buffer_eval, *
cell_data);
810 const auto my_rank_local_recv_ptr =
813 if (my_rank_local_recv_ptr !=
recv_ranks.end())
815 const unsigned int my_rank_local_recv =
816 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
817 const unsigned int my_rank_local_send = std::distance(
820 const unsigned int start =
send_ptrs[my_rank_local_send];
821 const unsigned int end =
send_ptrs[my_rank_local_send + 1];
822 const unsigned int *recv_ptr =
828 if (start <= send_index && send_index <
end)
830 for (
unsigned int c = 0; c < n_components; ++c)
831 output[recv_ptr[send_index - start] * n_components + c] =
832 buffer_eval[i * n_components + c];
835 for (
unsigned int c = 0; c < n_components; ++c)
836 buffer_send[send_index * n_components + c] =
837 buffer_eval[i * n_components + c];
843 for (
unsigned int c = 0; c < n_components; ++c)
845 buffer_eval[i * n_components + c];
850 send_buffers_packed.reserve(
send_ranks.size());
853 for (
unsigned int i = 0; i <
send_ranks.size(); ++i)
872 const auto my_rank_local_recv_ptr =
875 if (my_rank_local_recv_ptr !=
recv_ranks.end())
877 const unsigned int my_rank_local_recv =
878 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
879 const unsigned int my_rank_local_send = std::distance(
883 for (
unsigned int j =
recv_ptrs[my_rank_local_recv],
887 for (
unsigned int c = 0; c < n_components; ++c)
888 output[j * n_components + c] =
889 buffer_eval[k * n_components + c];
894 for (
unsigned int i = 0; i <
recv_ranks.size(); ++i)
901 int ierr = MPI_Probe(MPI_ANY_SOURCE,
912 const unsigned int j = std::distance(
recv_ranks.begin(), ptr);
918 (output.data() +
recv_ptrs[j] * n_components),
931 for (
unsigned int c = 0; c < n_components; ++c)
933 recv_buffer[k * n_components + c];
938 if (!send_requests.
empty())
940 const int ierr = MPI_Waitall(send_requests.
size(),
941 send_requests.
data(),
942 MPI_STATUSES_IGNORE);
949 template <
int dim,
int spacedim>
950 template <
typename DataType,
unsigned int n_components>
951 std::vector<DataType>
954 &evaluation_function,
955 const bool sort_data)
const
957 std::vector<DataType> output;
958 std::vector<DataType> buffer;
960 this->evaluate_and_process<DataType, n_components>(output,
970 template <
int dim,
int spacedim>
971 template <
typename DataType,
unsigned int n_components>
974 const std::vector<DataType> &input,
975 std::vector<DataType> &buffer,
977 const CellData &)> &evaluation_function,
978 const bool sort_data)
const
980#ifndef DEAL_II_WITH_MPI
984 (void)evaluation_function;
997 sort_data ? ((
point_ptrs.size() - 1) * n_components) :
1010 const_cast<DataType *
>(input.data()),
1014 std::vector<MPI_Request> send_requests;
1015 std::vector<std::vector<char>> send_buffers_packed;
1016 std::vector<char> recv_buffer_packed;
1022 const auto my_rank_local_recv_ptr =
1025 if (my_rank_local_recv_ptr !=
recv_ranks.end())
1029 const unsigned int my_rank_local_recv =
1030 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
1031 const unsigned int my_rank_local_send = std::distance(
1035 const unsigned int start =
recv_ptrs[my_rank_local_recv];
1036 const unsigned int end =
recv_ptrs[my_rank_local_recv + 1];
1037 const unsigned int *send_ptr =
1039 for (
unsigned int i = 0, k = 0; i <
point_ptrs.size() - 1; ++i)
1042 for (
unsigned int j =
point_ptrs[i]; j < next; ++j, ++k)
1047 if (start <= recv_index && recv_index <
end)
1048 for (
unsigned int c = 0; c < n_components; ++c)
1049 buffer_eval[send_ptr[recv_index - start] *
1051 c] = input[i * n_components + c];
1053 for (
unsigned int c = 0; c < n_components; ++c)
1054 buffer_send[recv_index * n_components + c] =
1055 input[i * n_components + c];
1061 for (
unsigned int i = 0, k = 0; i <
point_ptrs.size() - 1; ++i)
1064 for (
unsigned int c = 0; c < n_components; ++c)
1066 input[i * n_components + c];
1071 send_buffers_packed.reserve(
recv_ranks.size());
1074 for (
unsigned int i = 0; i <
recv_ranks.size(); ++i)
1086 send_buffers_packed,
1093 const auto my_rank_local_recv_ptr =
1096 if (my_rank_local_recv_ptr !=
recv_ranks.end())
1098 const unsigned int my_rank_local_recv =
1099 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
1100 const unsigned int my_rank_local_send = std::distance(
1104 for (
unsigned int j =
recv_ptrs[my_rank_local_recv],
1108 for (
unsigned int c = 0; c < n_components; ++c)
1109 buffer_eval[k * n_components + c] =
1110 input[j * n_components + c];
1114 for (
unsigned int i = 0; i <
send_ranks.size(); ++i)
1121 int ierr = MPI_Probe(MPI_ANY_SOURCE,
1133 const unsigned int j = std::distance(
send_ranks.begin(), ptr);
1139 (buffer.data() +
send_ptrs[j] * n_components),
1145 recv_buffer_packed);
1151 for (
unsigned int c = 0; c < n_components; ++c)
1153 recv_buffer[k * n_components + c];
1157 if (!send_requests.
empty())
1159 const int ierr = MPI_Waitall(send_requests.
size(),
1160 send_requests.
data(),
1161 MPI_STATUSES_IGNORE);
1166 evaluation_function(buffer_eval, *
cell_data);
1172 template <
int dim,
int spacedim>
1173 template <
typename DataType,
unsigned int n_components>
1176 const std::vector<DataType> &input,
1178 const CellData &)> &evaluation_function,
1179 const bool sort_data)
const
1181 std::vector<DataType> buffer;
1182 this->process_and_evaluate<DataType, n_components>(input,
1184 evaluation_function,
value_type * data() const noexcept
Abstract base class for mapping classes.
virtual MPI_Comm get_mpi_communicator() const
ArrayView< DataType > get_data_view(const unsigned int cell, const ArrayView< DataType > &values, const unsigned int n_components=1) 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
Communicate values between a mesh and arbitrary points.
void evaluate_and_process(std::vector< DataType > &output, std::vector< DataType > &buffer, const std::function< void(const ArrayView< DataType > &, const CellData &)> &evaluation_function, const bool sort_data=true) const
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
std::vector< DataType > evaluate_and_process(const std::function< void(const ArrayView< DataType > &, const CellData &)> &evaluation_function, const bool sort_data=true) const
void process_and_evaluate(const std::vector< DataType > &input, std::vector< DataType > &buffer, const std::function< void(const ArrayView< const DataType > &, const CellData &)> &evaluation_function, const bool sort_data=true) 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
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
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
const Mapping< dim, spacedim > & get_mapping() const
const CellData & get_cell_data() const
std::vector< unsigned int > send_ranks
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
void process_and_evaluate(const std::vector< DataType > &input, const std::function< void(const ArrayView< const DataType > &, const CellData &)> &evaluation_function, const bool sort_data=true) 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)
static ::ExceptionBase & ExcMessage(std::string arg1)
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