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.h
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 - 2026 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#ifndef dealii_mpi_mpi_remote_point_evaluation_h
14#define dealii_mpi_mpi_remote_point_evaluation_h
15
16#include <deal.II/base/config.h>
17
18#include <deal.II/base/mpi.h>
20
22
23#include <boost/signals2/connection.hpp>
24
25
27
28// Forward declarations
29namespace GridTools
30{
31 template <int dim, int spacedim>
32 class Cache;
33
34 namespace internal
35 {
36 template <int dim, int spacedim>
38 }
39} // namespace GridTools
40
41namespace Utilities
42{
43 namespace MPI
44 {
80 template <int dim, int spacedim = dim>
82 {
83 public:
89 {
90 public:
95 const double tolerance = 1e-6,
96 const bool enforce_unique_mapping = false,
97 const unsigned int rtree_level = 0,
98 const std::function<std::vector<bool>()> &marked_vertices = {});
99
108 double tolerance;
109
115
119 unsigned int rtree_level;
120
125 std::function<std::vector<bool>()> marked_vertices;
126 };
127
135
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 = {});
161
166
178 void
179 reinit(const std::vector<Point<spacedim>> &points,
182
193 void
195 const std::vector<Point<spacedim>> &points);
196
206 void
208 DistributedComputePointLocationsInternal<dim, spacedim> &data,
209 const Triangulation<dim, spacedim> &tria,
210 const Mapping<dim, spacedim> &mapping);
211
217 {
218 public:
225
252 cell_indices() const;
253
258 get_active_cell_iterator(const unsigned int cell) const;
259
264 get_unit_points(const unsigned int cell) const;
265
276 template <typename DataType>
278 get_data_view(const unsigned int cell,
279 const ArrayView<DataType> &values,
280 const unsigned int n_components = 1) const;
281
285 std::vector<std::pair<int, int>> cells;
286
291 std::vector<unsigned int> reference_point_ptrs;
292
296 std::vector<Point<dim>> reference_point_values;
297
298 private:
304 };
305
310 const CellData &
311 get_cell_data() const;
312
339 template <typename DataType, unsigned int n_components = 1>
340 void
342 std::vector<DataType> &output,
343 std::vector<DataType> &buffer,
344 const std::function<void(const ArrayView<DataType> &, const CellData &)>
345 &evaluation_function,
346 const bool sort_data = true) const;
347
352 template <typename DataType, unsigned int n_components = 1>
353 std::vector<DataType>
355 const std::function<void(const ArrayView<DataType> &, const CellData &)>
356 &evaluation_function,
357 const bool sort_data = true) const;
358
376 template <typename DataType, unsigned int n_components = 1>
377 void
379 const std::vector<DataType> &input,
380 std::vector<DataType> &buffer,
381 const std::function<void(const ArrayView<const DataType> &,
382 const CellData &)> &evaluation_function,
383 const bool sort_data = true) const;
384
389 template <typename DataType, unsigned int n_components = 1>
390 void
392 const std::vector<DataType> &input,
393 const std::function<void(const ArrayView<const DataType> &,
394 const CellData &)> &evaluation_function,
395 const bool sort_data = true) const;
396
401 const std::vector<unsigned int> &
402 get_point_ptrs() const;
403
410 bool
411 is_map_unique() const;
412
416 bool
417 all_points_found() const;
418
422 bool
423 point_found(const unsigned int i) const;
424
429 get_triangulation() const;
430
435 get_mapping() const;
436
442 bool
443 is_ready() const;
444
450 const std::vector<unsigned int> &
451 get_send_permutation() const;
452
459 const std::vector<unsigned int> &
461
462
463 private:
468
472 boost::signals2::connection tria_signal;
473
480
485
490
495
500
506 std::vector<unsigned int> point_ptrs;
507
511 std::vector<unsigned int> recv_permutation;
512
516 std::vector<unsigned int> recv_permutation_inv;
517
522 std::vector<unsigned int> recv_ptrs;
523
527 std::vector<unsigned int> recv_ranks;
528
533 std::unique_ptr<CellData> cell_data;
534
538 std::vector<unsigned int> send_permutation;
539
543 std::vector<unsigned int> send_permutation_inv;
544
548 std::vector<unsigned int> send_ranks;
549
554 std::vector<unsigned int> send_ptrs;
555
570
576 };
577
578 namespace internal
579 {
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,
589 const MPI_Comm comm,
590 std::vector<std::vector<char>> &buffers,
591 std::vector<MPI_Request> &requests)
592 {
593 requests.emplace_back(MPI_Request());
594
595 buffers.emplace_back(Utilities::pack(
596 std::vector<T>(data.data(), data.data() + data.size()), false));
597
598 const int ierr = MPI_Isend(buffers.back().data(),
599 buffers.back().size(),
600 MPI_CHAR,
601 rank,
602 tag,
603 comm,
604 &requests.back());
605 AssertThrowMPI(ierr);
606 }
607
608
609
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,
619 const MPI_Comm comm,
620 std::vector<std::vector<char>> & /*buffers*/,
621 std::vector<MPI_Request> &requests)
622 {
623 requests.emplace_back(MPI_Request());
624
625 const int ierr = MPI_Isend(data.data(),
626 data.size(),
627 Utilities::MPI::mpi_type_id_for_type<T>,
628 rank,
629 tag,
630 comm,
631 &requests.back());
632 AssertThrowMPI(ierr);
633 }
634
635
636
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,
646 const MPI_Comm comm,
647 std::vector<std::vector<char>> &buffers,
648 std::vector<MPI_Request> &requests)
649 {
650 ArrayView<const T> data_(reinterpret_cast<const T *>(data.data()),
651 data.size() * Utilities::pow(dim, rank_));
652
653 pack_and_isend(data_, rank, tag, comm, buffers, requests);
654 }
655
656
660 template <typename T>
661 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == false, void>
663 const MPI_Comm comm,
664 const MPI_Status &status,
665 std::vector<char> &buffer)
666 {
667 int message_length;
668 int ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
669 AssertThrowMPI(ierr);
670
671 buffer.resize(message_length);
672
673 ierr = MPI_Recv(buffer.data(),
674 buffer.size(),
675 MPI_CHAR,
676 status.MPI_SOURCE,
678 comm,
679 MPI_STATUS_IGNORE);
680 AssertThrowMPI(ierr);
681
682 // unpack data
683 const auto temp = Utilities::unpack<std::vector<T>>(buffer, false);
684
685 for (unsigned int i = 0; i < data.size(); ++i)
686 data[i] = temp[i];
687 }
688
689
690
695 template <typename T>
696 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == true, void>
698 const MPI_Comm comm,
699 const MPI_Status &status,
700 std::vector<char> & /*buffer*/)
701 {
702 const auto ierr = MPI_Recv(data.data(),
703 data.size(),
704 Utilities::MPI::mpi_type_id_for_type<T>,
705 status.MPI_SOURCE,
707 comm,
708 MPI_STATUS_IGNORE);
709 AssertThrowMPI(ierr);
710 }
711
712
713
718 template <int rank_, int dim, typename T>
719 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == true, void>
721 const MPI_Comm comm,
722 const MPI_Status &status,
723 std::vector<char> &buffer)
724 {
725 const ArrayView<T> data_(reinterpret_cast<T *>(data.data()),
726 data.size() * Utilities::pow(dim, rank_));
727
728 recv_and_unpack(data_, comm, status, buffer);
729 }
730#endif
731 } // namespace internal
732
733
734
735 template <int dim, int spacedim>
736 template <typename DataType>
739 const unsigned int cell,
740 const ArrayView<DataType> &values,
741 const unsigned int n_components) const
742 {
743 AssertIndexRange(cell, cells.size());
744 Assert(n_components > 0,
745 ExcMessage("The number of components needs to be positive!"));
746
747 Assert(
748 values.size() == n_components * reference_point_ptrs[cells.size()],
750 "The size of values is incorrect. One value per component needs to be provided!"));
751
752 return {values.data() + n_components * reference_point_ptrs[cell],
753 n_components *
754 (reference_point_ptrs[cell + 1] - reference_point_ptrs[cell])};
755 }
756
757
758
759 template <int dim, int spacedim>
760 template <typename DataType, unsigned int n_components>
761 void
763 std::vector<DataType> &output,
764 std::vector<DataType> &buffer,
765 const std::function<void(const ArrayView<DataType> &, const CellData &)>
766 &evaluation_function,
767 const bool sort_data) const
768 {
769#ifndef DEAL_II_WITH_MPI
770 Assert(false, ExcNeedsMPI());
771 (void)output;
772 (void)buffer;
773 (void)evaluation_function;
774 (void)sort_data;
775#else
776 static CollectiveMutex mutex;
778
779 const unsigned int my_rank =
781
782 // allocate memory for output and buffer
783 output.resize(point_ptrs.back() * n_components);
784
785 buffer.resize(
787 n_components);
788
789 // ... for evaluation
790 ArrayView<DataType> buffer_eval(buffer.data(),
791 send_permutation.size() * n_components);
792
793 // ... for communication (send)
794 ArrayView<DataType> buffer_send(
795 sort_data ? (buffer.data() + send_permutation.size() * n_components) :
796 buffer.data(),
797 send_permutation.size() * n_components);
798
799 // more arrays
800 std::vector<MPI_Request> send_requests;
801 std::vector<std::vector<char>> send_buffers_packed;
802 std::vector<char> recv_buffer_packed;
803
804 // evaluate functions at points
805 evaluation_function(buffer_eval, *cell_data);
806
807 // sort for communication (optional)
808 if (sort_data)
809 {
810 const auto my_rank_local_recv_ptr =
811 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
812
813 if (my_rank_local_recv_ptr != recv_ranks.end())
814 {
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(
818 send_ranks.begin(),
819 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
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 =
823 recv_permutation.data() + recv_ptrs[my_rank_local_recv];
824 for (unsigned int i = 0; i < send_permutation.size(); ++i)
825 {
826 const unsigned int send_index = send_permutation[i];
827
828 if (start <= send_index && send_index < end)
829 // local data -> can be copied to output directly
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];
833 else
834 // data to be sent
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];
838 }
839 }
840 else
841 {
842 for (unsigned int i = 0; i < send_permutation.size(); ++i)
843 for (unsigned int c = 0; c < n_components; ++c)
844 buffer_send[send_permutation[i] * n_components + c] =
845 buffer_eval[i * n_components + c];
846 }
847 }
848
849 // send data
850 send_buffers_packed.reserve(send_ranks.size());
851 send_requests.reserve(send_ranks.size());
852
853 for (unsigned int i = 0; i < send_ranks.size(); ++i)
854 {
855 if (send_ranks[i] == my_rank)
856 continue;
857
860 buffer_send.begin() + send_ptrs[i] * n_components,
861 (send_ptrs[i + 1] - send_ptrs[i]) * n_components),
862 send_ranks[i],
865 send_buffers_packed,
866 send_requests);
867 }
868
869 // copy local data directly to output if no sorting is requested
870 if (!sort_data)
871 {
872 const auto my_rank_local_recv_ptr =
873 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
874
875 if (my_rank_local_recv_ptr != recv_ranks.end())
876 {
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(
880 send_ranks.begin(),
881 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
882
883 for (unsigned int j = recv_ptrs[my_rank_local_recv],
884 k = send_ptrs[my_rank_local_send];
885 j < recv_ptrs[my_rank_local_recv + 1];
886 ++j, ++k)
887 for (unsigned int c = 0; c < n_components; ++c)
888 output[j * n_components + c] =
889 buffer_eval[k * n_components + c];
890 }
891 }
892
893 // receive data
894 for (unsigned int i = 0; i < recv_ranks.size(); ++i)
895 {
896 if (recv_ranks[i] == my_rank)
897 continue;
898
899 // receive remote data
900 MPI_Status status;
901 int ierr = MPI_Probe(MPI_ANY_SOURCE,
904 &status);
905 AssertThrowMPI(ierr);
906
907 const auto ptr =
908 std::find(recv_ranks.begin(), recv_ranks.end(), status.MPI_SOURCE);
909
910 Assert(ptr != recv_ranks.end(), ExcNotImplemented());
911
912 const unsigned int j = std::distance(recv_ranks.begin(), ptr);
913
914 // ... for communication (recv)
915 ArrayView<DataType> recv_buffer(
916 sort_data ?
917 (buffer.data() + send_permutation.size() * 2 * n_components) :
918 (output.data() + recv_ptrs[j] * n_components),
919 (recv_ptrs[j + 1] - recv_ptrs[j]) * n_components);
920
921 internal::recv_and_unpack(recv_buffer,
923 status,
924 recv_buffer_packed);
925
926 if (sort_data)
927 {
928 // sort data into output vector (optional)
929 for (unsigned int i = recv_ptrs[j], k = 0; i < recv_ptrs[j + 1];
930 ++i, ++k)
931 for (unsigned int c = 0; c < n_components; ++c)
932 output[recv_permutation[i] * n_components + c] =
933 recv_buffer[k * n_components + c];
934 }
935 }
936
937 // make sure all messages have been sent
938 if (!send_requests.empty())
939 {
940 const int ierr = MPI_Waitall(send_requests.size(),
941 send_requests.data(),
942 MPI_STATUSES_IGNORE);
943 AssertThrowMPI(ierr);
944 }
945#endif
946 }
947
948
949 template <int dim, int spacedim>
950 template <typename DataType, unsigned int n_components>
951 std::vector<DataType>
953 const std::function<void(const ArrayView<DataType> &, const CellData &)>
954 &evaluation_function,
955 const bool sort_data) const
956 {
957 std::vector<DataType> output;
958 std::vector<DataType> buffer;
959
960 this->evaluate_and_process<DataType, n_components>(output,
961 buffer,
962 evaluation_function,
963 sort_data);
964
965 return output;
966 }
967
968
969
970 template <int dim, int spacedim>
971 template <typename DataType, unsigned int n_components>
972 void
974 const std::vector<DataType> &input,
975 std::vector<DataType> &buffer,
976 const std::function<void(const ArrayView<const DataType> &,
977 const CellData &)> &evaluation_function,
978 const bool sort_data) const
979 {
980#ifndef DEAL_II_WITH_MPI
981 Assert(false, ExcNeedsMPI());
982 (void)input;
983 (void)buffer;
984 (void)evaluation_function;
985 (void)sort_data;
986#else
987 static CollectiveMutex mutex;
989
990 const unsigned int my_rank =
992
993 // allocate memory for buffer
994 const auto &point_ptrs = this->get_point_ptrs();
995
996 AssertDimension(input.size(),
997 sort_data ? ((point_ptrs.size() - 1) * n_components) :
998 (point_ptrs.back() * n_components));
999 buffer.resize(
1001 n_components);
1002
1003 // ... for evaluation
1004 ArrayView<DataType> buffer_eval(buffer.data(),
1005 send_permutation.size() * n_components);
1006
1007 // ... for communication (send)
1008 ArrayView<DataType> buffer_send(
1009 sort_data ? (buffer.data() + send_permutation.size() * n_components) :
1010 const_cast<DataType *>(input.data()),
1011 point_ptrs.back() * n_components);
1012
1013 // more arrays
1014 std::vector<MPI_Request> send_requests;
1015 std::vector<std::vector<char>> send_buffers_packed;
1016 std::vector<char> recv_buffer_packed;
1017
1018 // sort for communication (and duplicate data if necessary)
1019
1020 if (sort_data)
1021 {
1022 const auto my_rank_local_recv_ptr =
1023 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
1024
1025 if (my_rank_local_recv_ptr != recv_ranks.end())
1026 {
1027 // optimize the case if we have our own rank among the possible
1028 // list
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(
1032 send_ranks.begin(),
1033 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
1034
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 =
1038 send_permutation_inv.data() + send_ptrs[my_rank_local_send];
1039 for (unsigned int i = 0, k = 0; i < point_ptrs.size() - 1; ++i)
1040 {
1041 const unsigned int next = point_ptrs[i + 1];
1042 for (unsigned int j = point_ptrs[i]; j < next; ++j, ++k)
1043 {
1044 const unsigned int recv_index = recv_permutation_inv[k];
1045
1046 // local data -> can be copied to final buffer directly
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] *
1050 n_components +
1051 c] = input[i * n_components + c];
1052 else // data to be sent
1053 for (unsigned int c = 0; c < n_components; ++c)
1054 buffer_send[recv_index * n_components + c] =
1055 input[i * n_components + c];
1056 }
1057 }
1058 }
1059 else
1060 {
1061 for (unsigned int i = 0, k = 0; i < point_ptrs.size() - 1; ++i)
1062 for (unsigned int j = point_ptrs[i]; j < point_ptrs[i + 1];
1063 ++j, ++k)
1064 for (unsigned int c = 0; c < n_components; ++c)
1065 buffer_send[recv_permutation_inv[k] * n_components + c] =
1066 input[i * n_components + c];
1067 }
1068 }
1069
1070 // send data
1071 send_buffers_packed.reserve(recv_ranks.size());
1072 send_requests.reserve(recv_ranks.size());
1073
1074 for (unsigned int i = 0; i < recv_ranks.size(); ++i)
1075 {
1076 if (recv_ranks[i] == my_rank)
1077 continue;
1078
1081 buffer_send.begin() + recv_ptrs[i] * n_components,
1082 (recv_ptrs[i + 1] - recv_ptrs[i]) * n_components),
1083 recv_ranks[i],
1086 send_buffers_packed,
1087 send_requests);
1088 }
1089
1090 // copy local data directly to output if no sorting is requested
1091 if (!sort_data)
1092 {
1093 const auto my_rank_local_recv_ptr =
1094 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
1095
1096 if (my_rank_local_recv_ptr != recv_ranks.end())
1097 {
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(
1101 send_ranks.begin(),
1102 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
1103
1104 for (unsigned int j = recv_ptrs[my_rank_local_recv],
1105 k = send_ptrs[my_rank_local_send];
1106 j < recv_ptrs[my_rank_local_recv + 1];
1107 ++j, ++k)
1108 for (unsigned int c = 0; c < n_components; ++c)
1109 buffer_eval[k * n_components + c] =
1110 input[j * n_components + c];
1111 }
1112 }
1113
1114 for (unsigned int i = 0; i < send_ranks.size(); ++i)
1115 {
1116 if (send_ranks[i] == my_rank)
1117 continue;
1118
1119 // receive remote data
1120 MPI_Status status;
1121 int ierr = MPI_Probe(MPI_ANY_SOURCE,
1124 &status);
1125 AssertThrowMPI(ierr);
1126
1127 // write data into buffer vector
1128 const auto ptr =
1129 std::find(send_ranks.begin(), send_ranks.end(), status.MPI_SOURCE);
1130
1131 Assert(ptr != send_ranks.end(), ExcNotImplemented());
1132
1133 const unsigned int j = std::distance(send_ranks.begin(), ptr);
1134
1135 ArrayView<DataType> recv_buffer(
1136 sort_data ?
1137 (buffer.data() +
1138 (point_ptrs.back() + send_permutation.size()) * n_components) :
1139 (buffer.data() + send_ptrs[j] * n_components),
1140 (send_ptrs[j + 1] - send_ptrs[j]) * n_components);
1141
1142 internal::recv_and_unpack(recv_buffer,
1144 status,
1145 recv_buffer_packed);
1146
1147 if (sort_data)
1148 {
1149 for (unsigned int i = send_ptrs[j], k = 0; i < send_ptrs[j + 1];
1150 ++i, ++k)
1151 for (unsigned int c = 0; c < n_components; ++c)
1152 buffer_eval[send_permutation_inv[i] * n_components + c] =
1153 recv_buffer[k * n_components + c];
1154 }
1155 }
1156
1157 if (!send_requests.empty())
1158 {
1159 const int ierr = MPI_Waitall(send_requests.size(),
1160 send_requests.data(),
1161 MPI_STATUSES_IGNORE);
1162 AssertThrowMPI(ierr);
1163 }
1164
1165 // evaluate function at points
1166 evaluation_function(buffer_eval, *cell_data);
1167#endif
1168 }
1169
1170
1171
1172 template <int dim, int spacedim>
1173 template <typename DataType, unsigned int n_components>
1174 void
1176 const std::vector<DataType> &input,
1177 const std::function<void(const ArrayView<const DataType> &,
1178 const CellData &)> &evaluation_function,
1179 const bool sort_data) const
1180 {
1181 std::vector<DataType> buffer;
1182 this->process_and_evaluate<DataType, n_components>(input,
1183 buffer,
1184 evaluation_function,
1185 sort_data);
1186 }
1187
1188 } // end of namespace MPI
1189} // end of namespace Utilities
1190
1191
1193
1194#endif
*  iterator end()
iterator begin() const
Definition array_view.h:755
bool empty() const
Definition array_view.h:746
value_type * data() const noexcept
Definition array_view.h:714
std::size_t size() const
Definition array_view.h:737
Abstract base class for mapping classes.
Definition mapping.h:318
Definition point.h:111
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_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
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< 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
ObserverPointer< const Mapping< dim, spacedim > > mapping
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)
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
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_DEPRECATED_WITH_COMMENT(comment)
Definition config.h:295
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
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
Definition mpi.cc:917
std::vector< index_type > data
Definition mpi.cc:734
const MPI_Comm comm
Definition mpi.cc:912
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)
Definition mpi.cc:118
std::size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
Definition utilities.h:1352
constexpr T pow(const T base, const int iexp)
Definition utilities.h:966
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:43
STL namespace.