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>
82 template <
int dim,
int spacedim = dim>
157 "Use the constructor with AdditionalData struct.")
159 const
double tolerance,
160 const
bool enforce_unique_mapping = false,
161 const
unsigned int rtree_level = 0,
162 const
std::function<
std::vector<
bool>()> &marked_vertices = {});
210 DistributedComputePointLocationsInternal<dim, spacedim> &
data,
271 template <
typename DataType>
279 std::vector<std::pair<int, int>>
cells;
330 template <
typename DataType,
unsigned int n_components = 1>
333 std::vector<DataType> &output,
334 std::vector<DataType> &buffer,
336 &evaluation_function,
337 const bool sort_data =
true)
const;
343 template <
typename DataType,
unsigned int n_components = 1>
344 std::vector<DataType>
347 &evaluation_function,
348 const bool sort_data =
true)
const;
364 template <
typename DataType,
unsigned int n_components = 1>
367 const std::vector<DataType> &input,
368 std::vector<DataType> &buffer,
370 const CellData &)> &evaluation_function,
371 const bool sort_data =
true)
const;
377 template <
typename DataType,
unsigned int n_components = 1>
380 const std::vector<DataType> &input,
382 const CellData &)> &evaluation_function,
383 const bool sort_data =
true)
const;
389 const std::vector<unsigned int> &
438 const std::vector<unsigned int> &
447 const std::vector<unsigned int> &
568#ifdef DEAL_II_WITH_MPI
572 template <
typename T>
573 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
false,
void>
575 const unsigned int rank,
576 const unsigned int tag,
578 std::vector<std::vector<char>> &buffers,
579 std::vector<MPI_Request> &requests)
581 requests.emplace_back(MPI_Request());
584 std::vector<T>(
data.data(),
data.data() +
data.size()),
false));
586 const int ierr = MPI_Isend(buffers.back().data(),
587 buffers.back().size(),
602 template <
typename T>
603 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
605 const unsigned int rank,
606 const unsigned int tag,
608 std::vector<std::vector<char>> & ,
609 std::vector<MPI_Request> &requests)
611 requests.emplace_back(MPI_Request());
613 const int ierr = MPI_Isend(
data.data(),
615 Utilities::MPI::mpi_type_id_for_type<T>,
629 template <
int rank_,
int dim,
typename T>
630 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
632 const unsigned int rank,
633 const unsigned int tag,
635 std::vector<std::vector<char>> &buffers,
636 std::vector<MPI_Request> &requests)
648 template <
typename T>
649 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
false,
void>
652 const MPI_Status &status,
653 std::vector<char> &buffer)
656 int ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
659 buffer.resize(message_length);
661 ierr = MPI_Recv(buffer.data(),
671 const auto temp = Utilities::unpack<std::vector<T>>(buffer,
false);
673 for (
unsigned int i = 0; i <
data.size(); ++i)
683 template <
typename T>
684 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
687 const MPI_Status &status,
688 std::vector<char> & )
690 const auto ierr = MPI_Recv(
data.data(),
692 Utilities::MPI::mpi_type_id_for_type<T>,
706 template <
int rank_,
int dim,
typename T>
707 std::enable_if_t<Utilities::MPI::is_mpi_type<T> ==
true,
void>
710 const MPI_Status &status,
711 std::vector<char> &buffer)
723 template <
int dim,
int spacedim>
724 template <
typename DataType>
727 const unsigned int cell,
737 template <
int dim,
int spacedim>
738 template <
typename DataType,
unsigned int n_components>
741 std::vector<DataType> &output,
742 std::vector<DataType> &buffer,
744 &evaluation_function,
745 const bool sort_data)
const
747#ifndef DEAL_II_WITH_MPI
751 (void)evaluation_function;
761 output.resize(
point_ptrs.back() * n_components);
778 std::vector<MPI_Request> send_requests;
779 std::vector<std::vector<char>> send_buffers_packed;
780 std::vector<char> recv_buffer_packed;
783 evaluation_function(buffer_eval, *
cell_data);
788 const auto my_rank_local_recv_ptr =
791 if (my_rank_local_recv_ptr !=
recv_ranks.end())
793 const unsigned int my_rank_local_recv =
794 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
795 const unsigned int my_rank_local_send = std::distance(
798 const unsigned int start =
send_ptrs[my_rank_local_send];
799 const unsigned int end =
send_ptrs[my_rank_local_send + 1];
800 const unsigned int *recv_ptr =
806 if (start <= send_index && send_index < end)
808 for (
unsigned int c = 0; c < n_components; ++c)
809 output[recv_ptr[send_index - start] * n_components + c] =
810 buffer_eval[i * n_components + c];
813 for (
unsigned int c = 0; c < n_components; ++c)
814 buffer_send[send_index * n_components + c] =
815 buffer_eval[i * n_components + c];
821 for (
unsigned int c = 0; c < n_components; ++c)
823 buffer_eval[i * n_components + c];
828 send_buffers_packed.reserve(
send_ranks.size());
831 for (
unsigned int i = 0; i <
send_ranks.size(); ++i)
850 const auto my_rank_local_recv_ptr =
853 if (my_rank_local_recv_ptr !=
recv_ranks.end())
855 const unsigned int my_rank_local_recv =
856 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
857 const unsigned int my_rank_local_send = std::distance(
861 for (
unsigned int j =
recv_ptrs[my_rank_local_recv],
865 for (
unsigned int c = 0; c < n_components; ++c)
866 output[j * n_components + c] =
867 buffer_eval[k * n_components + c];
872 for (
unsigned int i = 0; i <
recv_ranks.size(); ++i)
879 int ierr = MPI_Probe(MPI_ANY_SOURCE,
890 const unsigned int j = std::distance(
recv_ranks.begin(), ptr);
896 (output.data() +
recv_ptrs[j] * n_components),
909 for (
unsigned int c = 0; c < n_components; ++c)
911 recv_buffer[k * n_components + c];
916 if (!send_requests.
empty())
918 const int ierr = MPI_Waitall(send_requests.
size(),
919 send_requests.
data(),
920 MPI_STATUSES_IGNORE);
927 template <
int dim,
int spacedim>
928 template <
typename DataType,
unsigned int n_components>
929 std::vector<DataType>
932 &evaluation_function,
933 const bool sort_data)
const
935 std::vector<DataType> output;
936 std::vector<DataType> buffer;
938 this->evaluate_and_process<DataType, n_components>(output,
948 template <
int dim,
int spacedim>
949 template <
typename DataType,
unsigned int n_components>
952 const std::vector<DataType> &input,
953 std::vector<DataType> &buffer,
955 const CellData &)> &evaluation_function,
956 const bool sort_data)
const
958#ifndef DEAL_II_WITH_MPI
962 (void)evaluation_function;
975 sort_data ? ((
point_ptrs.size() - 1) * n_components) :
988 const_cast<DataType *
>(input.data()),
992 std::vector<MPI_Request> send_requests;
993 std::vector<std::vector<char>> send_buffers_packed;
994 std::vector<char> recv_buffer_packed;
1000 const auto my_rank_local_recv_ptr =
1003 if (my_rank_local_recv_ptr !=
recv_ranks.end())
1007 const unsigned int my_rank_local_recv =
1008 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
1009 const unsigned int my_rank_local_send = std::distance(
1013 const unsigned int start =
recv_ptrs[my_rank_local_recv];
1014 const unsigned int end =
recv_ptrs[my_rank_local_recv + 1];
1015 const unsigned int *send_ptr =
1017 for (
unsigned int i = 0, k = 0; i <
point_ptrs.size() - 1; ++i)
1020 for (
unsigned int j =
point_ptrs[i]; j < next; ++j, ++k)
1025 if (start <= recv_index && recv_index < end)
1026 for (
unsigned int c = 0; c < n_components; ++c)
1027 buffer_eval[send_ptr[recv_index - start] *
1029 c] = input[i * n_components + c];
1031 for (
unsigned int c = 0; c < n_components; ++c)
1032 buffer_send[recv_index * n_components + c] =
1033 input[i * n_components + c];
1039 for (
unsigned int i = 0, k = 0; i <
point_ptrs.size() - 1; ++i)
1042 for (
unsigned int c = 0; c < n_components; ++c)
1044 input[i * n_components + c];
1049 send_buffers_packed.reserve(
recv_ranks.size());
1052 for (
unsigned int i = 0; i <
recv_ranks.size(); ++i)
1064 send_buffers_packed,
1071 const auto my_rank_local_recv_ptr =
1074 if (my_rank_local_recv_ptr !=
recv_ranks.end())
1076 const unsigned int my_rank_local_recv =
1077 std::distance(
recv_ranks.begin(), my_rank_local_recv_ptr);
1078 const unsigned int my_rank_local_send = std::distance(
1082 for (
unsigned int j =
recv_ptrs[my_rank_local_recv],
1086 for (
unsigned int c = 0; c < n_components; ++c)
1087 buffer_eval[k * n_components + c] =
1088 input[j * n_components + c];
1092 for (
unsigned int i = 0; i <
send_ranks.size(); ++i)
1099 int ierr = MPI_Probe(MPI_ANY_SOURCE,
1111 const unsigned int j = std::distance(
send_ranks.begin(), ptr);
1117 (buffer.data() +
send_ptrs[j] * n_components),
1123 recv_buffer_packed);
1129 for (
unsigned int c = 0; c < n_components; ++c)
1131 recv_buffer[k * n_components + c];
1135 if (!send_requests.
empty())
1137 const int ierr = MPI_Waitall(send_requests.
size(),
1138 send_requests.
data(),
1139 MPI_STATUSES_IGNORE);
1144 evaluation_function(buffer_eval, *
cell_data);
1150 template <
int dim,
int spacedim>
1151 template <
typename DataType,
unsigned int n_components>
1154 const std::vector<DataType> &input,
1156 const CellData &)> &evaluation_function,
1157 const bool sort_data)
const
1159 std::vector<DataType> buffer;
1160 this->process_and_evaluate<DataType, n_components>(input,
1162 evaluation_function,
value_type * data() const noexcept
Abstract base class for mapping classes.
virtual MPI_Comm get_mpi_communicator() 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
ArrayView< DataType > get_data_view(const unsigned int cell, const ArrayView< DataType > &values) const
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)
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