deal.II version GIT relicensing-2888-ge8e3b84039 2025-03-21 18: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 - 2024 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 {
57 template <int dim, int spacedim = dim>
59 {
60 public:
66 {
67 public:
72 const double tolerance = 1e-6,
73 const bool enforce_unique_mapping = false,
74 const unsigned int rtree_level = 0,
75 const std::function<std::vector<bool>()> &marked_vertices = {});
76
85 double tolerance;
86
92
96 unsigned int rtree_level;
97
102 std::function<std::vector<bool>()> marked_vertices;
103 };
104
112
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 = {});
138
143
155 void
156 reinit(const std::vector<Point<spacedim>> &points,
159
170 void
172 const std::vector<Point<spacedim>> &points);
173
183 void
185 DistributedComputePointLocationsInternal<dim, spacedim> &data,
186 const Triangulation<dim, spacedim> &tria,
187 const Mapping<dim, spacedim> &mapping);
188
194 {
195 public:
202
229 cell_indices() const;
230
235 get_active_cell_iterator(const unsigned int cell) const;
236
241 get_unit_points(const unsigned int cell) const;
242
246 template <typename T>
248 get_data_view(const unsigned int cell,
249 const ArrayView<T> &values) const;
250
254 std::vector<std::pair<int, int>> cells;
255
260 std::vector<unsigned int> reference_point_ptrs;
261
265 std::vector<Point<dim>> reference_point_values;
266
267 private:
273 };
274
279 const CellData &
280 get_cell_data() const;
281
302 template <typename T, unsigned int n_components = 1>
303 void
305 std::vector<T> &output,
306 std::vector<T> &buffer,
307 const std::function<void(const ArrayView<T> &, const CellData &)>
308 &evaluation_function,
309 const bool sort_data = true) const;
310
315 template <typename T, unsigned int n_components = 1>
316 std::vector<T>
318 const std::function<void(const ArrayView<T> &, const CellData &)>
319 &evaluation_function,
320 const bool sort_data = true) const;
321
336 template <typename T, unsigned int n_components = 1>
337 void
339 const std::vector<T> &input,
340 std::vector<T> &buffer,
341 const std::function<void(const ArrayView<const T> &, const CellData &)>
342 &evaluation_function,
343 const bool sort_data = true) const;
344
349 template <typename T, unsigned int n_components = 1>
350 void
352 const std::vector<T> &input,
353 const std::function<void(const ArrayView<const T> &, const CellData &)>
354 &evaluation_function,
355 const bool sort_data = true) const;
356
361 const std::vector<unsigned int> &
362 get_point_ptrs() const;
363
370 bool
371 is_map_unique() const;
372
376 bool
377 all_points_found() const;
378
382 bool
383 point_found(const unsigned int i) const;
384
389 get_triangulation() const;
390
395 get_mapping() const;
396
402 bool
403 is_ready() const;
404
410 const std::vector<unsigned int> &
411 get_send_permutation() const;
412
419 const std::vector<unsigned int> &
421
422
423 private:
428
432 boost::signals2::connection tria_signal;
433
440
445
450
455
460
466 std::vector<unsigned int> point_ptrs;
467
471 std::vector<unsigned int> recv_permutation;
472
476 std::vector<unsigned int> recv_permutation_inv;
477
482 std::vector<unsigned int> recv_ptrs;
483
487 std::vector<unsigned int> recv_ranks;
488
493 std::unique_ptr<CellData> cell_data;
494
498 std::vector<unsigned int> send_permutation;
499
503 std::vector<unsigned int> send_permutation_inv;
504
508 std::vector<unsigned int> send_ranks;
509
514 std::vector<unsigned int> send_ptrs;
515
530
536 };
537
538 namespace internal
539 {
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,
549 const MPI_Comm comm,
550 std::vector<std::vector<char>> &buffers,
551 std::vector<MPI_Request> &requests)
552 {
553 requests.emplace_back(MPI_Request());
554
555 buffers.emplace_back(Utilities::pack(
556 std::vector<T>(data.data(), data.data() + data.size()), false));
557
558 const int ierr = MPI_Isend(buffers.back().data(),
559 buffers.back().size(),
560 MPI_CHAR,
561 rank,
562 tag,
563 comm,
564 &requests.back());
565 AssertThrowMPI(ierr);
566 }
567
568
569
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,
579 const MPI_Comm comm,
580 std::vector<std::vector<char>> & /*buffers*/,
581 std::vector<MPI_Request> &requests)
582 {
583 requests.emplace_back(MPI_Request());
584
585 const int ierr = MPI_Isend(data.data(),
586 data.size(),
587 Utilities::MPI::mpi_type_id_for_type<T>,
588 rank,
589 tag,
590 comm,
591 &requests.back());
592 AssertThrowMPI(ierr);
593 }
594
595
596
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,
606 const MPI_Comm comm,
607 std::vector<std::vector<char>> &buffers,
608 std::vector<MPI_Request> &requests)
609 {
610 ArrayView<const T> data_(reinterpret_cast<const T *>(data.data()),
611 data.size() * Utilities::pow(dim, rank_));
612
613 pack_and_isend(data_, rank, tag, comm, buffers, requests);
614 }
615
616
620 template <typename T>
621 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == false, void>
623 const MPI_Comm comm,
624 const MPI_Status &status,
625 std::vector<char> &buffer)
626 {
627 int message_length;
628 int ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
629 AssertThrowMPI(ierr);
630
631 buffer.resize(message_length);
632
633 ierr = MPI_Recv(buffer.data(),
634 buffer.size(),
635 MPI_CHAR,
636 status.MPI_SOURCE,
638 comm,
639 MPI_STATUS_IGNORE);
640 AssertThrowMPI(ierr);
641
642 // unpack data
643 const auto temp = Utilities::unpack<std::vector<T>>(buffer, false);
644
645 for (unsigned int i = 0; i < data.size(); ++i)
646 data[i] = temp[i];
647 }
648
649
650
655 template <typename T>
656 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == true, void>
658 const MPI_Comm comm,
659 const MPI_Status &status,
660 std::vector<char> & /*buffer*/)
661 {
662 const auto ierr = MPI_Recv(data.data(),
663 data.size(),
664 Utilities::MPI::mpi_type_id_for_type<T>,
665 status.MPI_SOURCE,
667 comm,
668 MPI_STATUS_IGNORE);
669 AssertThrowMPI(ierr);
670 }
671
672
673
678 template <int rank_, int dim, typename T>
679 std::enable_if_t<Utilities::MPI::is_mpi_type<T> == true, void>
681 const MPI_Comm comm,
682 const MPI_Status &status,
683 std::vector<char> &buffer)
684 {
685 const ArrayView<T> data_(reinterpret_cast<T *>(data.data()),
686 data.size() * Utilities::pow(dim, rank_));
687
688 recv_and_unpack(data_, comm, status, buffer);
689 }
690#endif
691 } // namespace internal
692
693
694
695 template <int dim, int spacedim>
696 template <typename T>
699 const unsigned int cell,
700 const ArrayView<T> &values) const
701 {
702 AssertIndexRange(cell, cells.size());
703 return {values.data() + reference_point_ptrs[cell],
705 }
706
707
708
709 template <int dim, int spacedim>
710 template <typename T, unsigned int n_components>
711 void
713 std::vector<T> &output,
714 std::vector<T> &buffer,
715 const std::function<void(const ArrayView<T> &, const CellData &)>
716 &evaluation_function,
717 const bool sort_data) const
718 {
719#ifndef DEAL_II_WITH_MPI
720 Assert(false, ExcNeedsMPI());
721 (void)output;
722 (void)buffer;
723 (void)evaluation_function;
724 (void)sort_data;
725#else
726 static CollectiveMutex mutex;
728
729 const unsigned int my_rank =
731
732 // allocate memory for output and buffer
733 output.resize(point_ptrs.back() * n_components);
734
735 buffer.resize(
737 n_components);
738
739 // ... for evaluation
740 ArrayView<T> buffer_eval(buffer.data(),
741 send_permutation.size() * n_components);
742
743 // ... for communication (send)
744 ArrayView<T> buffer_send(sort_data ?
745 (buffer.data() +
746 send_permutation.size() * n_components) :
747 buffer.data(),
748 send_permutation.size() * n_components);
749
750 // more arrays
751 std::vector<MPI_Request> send_requests;
752 std::vector<std::vector<char>> send_buffers_packed;
753 std::vector<char> recv_buffer_packed;
754
755 // evaluate functions at points
756 evaluation_function(buffer_eval, *cell_data);
757
758 // sort for communication (optional)
759 if (sort_data)
760 {
761 const auto my_rank_local_recv_ptr =
762 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
763
764 if (my_rank_local_recv_ptr != recv_ranks.end())
765 {
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(
769 send_ranks.begin(),
770 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
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 =
774 recv_permutation.data() + recv_ptrs[my_rank_local_recv];
775 for (unsigned int i = 0; i < send_permutation.size(); ++i)
776 {
777 const unsigned int send_index = send_permutation[i];
778
779 if (start <= send_index && send_index < end)
780 // local data -> can be copied to output directly
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];
784 else
785 // data to be sent
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];
789 }
790 }
791 else
792 {
793 for (unsigned int i = 0; i < send_permutation.size(); ++i)
794 for (unsigned int c = 0; c < n_components; ++c)
795 buffer_send[send_permutation[i] * n_components + c] =
796 buffer_eval[i * n_components + c];
797 }
798 }
799
800 // send data
801 send_buffers_packed.reserve(send_ranks.size());
802 send_requests.reserve(send_ranks.size());
803
804 for (unsigned int i = 0; i < send_ranks.size(); ++i)
805 {
806 if (send_ranks[i] == my_rank)
807 continue;
808
811 buffer_send.begin() + send_ptrs[i] * n_components,
812 (send_ptrs[i + 1] - send_ptrs[i]) * n_components),
813 send_ranks[i],
816 send_buffers_packed,
817 send_requests);
818 }
819
820 // copy local data directly to output if no sorting is requested
821 if (!sort_data)
822 {
823 const auto my_rank_local_recv_ptr =
824 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
825
826 if (my_rank_local_recv_ptr != recv_ranks.end())
827 {
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(
831 send_ranks.begin(),
832 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
833
834 for (unsigned int j = recv_ptrs[my_rank_local_recv],
835 k = send_ptrs[my_rank_local_send];
836 j < recv_ptrs[my_rank_local_recv + 1];
837 ++j, ++k)
838 for (unsigned int c = 0; c < n_components; ++c)
839 output[j * n_components + c] =
840 buffer_eval[k * n_components + c];
841 }
842 }
843
844 // receive data
845 for (unsigned int i = 0; i < recv_ranks.size(); ++i)
846 {
847 if (recv_ranks[i] == my_rank)
848 continue;
849
850 // receive remote data
851 MPI_Status status;
852 int ierr = MPI_Probe(MPI_ANY_SOURCE,
855 &status);
856 AssertThrowMPI(ierr);
857
858 const auto ptr =
859 std::find(recv_ranks.begin(), recv_ranks.end(), status.MPI_SOURCE);
860
861 Assert(ptr != recv_ranks.end(), ExcNotImplemented());
862
863 const unsigned int j = std::distance(recv_ranks.begin(), ptr);
864
865 // ... for communication (recv)
866 ArrayView<T> recv_buffer(
867 sort_data ?
868 (buffer.data() + send_permutation.size() * 2 * n_components) :
869 (output.data() + recv_ptrs[j] * n_components),
870 (recv_ptrs[j + 1] - recv_ptrs[j]) * n_components);
871
872 internal::recv_and_unpack(recv_buffer,
874 status,
875 recv_buffer_packed);
876
877 if (sort_data)
878 {
879 // sort data into output vector (optional)
880 for (unsigned int i = recv_ptrs[j], k = 0; i < recv_ptrs[j + 1];
881 ++i, ++k)
882 for (unsigned int c = 0; c < n_components; ++c)
883 output[recv_permutation[i] * n_components + c] =
884 recv_buffer[k * n_components + c];
885 }
886 }
887
888 // make sure all messages have been sent
889 if (!send_requests.empty())
890 {
891 const int ierr = MPI_Waitall(send_requests.size(),
892 send_requests.data(),
893 MPI_STATUSES_IGNORE);
894 AssertThrowMPI(ierr);
895 }
896#endif
897 }
898
899
900 template <int dim, int spacedim>
901 template <typename T, unsigned int n_components>
902 std::vector<T>
904 const std::function<void(const ArrayView<T> &, const CellData &)>
905 &evaluation_function,
906 const bool sort_data) const
907 {
908 std::vector<T> output;
909 std::vector<T> buffer;
910
911 this->evaluate_and_process<T, n_components>(output,
912 buffer,
913 evaluation_function,
914 sort_data);
915
916 return output;
917 }
918
919
920
921 template <int dim, int spacedim>
922 template <typename T, unsigned int n_components>
923 void
925 const std::vector<T> &input,
926 std::vector<T> &buffer,
927 const std::function<void(const ArrayView<const T> &, const CellData &)>
928 &evaluation_function,
929 const bool sort_data) const
930 {
931#ifndef DEAL_II_WITH_MPI
932 Assert(false, ExcNeedsMPI());
933 (void)input;
934 (void)buffer;
935 (void)evaluation_function;
936 (void)sort_data;
937#else
938 static CollectiveMutex mutex;
940
941 const unsigned int my_rank =
943
944 // allocate memory for buffer
945 const auto &point_ptrs = this->get_point_ptrs();
946
947 AssertDimension(input.size(),
948 sort_data ? ((point_ptrs.size() - 1) * n_components) :
949 (point_ptrs.back() * n_components));
950 buffer.resize(
952 n_components);
953
954 // ... for evaluation
955 ArrayView<T> buffer_eval(buffer.data(),
956 send_permutation.size() * n_components);
957
958 // ... for communication (send)
959 ArrayView<T> buffer_send(sort_data ?
960 (buffer.data() +
961 send_permutation.size() * n_components) :
962 const_cast<T *>(input.data()),
963 point_ptrs.back() * n_components);
964
965 // more arrays
966 std::vector<MPI_Request> send_requests;
967 std::vector<std::vector<char>> send_buffers_packed;
968 std::vector<char> recv_buffer_packed;
969
970 // sort for communication (and duplicate data if necessary)
971
972 if (sort_data)
973 {
974 const auto my_rank_local_recv_ptr =
975 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
976
977 if (my_rank_local_recv_ptr != recv_ranks.end())
978 {
979 // optimize the case if we have our own rank among the possible
980 // list
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(
984 send_ranks.begin(),
985 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
986
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 =
990 send_permutation_inv.data() + send_ptrs[my_rank_local_send];
991 for (unsigned int i = 0, k = 0; i < point_ptrs.size() - 1; ++i)
992 {
993 const unsigned int next = point_ptrs[i + 1];
994 for (unsigned int j = point_ptrs[i]; j < next; ++j, ++k)
995 {
996 const unsigned int recv_index = recv_permutation_inv[k];
997
998 // local data -> can be copied to final buffer directly
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] *
1002 n_components +
1003 c] = input[i * n_components + c];
1004 else // data to be sent
1005 for (unsigned int c = 0; c < n_components; ++c)
1006 buffer_send[recv_index * n_components + c] =
1007 input[i * n_components + c];
1008 }
1009 }
1010 }
1011 else
1012 {
1013 for (unsigned int i = 0, k = 0; i < point_ptrs.size() - 1; ++i)
1014 for (unsigned int j = point_ptrs[i]; j < point_ptrs[i + 1];
1015 ++j, ++k)
1016 for (unsigned int c = 0; c < n_components; ++c)
1017 buffer_send[recv_permutation_inv[k] * n_components + c] =
1018 input[i * n_components + c];
1019 }
1020 }
1021
1022 // send data
1023 send_buffers_packed.reserve(recv_ranks.size());
1024 send_requests.reserve(recv_ranks.size());
1025
1026 for (unsigned int i = 0; i < recv_ranks.size(); ++i)
1027 {
1028 if (recv_ranks[i] == my_rank)
1029 continue;
1030
1033 buffer_send.begin() + recv_ptrs[i] * n_components,
1034 (recv_ptrs[i + 1] - recv_ptrs[i]) * n_components),
1035 recv_ranks[i],
1038 send_buffers_packed,
1039 send_requests);
1040 }
1041
1042 // copy local data directly to output if no sorting is requested
1043 if (!sort_data)
1044 {
1045 const auto my_rank_local_recv_ptr =
1046 std::find(recv_ranks.begin(), recv_ranks.end(), my_rank);
1047
1048 if (my_rank_local_recv_ptr != recv_ranks.end())
1049 {
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(
1053 send_ranks.begin(),
1054 std::find(send_ranks.begin(), send_ranks.end(), my_rank));
1055
1056 for (unsigned int j = recv_ptrs[my_rank_local_recv],
1057 k = send_ptrs[my_rank_local_send];
1058 j < recv_ptrs[my_rank_local_recv + 1];
1059 ++j, ++k)
1060 for (unsigned int c = 0; c < n_components; ++c)
1061 buffer_eval[k * n_components + c] =
1062 input[j * n_components + c];
1063 }
1064 }
1065
1066 for (unsigned int i = 0; i < send_ranks.size(); ++i)
1067 {
1068 if (send_ranks[i] == my_rank)
1069 continue;
1070
1071 // receive remote data
1072 MPI_Status status;
1073 int ierr = MPI_Probe(MPI_ANY_SOURCE,
1076 &status);
1077 AssertThrowMPI(ierr);
1078
1079 // write data into buffer vector
1080 const auto ptr =
1081 std::find(send_ranks.begin(), send_ranks.end(), status.MPI_SOURCE);
1082
1083 Assert(ptr != send_ranks.end(), ExcNotImplemented());
1084
1085 const unsigned int j = std::distance(send_ranks.begin(), ptr);
1086
1087 ArrayView<T> recv_buffer(
1088 sort_data ?
1089 (buffer.data() +
1090 (point_ptrs.back() + send_permutation.size()) * n_components) :
1091 (buffer.data() + send_ptrs[j] * n_components),
1092 (send_ptrs[j + 1] - send_ptrs[j]) * n_components);
1093
1094 internal::recv_and_unpack(recv_buffer,
1096 status,
1097 recv_buffer_packed);
1098
1099 if (sort_data)
1100 {
1101 for (unsigned int i = send_ptrs[j], k = 0; i < send_ptrs[j + 1];
1102 ++i, ++k)
1103 for (unsigned int c = 0; c < n_components; ++c)
1104 buffer_eval[send_permutation_inv[i] * n_components + c] =
1105 recv_buffer[k * n_components + c];
1106 }
1107 }
1108
1109 if (!send_requests.empty())
1110 {
1111 const int ierr = MPI_Waitall(send_requests.size(),
1112 send_requests.data(),
1113 MPI_STATUSES_IGNORE);
1114 AssertThrowMPI(ierr);
1115 }
1116
1117 // evaluate function at points
1118 evaluation_function(buffer_eval, *cell_data);
1119#endif
1120 }
1121
1122
1123
1124 template <int dim, int spacedim>
1125 template <typename T, unsigned int n_components>
1126 void
1128 const std::vector<T> &input,
1129 const std::function<void(const ArrayView<const T> &, const CellData &)>
1130 &evaluation_function,
1131 const bool sort_data) const
1132 {
1133 std::vector<T> buffer;
1134 this->process_and_evaluate<T, n_components>(input,
1135 buffer,
1136 evaluation_function,
1137 sort_data);
1138 }
1139
1140 } // end of namespace MPI
1141} // end of namespace Utilities
1142
1143
1145
1146#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
ArrayView< T > get_data_view(const unsigned int cell, const ArrayView< T > &values) 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
const std::vector< unsigned int > & get_send_permutation() const
ObserverPointer< const Mapping< dim, spacedim > > mapping
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
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
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
void reinit(const std::vector< Point< spacedim > > &points, const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_DEPRECATED_WITH_COMMENT(comment)
Definition config.h:284
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
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:929
std::vector< index_type > data
Definition mpi.cc:746
const MPI_Comm comm
Definition mpi.cc:924
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:114
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.