deal.II version GIT relicensing-3713-g695aaf43dd 2025-07-09 15:30:00+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: LGPL-2.1-or-later
4// Copyright (C) 2021 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_mpi_mpi_remote_point_evaluation_h
16#define dealii_mpi_mpi_remote_point_evaluation_h
17
18#include <deal.II/base/config.h>
19
20#include <deal.II/base/mpi.h>
22
24
25#include <boost/signals2/connection.hpp>
26
27
29
30// Forward declarations
31namespace GridTools
32{
33 template <int dim, int spacedim>
34 class Cache;
35
36 namespace internal
37 {
38 template <int dim, int spacedim>
40 }
41} // namespace GridTools
42
43namespace Utilities
44{
45 namespace MPI
46 {
82 template <int dim, int spacedim = dim>
84 {
85 public:
91 {
92 public:
97 const double tolerance = 1e-6,
98 const bool enforce_unique_mapping = false,
99 const unsigned int rtree_level = 0,
100 const std::function<std::vector<bool>()> &marked_vertices = {});
101
110 double tolerance;
111
117
121 unsigned int rtree_level;
122
127 std::function<std::vector<bool>()> marked_vertices;
128 };
129
137
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 = {});
163
168
180 void
181 reinit(const std::vector<Point<spacedim>> &points,
184
195 void
197 const std::vector<Point<spacedim>> &points);
198
208 void
210 DistributedComputePointLocationsInternal<dim, spacedim> &data,
211 const Triangulation<dim, spacedim> &tria,
212 const Mapping<dim, spacedim> &mapping);
213
219 {
220 public:
227
254 cell_indices() const;
255
260 get_active_cell_iterator(const unsigned int cell) const;
261
266 get_unit_points(const unsigned int cell) const;
267
271 template <typename DataType>
273 get_data_view(const unsigned int cell,
274 const ArrayView<DataType> &values) const;
275
279 std::vector<std::pair<int, int>> cells;
280
285 std::vector<unsigned int> reference_point_ptrs;
286
290 std::vector<Point<dim>> reference_point_values;
291
292 private:
298 };
299
304 const CellData &
305 get_cell_data() const;
306
330 template <typename DataType, unsigned int n_components = 1>
331 void
333 std::vector<DataType> &output,
334 std::vector<DataType> &buffer,
335 const std::function<void(const ArrayView<DataType> &, const CellData &)>
336 &evaluation_function,
337 const bool sort_data = true) const;
338
343 template <typename DataType, unsigned int n_components = 1>
344 std::vector<DataType>
346 const std::function<void(const ArrayView<DataType> &, const CellData &)>
347 &evaluation_function,
348 const bool sort_data = true) const;
349
364 template <typename DataType, unsigned int n_components = 1>
365 void
367 const std::vector<DataType> &input,
368 std::vector<DataType> &buffer,
369 const std::function<void(const ArrayView<const DataType> &,
370 const CellData &)> &evaluation_function,
371 const bool sort_data = true) const;
372
377 template <typename DataType, unsigned int n_components = 1>
378 void
380 const std::vector<DataType> &input,
381 const std::function<void(const ArrayView<const DataType> &,
382 const CellData &)> &evaluation_function,
383 const bool sort_data = true) const;
384
389 const std::vector<unsigned int> &
390 get_point_ptrs() const;
391
398 bool
399 is_map_unique() const;
400
404 bool
405 all_points_found() const;
406
410 bool
411 point_found(const unsigned int i) const;
412
417 get_triangulation() const;
418
423 get_mapping() const;
424
430 bool
431 is_ready() const;
432
438 const std::vector<unsigned int> &
439 get_send_permutation() const;
440
447 const std::vector<unsigned int> &
449
450
451 private:
456
460 boost::signals2::connection tria_signal;
461
468
473
478
483
488
494 std::vector<unsigned int> point_ptrs;
495
499 std::vector<unsigned int> recv_permutation;
500
504 std::vector<unsigned int> recv_permutation_inv;
505
510 std::vector<unsigned int> recv_ptrs;
511
515 std::vector<unsigned int> recv_ranks;
516
521 std::unique_ptr<CellData> cell_data;
522
526 std::vector<unsigned int> send_permutation;
527
531 std::vector<unsigned int> send_permutation_inv;
532
536 std::vector<unsigned int> send_ranks;
537
542 std::vector<unsigned int> send_ptrs;
543
558
564 };
565
566 namespace internal
567 {
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,
577 const MPI_Comm comm,
578 std::vector<std::vector<char>> &buffers,
579 std::vector<MPI_Request> &requests)
580 {
581 requests.emplace_back(MPI_Request());
582
583 buffers.emplace_back(Utilities::pack(
584 std::vector<T>(data.data(), data.data() + data.size()), false));
585
586 const int ierr = MPI_Isend(buffers.back().data(),
587 buffers.back().size(),
588 MPI_CHAR,
589 rank,
590 tag,
591 comm,
592 &requests.back());
593 AssertThrowMPI(ierr);
594 }
595
596
597
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,
607 const MPI_Comm comm,
608 std::vector<std::vector<char>> & /*buffers*/,
609 std::vector<MPI_Request> &requests)
610 {
611 requests.emplace_back(MPI_Request());
612
613 const int ierr = MPI_Isend(data.data(),
614 data.size(),
615 Utilities::MPI::mpi_type_id_for_type<T>,
616 rank,
617 tag,
618 comm,
619 &requests.back());
620 AssertThrowMPI(ierr);
621 }
622
623
624
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,
634 const MPI_Comm comm,
635 std::vector<std::vector<char>> &buffers,
636 std::vector<MPI_Request> &requests)
637 {
638 ArrayView<const T> data_(reinterpret_cast<const T *>(data.data()),
639 data.size() * Utilities::pow(dim, rank_));
640
641 pack_and_isend(data_, rank, tag, comm, buffers, requests);
642 }
643
644
648 template <typename T>
649 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == false, void>
651 const MPI_Comm comm,
652 const MPI_Status &status,
653 std::vector<char> &buffer)
654 {
655 int message_length;
656 int ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
657 AssertThrowMPI(ierr);
658
659 buffer.resize(message_length);
660
661 ierr = MPI_Recv(buffer.data(),
662 buffer.size(),
663 MPI_CHAR,
664 status.MPI_SOURCE,
666 comm,
667 MPI_STATUS_IGNORE);
668 AssertThrowMPI(ierr);
669
670 // unpack data
671 const auto temp = Utilities::unpack<std::vector<T>>(buffer, false);
672
673 for (unsigned int i = 0; i < data.size(); ++i)
674 data[i] = temp[i];
675 }
676
677
678
683 template <typename T>
684 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == true, void>
686 const MPI_Comm comm,
687 const MPI_Status &status,
688 std::vector<char> & /*buffer*/)
689 {
690 const auto ierr = MPI_Recv(data.data(),
691 data.size(),
692 Utilities::MPI::mpi_type_id_for_type<T>,
693 status.MPI_SOURCE,
695 comm,
696 MPI_STATUS_IGNORE);
697 AssertThrowMPI(ierr);
698 }
699
700
701
706 template <int rank_, int dim, typename T>
707 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == true, void>
709 const MPI_Comm comm,
710 const MPI_Status &status,
711 std::vector<char> &buffer)
712 {
713 const ArrayView<T> data_(reinterpret_cast<T *>(data.data()),
714 data.size() * Utilities::pow(dim, rank_));
715
716 recv_and_unpack(data_, comm, status, buffer);
717 }
718#endif
719 } // namespace internal
720
721
722
723 template <int dim, int spacedim>
724 template <typename DataType>
727 const unsigned int cell,
728 const ArrayView<DataType> &values) const
729 {
730 AssertIndexRange(cell, cells.size());
731 return {values.data() + reference_point_ptrs[cell],
733 }
734
735
736
737 template <int dim, int spacedim>
738 template <typename DataType, unsigned int n_components>
739 void
741 std::vector<DataType> &output,
742 std::vector<DataType> &buffer,
743 const std::function<void(const ArrayView<DataType> &, const CellData &)>
744 &evaluation_function,
745 const bool sort_data) const
746 {
747#ifndef DEAL_II_WITH_MPI
748 Assert(false, ExcNeedsMPI());
749 (void)output;
750 (void)buffer;
751 (void)evaluation_function;
752 (void)sort_data;
753#else
754 static CollectiveMutex mutex;
756
757 const unsigned int my_rank =
759
760 // allocate memory for output and buffer
761 output.resize(point_ptrs.back() * n_components);
762
763 buffer.resize(
765 n_components);
766
767 // ... for evaluation
768 ArrayView<DataType> buffer_eval(buffer.data(),
769 send_permutation.size() * n_components);
770
771 // ... for communication (send)
772 ArrayView<DataType> buffer_send(
773 sort_data ? (buffer.data() + send_permutation.size() * n_components) :
774 buffer.data(),
775 send_permutation.size() * n_components);
776
777 // more arrays
778 std::vector<MPI_Request> send_requests;
779 std::vector<std::vector<char>> send_buffers_packed;
780 std::vector<char> recv_buffer_packed;
781
782 // evaluate functions at points
783 evaluation_function(buffer_eval, *cell_data);
784
785 // sort for communication (optional)
786 if (sort_data)
787 {
788 const auto my_rank_local_recv_ptr =
789 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
790
791 if (my_rank_local_recv_ptr != recv_ranks.end())
792 {
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(
796 send_ranks.begin(),
797 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
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 =
801 recv_permutation.data() + recv_ptrs[my_rank_local_recv];
802 for (unsigned int i = 0; i < send_permutation.size(); ++i)
803 {
804 const unsigned int send_index = send_permutation[i];
805
806 if (start <= send_index && send_index < end)
807 // local data -> can be copied to output directly
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];
811 else
812 // data to be sent
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];
816 }
817 }
818 else
819 {
820 for (unsigned int i = 0; i < send_permutation.size(); ++i)
821 for (unsigned int c = 0; c < n_components; ++c)
822 buffer_send[send_permutation[i] * n_components + c] =
823 buffer_eval[i * n_components + c];
824 }
825 }
826
827 // send data
828 send_buffers_packed.reserve(send_ranks.size());
829 send_requests.reserve(send_ranks.size());
830
831 for (unsigned int i = 0; i < send_ranks.size(); ++i)
832 {
833 if (send_ranks[i] == my_rank)
834 continue;
835
838 buffer_send.begin() + send_ptrs[i] * n_components,
839 (send_ptrs[i + 1] - send_ptrs[i]) * n_components),
840 send_ranks[i],
843 send_buffers_packed,
844 send_requests);
845 }
846
847 // copy local data directly to output if no sorting is requested
848 if (!sort_data)
849 {
850 const auto my_rank_local_recv_ptr =
851 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
852
853 if (my_rank_local_recv_ptr != recv_ranks.end())
854 {
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(
858 send_ranks.begin(),
859 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
860
861 for (unsigned int j = recv_ptrs[my_rank_local_recv],
862 k = send_ptrs[my_rank_local_send];
863 j < recv_ptrs[my_rank_local_recv + 1];
864 ++j, ++k)
865 for (unsigned int c = 0; c < n_components; ++c)
866 output[j * n_components + c] =
867 buffer_eval[k * n_components + c];
868 }
869 }
870
871 // receive data
872 for (unsigned int i = 0; i < recv_ranks.size(); ++i)
873 {
874 if (recv_ranks[i] == my_rank)
875 continue;
876
877 // receive remote data
878 MPI_Status status;
879 int ierr = MPI_Probe(MPI_ANY_SOURCE,
882 &status);
883 AssertThrowMPI(ierr);
884
885 const auto ptr =
886 std::find(recv_ranks.begin(), recv_ranks.end(), status.MPI_SOURCE);
887
888 Assert(ptr != recv_ranks.end(), ExcNotImplemented());
889
890 const unsigned int j = std::distance(recv_ranks.begin(), ptr);
891
892 // ... for communication (recv)
893 ArrayView<DataType> recv_buffer(
894 sort_data ?
895 (buffer.data() + send_permutation.size() * 2 * n_components) :
896 (output.data() + recv_ptrs[j] * n_components),
897 (recv_ptrs[j + 1] - recv_ptrs[j]) * n_components);
898
899 internal::recv_and_unpack(recv_buffer,
901 status,
902 recv_buffer_packed);
903
904 if (sort_data)
905 {
906 // sort data into output vector (optional)
907 for (unsigned int i = recv_ptrs[j], k = 0; i < recv_ptrs[j + 1];
908 ++i, ++k)
909 for (unsigned int c = 0; c < n_components; ++c)
910 output[recv_permutation[i] * n_components + c] =
911 recv_buffer[k * n_components + c];
912 }
913 }
914
915 // make sure all messages have been sent
916 if (!send_requests.empty())
917 {
918 const int ierr = MPI_Waitall(send_requests.size(),
919 send_requests.data(),
920 MPI_STATUSES_IGNORE);
921 AssertThrowMPI(ierr);
922 }
923#endif
924 }
925
926
927 template <int dim, int spacedim>
928 template <typename DataType, unsigned int n_components>
929 std::vector<DataType>
931 const std::function<void(const ArrayView<DataType> &, const CellData &)>
932 &evaluation_function,
933 const bool sort_data) const
934 {
935 std::vector<DataType> output;
936 std::vector<DataType> buffer;
937
938 this->evaluate_and_process<DataType, n_components>(output,
939 buffer,
940 evaluation_function,
941 sort_data);
942
943 return output;
944 }
945
946
947
948 template <int dim, int spacedim>
949 template <typename DataType, unsigned int n_components>
950 void
952 const std::vector<DataType> &input,
953 std::vector<DataType> &buffer,
954 const std::function<void(const ArrayView<const DataType> &,
955 const CellData &)> &evaluation_function,
956 const bool sort_data) const
957 {
958#ifndef DEAL_II_WITH_MPI
959 Assert(false, ExcNeedsMPI());
960 (void)input;
961 (void)buffer;
962 (void)evaluation_function;
963 (void)sort_data;
964#else
965 static CollectiveMutex mutex;
967
968 const unsigned int my_rank =
970
971 // allocate memory for buffer
972 const auto &point_ptrs = this->get_point_ptrs();
973
974 AssertDimension(input.size(),
975 sort_data ? ((point_ptrs.size() - 1) * n_components) :
976 (point_ptrs.back() * n_components));
977 buffer.resize(
979 n_components);
980
981 // ... for evaluation
982 ArrayView<DataType> buffer_eval(buffer.data(),
983 send_permutation.size() * n_components);
984
985 // ... for communication (send)
986 ArrayView<DataType> buffer_send(
987 sort_data ? (buffer.data() + send_permutation.size() * n_components) :
988 const_cast<DataType *>(input.data()),
989 point_ptrs.back() * n_components);
990
991 // more arrays
992 std::vector<MPI_Request> send_requests;
993 std::vector<std::vector<char>> send_buffers_packed;
994 std::vector<char> recv_buffer_packed;
995
996 // sort for communication (and duplicate data if necessary)
997
998 if (sort_data)
999 {
1000 const auto my_rank_local_recv_ptr =
1001 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
1002
1003 if (my_rank_local_recv_ptr != recv_ranks.end())
1004 {
1005 // optimize the case if we have our own rank among the possible
1006 // list
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(
1010 send_ranks.begin(),
1011 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
1012
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 =
1016 send_permutation_inv.data() + send_ptrs[my_rank_local_send];
1017 for (unsigned int i = 0, k = 0; i < point_ptrs.size() - 1; ++i)
1018 {
1019 const unsigned int next = point_ptrs[i + 1];
1020 for (unsigned int j = point_ptrs[i]; j < next; ++j, ++k)
1021 {
1022 const unsigned int recv_index = recv_permutation_inv[k];
1023
1024 // local data -> can be copied to final buffer directly
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] *
1028 n_components +
1029 c] = input[i * n_components + c];
1030 else // data to be sent
1031 for (unsigned int c = 0; c < n_components; ++c)
1032 buffer_send[recv_index * n_components + c] =
1033 input[i * n_components + c];
1034 }
1035 }
1036 }
1037 else
1038 {
1039 for (unsigned int i = 0, k = 0; i < point_ptrs.size() - 1; ++i)
1040 for (unsigned int j = point_ptrs[i]; j < point_ptrs[i + 1];
1041 ++j, ++k)
1042 for (unsigned int c = 0; c < n_components; ++c)
1043 buffer_send[recv_permutation_inv[k] * n_components + c] =
1044 input[i * n_components + c];
1045 }
1046 }
1047
1048 // send data
1049 send_buffers_packed.reserve(recv_ranks.size());
1050 send_requests.reserve(recv_ranks.size());
1051
1052 for (unsigned int i = 0; i < recv_ranks.size(); ++i)
1053 {
1054 if (recv_ranks[i] == my_rank)
1055 continue;
1056
1059 buffer_send.begin() + recv_ptrs[i] * n_components,
1060 (recv_ptrs[i + 1] - recv_ptrs[i]) * n_components),
1061 recv_ranks[i],
1064 send_buffers_packed,
1065 send_requests);
1066 }
1067
1068 // copy local data directly to output if no sorting is requested
1069 if (!sort_data)
1070 {
1071 const auto my_rank_local_recv_ptr =
1072 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
1073
1074 if (my_rank_local_recv_ptr != recv_ranks.end())
1075 {
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(
1079 send_ranks.begin(),
1080 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
1081
1082 for (unsigned int j = recv_ptrs[my_rank_local_recv],
1083 k = send_ptrs[my_rank_local_send];
1084 j < recv_ptrs[my_rank_local_recv + 1];
1085 ++j, ++k)
1086 for (unsigned int c = 0; c < n_components; ++c)
1087 buffer_eval[k * n_components + c] =
1088 input[j * n_components + c];
1089 }
1090 }
1091
1092 for (unsigned int i = 0; i < send_ranks.size(); ++i)
1093 {
1094 if (send_ranks[i] == my_rank)
1095 continue;
1096
1097 // receive remote data
1098 MPI_Status status;
1099 int ierr = MPI_Probe(MPI_ANY_SOURCE,
1102 &status);
1103 AssertThrowMPI(ierr);
1104
1105 // write data into buffer vector
1106 const auto ptr =
1107 std::find(send_ranks.begin(), send_ranks.end(), status.MPI_SOURCE);
1108
1109 Assert(ptr != send_ranks.end(), ExcNotImplemented());
1110
1111 const unsigned int j = std::distance(send_ranks.begin(), ptr);
1112
1113 ArrayView<DataType> recv_buffer(
1114 sort_data ?
1115 (buffer.data() +
1116 (point_ptrs.back() + send_permutation.size()) * n_components) :
1117 (buffer.data() + send_ptrs[j] * n_components),
1118 (send_ptrs[j + 1] - send_ptrs[j]) * n_components);
1119
1120 internal::recv_and_unpack(recv_buffer,
1122 status,
1123 recv_buffer_packed);
1124
1125 if (sort_data)
1126 {
1127 for (unsigned int i = send_ptrs[j], k = 0; i < send_ptrs[j + 1];
1128 ++i, ++k)
1129 for (unsigned int c = 0; c < n_components; ++c)
1130 buffer_eval[send_permutation_inv[i] * n_components + c] =
1131 recv_buffer[k * n_components + c];
1132 }
1133 }
1134
1135 if (!send_requests.empty())
1136 {
1137 const int ierr = MPI_Waitall(send_requests.size(),
1138 send_requests.data(),
1139 MPI_STATUSES_IGNORE);
1140 AssertThrowMPI(ierr);
1141 }
1142
1143 // evaluate function at points
1144 evaluation_function(buffer_eval, *cell_data);
1145#endif
1146 }
1147
1148
1149
1150 template <int dim, int spacedim>
1151 template <typename DataType, unsigned int n_components>
1152 void
1154 const std::vector<DataType> &input,
1155 const std::function<void(const ArrayView<const DataType> &,
1156 const CellData &)> &evaluation_function,
1157 const bool sort_data) const
1158 {
1159 std::vector<DataType> buffer;
1160 this->process_and_evaluate<DataType, n_components>(input,
1161 buffer,
1162 evaluation_function,
1163 sort_data);
1164 }
1165
1166 } // end of namespace MPI
1167} // end of namespace Utilities
1168
1169
1171
1172#endif
iterator begin() const
Definition array_view.h:707
bool empty() const
Definition array_view.h:698
value_type * data() const noexcept
Definition array_view.h:666
std::size_t size() const
Definition array_view.h:689
Abstract base class for mapping classes.
Definition mapping.h:320
Definition point.h:113
virtual MPI_Comm get_mpi_communicator() 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
ArrayView< DataType > get_data_view(const unsigned int cell, const ArrayView< DataType > &values) 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:35
#define DEAL_II_DEPRECATED_WITH_COMMENT(comment)
Definition config.h:282
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:36
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
Definition mpi.cc:933
std::vector< index_type > data
Definition mpi.cc:750
const MPI_Comm comm
Definition mpi.cc:928
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:120
std::size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
Definition utilities.h:1382
constexpr T pow(const T base, const int iexp)
Definition utilities.h:967
boost::integer_range< IncrementableType > iota_view
Definition iota_view.h:45
STL namespace.