14#ifndef dealii_matrix_free_fe_remote_evaluation_h
15#define dealii_matrix_free_fe_remote_evaluation_h
39 template <
int dim,
int n_components,
typename value_type_>
42 using value_type =
typename internal::FEPointEvaluation::
43 EvaluatorTypeTraits<dim, dim, n_components, value_type_>::value_type;
46 EvaluatorTypeTraits<dim, dim, n_components, value_type_>::
81 const unsigned int face_number)
const;
102 std::vector<unsigned int>
ptrs;
110 template <
int dim,
int n_components,
typename value_type_>
164 reinit(
const unsigned int index_0,
const unsigned int index_1);
203 std::shared_ptr<Utilities::MPI::RemotePointEvaluation<dim>>
rpe;
216 std::vector<std::pair<unsigned int, unsigned int>>
232 std::shared_ptr<Utilities::MPI::RemotePointEvaluation<dim>>
rpe;
244 std::vector<unsigned int>
260 std::shared_ptr<Utilities::MPI::RemotePointEvaluation<dim>>
rpe;
267 std::pair<typename Triangulation<dim>::cell_iterator,
unsigned int>>
276 std::pair<typename Triangulation<dim>::cell_iterator,
unsigned int>>
295 const std::pair<unsigned int, unsigned int> &face_batch_range,
296 const std::vector<unsigned int> &quadrature_sizes);
306 const std::pair<unsigned int, unsigned int> &face_range,
307 const std::vector<unsigned int> &quadrature_sizes);
315 template <
typename Iterator>
320 const std::vector<std::vector<unsigned int>> &quadrature_sizes);
327 template <
int n_components,
328 typename PrecomputedEvaluationDataType,
333 PrecomputedEvaluationDataType &dst,
334 const MeshType &mesh,
335 const VectorType &src,
337 const unsigned int first_selected_component,
356 std::vector<std::variant<FERemoteCommunicationObjectEntityBatches<dim>,
372 template <
typename T1,
typename T2>
376 const std::vector<T2> &src,
377 const std::vector<unsigned int> &indices);
383 template <
typename T1,
typename T2>
388 const std::vector<T2> &src,
390 unsigned int>> &cell_face_nos);
396 template <
typename T1,
typename T2>
400 const std::vector<T2> &src,
401 const std::vector<std::pair<unsigned int, unsigned int>>
402 &batch_id_n_entities);
408 template <
typename T1, std::
size_t n_lanes>
411 const unsigned int v,
417 template <
typename T1,
int rank_, std::
size_t n_lanes,
int dim_>
420 const unsigned int v,
426 template <
typename T1,
436 const unsigned int v,
443 template <
typename T1,
typename T2>
482 &non_matching_faces_marked_vertices,
483 const unsigned int quadrature_index = 0,
484 const unsigned int dof_handler_index = 0,
485 const double tolerance = 1e-9);
515 &non_matching_faces_marked_vertices,
516 const unsigned int n_q_pnts_1D,
517 const unsigned int dof_handler_index = 0,
519 const double tolerance = 1e-9);
535template <
int dim,
int n_components,
typename value_type>
552 template <
typename MeshType>
554 const MeshType &mesh,
567 template <
typename VectorType>
652 const unsigned int face_number)
const
666 return ptrs[face_index];
676 template <
int dim,
int n_components,
typename value_type_>
683 , data_offset(
numbers::invalid_unsigned_int)
686 template <
int dim,
int n_components,
typename value_type_>
691 const unsigned int q)
const
696 return data.values[data_offset + q];
699 template <
int dim,
int n_components,
typename value_type_>
708 return data.gradients[data_offset + q];
711 template <
int dim,
int n_components,
typename value_type_>
714 const unsigned int index)
716 data_offset = view.get_shift(
index);
719 template <
int dim,
int n_components,
typename value_type_>
722 const unsigned int index_0,
723 const unsigned int index_1)
725 data_offset = view.get_shift(index_0, index_1);
733std::vector<std::pair<unsigned int, unsigned int>>
737 return batch_id_n_entities;
741std::vector<unsigned int>
748std::vector<std::pair<typename Triangulation<dim>::cell_iterator,
unsigned int>>
751 return cell_face_nos;
761 const std::pair<unsigned int, unsigned int> &face_batch_range,
762 const std::vector<unsigned int> &quadrature_sizes)
765 communication_objects.clear();
766 for (
const auto &co : comm_objects)
767 communication_objects.push_back(co);
770 const unsigned int n_cells = quadrature_sizes.size();
771 AssertDimension(n_cells, face_batch_range.second - face_batch_range.first);
774 view.start = face_batch_range.first;
776 view.ptrs.resize(n_cells + 1);
779 for (
unsigned int face = 0; face < n_cells; ++face)
781 view.ptrs[face + 1] = view.ptrs[face] + quadrature_sizes[face];
789 const std::pair<unsigned int, unsigned int> &face_range,
790 const std::vector<unsigned int> &quadrature_sizes)
793 communication_objects.clear();
794 for (
const auto &co : comm_objects)
795 communication_objects.push_back(co);
797 const unsigned int n_faces = quadrature_sizes.size();
801 view.start = face_range.first;
803 view.ptrs.resize(n_faces + 1);
806 for (
unsigned int face = 0; face < n_faces; ++face)
807 view.ptrs[face + 1] = view.ptrs[face] + quadrature_sizes[face];
811template <
typename Iterator>
816 const std::vector<std::vector<unsigned int>> &quadrature_sizes)
819 communication_objects.clear();
820 for (
const auto &co : comm_objects)
821 communication_objects.push_back(co);
823 const unsigned int n_cells = quadrature_sizes.size();
825 std::distance(cell_iterator_range.
begin(),
826 cell_iterator_range.
end()));
829 auto &cell_ptrs = view.ptrs_ptrs;
830 auto &face_ptrs = view.ptrs;
833 cell_ptrs.resize(n_cells);
834 unsigned int n_faces = 0;
835 for (
const auto &cell : cell_iterator_range)
837 cell_ptrs[cell->active_cell_index()] = n_faces;
838 n_faces += cell->n_faces();
841 face_ptrs.resize(n_faces + 1);
843 for (
const auto &cell : cell_iterator_range)
845 for (
const auto &f : cell->face_indices())
847 const unsigned int face_index =
848 cell_ptrs[cell->active_cell_index()] + f;
850 face_ptrs[face_index + 1] =
851 face_ptrs[face_index] +
852 quadrature_sizes[cell->active_cell_index()][f];
858template <
int n_components,
859 typename PrecomputedEvaluationDataType,
864 PrecomputedEvaluationDataType &dst,
865 const MeshType &mesh,
866 const VectorType &src,
868 const unsigned int first_selected_component,
871 const bool has_ghost_elements = src.has_ghost_elements();
873 if (has_ghost_elements ==
false)
874 src.update_ghost_values();
877 for (
const auto &communication_object : communication_objects)
882 [&](
const auto &obj) {
883 CopyInstructions::copy_data(
886 VectorTools::point_values<n_components>(
887 *obj.rpe, mesh, src, vec_flags, first_selected_component),
888 obj.get_communication_object_pntrs());
890 communication_object);
896 [&](
const auto &obj) {
897 CopyInstructions::copy_data(
900 VectorTools::point_gradients<n_components>(
901 *obj.rpe, mesh, src, vec_flags, first_selected_component),
902 obj.get_communication_object_pntrs());
904 communication_object);
910 if (has_ghost_elements ==
false)
911 src.zero_out_ghost_values();
922template <
typename T1,
typename T2>
927 const std::vector<T2> &src,
928 const std::vector<unsigned int> &indices)
933 for (
const auto idx : indices)
946template <
typename T1,
typename T2>
951 const std::vector<T2> &src,
953 unsigned int>> &cell_face_nos)
958 for (
const auto &[cell, f] : cell_face_nos)
960 for (
unsigned int j =
view.
get_shift(cell->active_cell_index(), f);
973template <
typename T1,
typename T2>
978 const std::vector<T2> &src,
979 const std::vector<std::pair<unsigned int, unsigned int>> &batch_id_n_entities)
984 for (
const auto &[batch_id, n_entries] : batch_id_n_entities)
986 for (
unsigned int v = 0; v < n_entries; ++v)
994 copy_data_entries(dst[j], v, src[c]);
1000template <
typename T1, std::
size_t n_lanes>
1004 const unsigned int v,
1013template <
typename T1,
int rank_, std::
size_t n_lanes,
int dim_>
1017 const unsigned int v,
1022 if constexpr (rank_ == 1)
1024 for (
unsigned int i = 0; i < dim_; ++i)
1029 for (
unsigned int i = 0; i < rank_; ++i)
1030 for (
unsigned int j = 0; j < dim_; ++j)
1031 dst[i][j][v] = src[i][j];
1036template <
typename T1,
1038 std::size_t n_lanes,
1046 const unsigned int v,
1049 if constexpr (rank_ == 1)
1051 for (
unsigned int i = 0; i < n_components_; ++i)
1052 copy_data(dst[i], v, src[i]);
1056 for (
unsigned int i = 0; i < rank_; ++i)
1057 for (
unsigned int j = 0; j < n_components_; ++j)
1058 dst[i][j][v] = src[i][j];
1063template <
typename T1,
typename T2>
1072 "copy_data_entries() not implemented for given arguments."));
1079 template <
int dim,
typename Number,
typename VectorizedArrayType>
1085 &non_matching_faces_marked_vertices,
1086 const unsigned int quadrature_index,
1087 const unsigned int dof_handler_index,
1088 const double tolerance)
1090 const auto &dof_handler = matrix_free.
get_dof_handler(dof_handler_index);
1091 const auto &tria = dof_handler.get_triangulation();
1107 std::vector<FERemoteCommunicationObjectEntityBatches<dim>> comm_objects;
1114 std::vector<unsigned int> global_quadrature_sizes(
1119 const auto face_batch_range =
1125 for (
const auto &[nm_face, marked_vertices] :
1126 non_matching_faces_marked_vertices)
1131 auto rpe = std::make_shared<Utilities::MPI::RemotePointEvaluation<dim>>(
1132 tolerance,
false, 0, marked_vertices);
1135 std::vector<std::pair<unsigned int, unsigned int>>
1136 face_batch_id_n_faces;
1139 std::vector<Point<dim>> points;
1149 for (
unsigned int bface = 0;
1150 bface < face_batch_range.second - face_batch_range.first;
1153 const unsigned int face = face_batch_range.first + bface;
1162 const unsigned int n_faces =
1164 face_batch_id_n_faces.emplace_back(face, n_faces);
1168 for (
unsigned int v = 0; v < n_faces; ++v)
1170 for (
unsigned int q : phi.quadrature_point_indices())
1172 const auto point = phi.quadrature_point(q);
1174 for (
unsigned int i = 0; i < dim; ++i)
1175 temp[i] = point[i][v];
1177 points.push_back(temp);
1183 Assert(global_quadrature_sizes[bface] ==
1186 "Quadrature for given face already provided."));
1188 global_quadrature_sizes[bface] = phi.n_q_points;
1193 rpe->reinit(points, tria, mapping);
1194 Assert(rpe->all_points_found(),
1201 comm_objects.push_back(co);
1209 std::replace(global_quadrature_sizes.begin(),
1210 global_quadrature_sizes.end(),
1216 global_quadrature_sizes);
1218 return remote_communicator;
1223 template <
int dim,
typename Number,
typename VectorizedArrayType>
1229 &non_matching_faces_marked_vertices,
1230 const unsigned int n_q_pnts_1D,
1231 const unsigned int dof_handler_index,
1233 const double tolerance)
1235 const auto &dof_handler = matrix_free.
get_dof_handler(dof_handler_index);
1236 const auto &tria = dof_handler.get_triangulation();
1241 std::pair<unsigned int, unsigned int> face_range =
1246 std::vector<
Quadrature<dim - 1>> global_quadrature_vector(
1258 std::vector<FERemoteCommunicationObject<dim>> comm_objects;
1262 std::vector<BoundingBox<dim>> local_boxes;
1263 for (
const auto &cell : tria.active_cell_iterators())
1264 if (cell->is_locally_owned())
1265 local_boxes.emplace_back(mapping.get_bounding_box(cell));
1268 const auto local_tree =
pack_rtree(local_boxes);
1271 std::vector<std::vector<BoundingBox<dim>>> global_bboxes(1);
1277 for (
const auto &[nm_face, marked_vertices] :
1278 non_matching_faces_marked_vertices)
1282 std::pair<typename Triangulation<dim>::cell_iterator,
unsigned int>>
1285 std::vector<unsigned int> indices;
1287 for (
unsigned int face = face_range.first; face < face_range.second;
1292 for (
unsigned int v = 0;
1298 cell_face_pairs.emplace_back(std::make_pair(c, f));
1299 indices.push_back(face * n_lanes + v);
1312 std::vector<std::vector<Point<dim>>> intersection_requests;
1313 for (
const auto &[cell, f] : cell_face_pairs)
1315 std::vector<Point<dim>> vertices(cell->face(f)->n_vertices());
1316 std::copy_n(mapping.get_vertices(cell, f).begin(),
1317 cell->face(f)->n_vertices(),
1319 intersection_requests.emplace_back(vertices);
1324 auto intersection_data =
1327 intersection_requests,
1333 std::vector<Quadrature<dim>> mapped_quadratures_recv_comp;
1336 std::make_shared<Utilities::MPI::RemotePointEvaluation<dim>>();
1339 .
template convert_to_distributed_compute_point_locations_internal<
1340 dim>(n_q_pnts_1D, tria, mapping, &mapped_quadratures_recv_comp),
1345 for (
unsigned int i = 0; i < intersection_requests.size(); ++i)
1347 const auto idx = indices[i];
1352 const auto &cell = std::get<0>(cell_face_pairs[i]);
1353 const auto &f = std::get<1>(cell_face_pairs[i]);
1355 std::vector<
Point<dim - 1>> q_points;
1356 std::vector<double> weights;
1357 for (
unsigned int ptr = intersection_data.recv_ptrs[i];
1358 ptr < intersection_data.recv_ptrs[i + 1];
1361 const auto &quad = mapped_quadratures_recv_comp[ptr];
1363 const auto &ps = quad.get_points();
1367 std::back_inserter(q_points),
1369 return mapping.project_real_point_to_unit_point_on_face(
1373 const auto &ws = quad.get_weights();
1374 weights.insert(weights.end(), ws.begin(), ws.end());
1378 Assert(global_quadrature_vector[idx].
size() == 0,
1379 ExcMessage(
"Quadrature for given face already provided."));
1381 global_quadrature_vector[idx] = quad;
1388 comm_objects.push_back(co);
1394 std::vector<unsigned int> global_quadrature_sizes(
1395 global_quadrature_vector.size());
1396 std::transform(global_quadrature_vector.cbegin(),
1397 global_quadrature_vector.cend(),
1398 global_quadrature_sizes.begin(),
1399 [](
const auto &q) { return q.size(); });
1403 std::make_pair(0, global_quadrature_vector.size()),
1404 global_quadrature_sizes);
1406 if (nm_mapping_info !=
nullptr)
1409 std::pair<typename DoFHandler<dim>::cell_iterator,
unsigned int>>
1410 vector_face_accessors;
1416 unsigned int face_batch = 0;
1419 for (
unsigned int v = 0; v < n_lanes; ++v)
1422 vector_face_accessors.push_back(
1425 vector_face_accessors.push_back(
1434 for (
unsigned int v = 0; v < n_lanes; ++v)
1437 vector_face_accessors.push_back(
1440 vector_face_accessors.push_back(
1446 global_quadrature_vector);
1449 return remote_communicator;
1455template <
int dim,
int n_components,
typename value_type>
1456template <
typename MeshType>
1459 const MeshType &mesh,
1460 const unsigned int first_selected_component,
1463 , first_selected_component(first_selected_component)
1464 , evaluation_flags(evaluation_flags)
1469template <
int dim,
int n_components,
typename value_type>
1470template <
typename VectorType>
1473 const VectorType &src,
1479 comm->template update_ghost_values<n_components>(this->
data,
1483 first_selected_component,
1486 else if (dof_handler)
1488 comm->template update_ghost_values<n_components>(this->
data,
1492 first_selected_component,
1499template <
int dim,
int n_components,
typename value_type>
1505 return data_accessor;
1508template <
int dim,
int n_components,
typename value_type>
1516template <
int dim,
int n_components,
typename value_type>
1521 this->dof_handler = &dof_handler;
void resize(const size_type new_size)
static void copy_data(const internal::PrecomputedEvaluationDataView &view, AlignedVector< T1 > &dst, const std::vector< T2 > &src, const std::vector< unsigned int > &indices)
static void copy_data_entries(VectorizedArray< T1, n_lanes > &dst, const unsigned int v, const T1 &src)
const internal::PrecomputedEvaluationDataView & get_view() const
void reinit_faces(const std::vector< FERemoteCommunicationObjectEntityBatches< dim > > &comm_objects, const std::pair< unsigned int, unsigned int > &face_batch_range, const std::vector< unsigned int > &quadrature_sizes)
void update_ghost_values(PrecomputedEvaluationDataType &dst, const MeshType &mesh, const VectorType &src, const EvaluationFlags::EvaluationFlags eval_flags, const unsigned int first_selected_component, const VectorTools::EvaluationFlags::EvaluationFlags vec_flags) const
internal::PrecomputedEvaluationDataView view
std::vector< std::variant< FERemoteCommunicationObjectEntityBatches< dim >, FERemoteCommunicationObject< dim >, FERemoteCommunicationObjectTwoLevel< dim > > > communication_objects
FERemoteEvaluation(const FERemoteEvaluationCommunicator< dim > &comm, const MeshType &mesh, const unsigned int first_selected_component=0, const VectorTools::EvaluationFlags::EvaluationFlags evaluation_flags=VectorTools::EvaluationFlags::avg)
ObserverPointer< const DoFHandler< dim > > dof_handler
ObserverPointer< const FERemoteEvaluationCommunicator< dim > > comm
void set_mesh(const Triangulation< dim > &tria)
internal::PrecomputedEvaluationData< dim, n_components, value_type > data
ObserverPointer< const Triangulation< dim > > tria
const VectorTools::EvaluationFlags::EvaluationFlags evaluation_flags
const unsigned int first_selected_component
internal::PrecomputedEvaluationDataAccessor< dim, n_components, value_type > get_data_accessor() const
void gather_evaluate(const VectorType &src, const EvaluationFlags::EvaluationFlags flags)
IteratorOverIterators end() const
IteratorOverIterators begin()
std::pair< typename DoFHandler< dim >::cell_iterator, unsigned int > get_face_iterator(const unsigned int face_batch_index, const unsigned int lane_index, const bool interior=true, const unsigned int fe_component=0) const
types::boundary_id get_boundary_id(const unsigned int face_batch_index) const
unsigned int n_inner_face_batches() const
const DoFHandler< dim > & get_dof_handler(const unsigned int dof_handler_index=0) const
const internal::MatrixFreeFunctions::MappingInfo< dim, Number, VectorizedArrayType > & get_mapping_info() const
unsigned int n_boundary_face_batches() const
unsigned int n_active_entries_per_face_batch(const unsigned int face_batch_index) const
void reinit_faces(const ContainerType &cell_iterator_range, const std::vector< std::vector< Quadrature< dim - 1 > > > &quadrature_vector, const unsigned int n_unfiltered_cells=numbers::invalid_unsigned_int)
static constexpr std::size_t size()
const gradient_type get_gradient(const unsigned int q) const
PrecomputedEvaluationDataAccessor(const PrecomputedEvaluationData< dim, n_components, value_type_ > &data, const PrecomputedEvaluationDataView &view)
const PrecomputedEvaluationDataView & view
typename PrecomputedEvaluationData< dim, n_components, value_type_ >::value_type value_type
const PrecomputedEvaluationData< dim, n_components, value_type_ > & data
const value_type get_value(const unsigned int q) const
void reinit(const unsigned int index)
typename PrecomputedEvaluationData< dim, n_components, value_type_ >::gradient_type gradient_type
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< index_type > data
EvaluationFlags
The EvaluationFlags enum.
FERemoteEvaluationCommunicator< dim > compute_remote_communicator_faces_point_to_point_interpolation(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const std::vector< std::pair< types::boundary_id, std::function< std::vector< bool >()> > > &non_matching_faces_marked_vertices, const unsigned int quadrature_index=0, const unsigned int dof_handler_index=0, const double tolerance=1e-9)
FERemoteEvaluationCommunicator< dim > compute_remote_communicator_faces_nitsche_type_mortaring(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free, const std::vector< std::pair< types::boundary_id, std::function< std::vector< bool >()> > > &non_matching_faces_marked_vertices, const unsigned int n_q_pnts_1D, const unsigned int dof_handler_index=0, NonMatching::MappingInfo< dim, dim, Number > *nm_mapping_info=nullptr, const double tolerance=1e-9)
constexpr unsigned int invalid_unsigned_int
std::vector< BoundingBox< boost::geometry::dimension< typename Rtree::indexable_type >::value > > extract_rtree_level(const Rtree &tree, const unsigned int level)
RTree< typename LeafTypeIterator::value_type, IndexType, IndexableGetter > pack_rtree(const LeafTypeIterator &begin, const LeafTypeIterator &end)
std::vector< std::pair< unsigned int, unsigned int > > batch_id_n_entities
std::vector< std::pair< unsigned int, unsigned int > > get_communication_object_pntrs() const
std::shared_ptr< Utilities::MPI::RemotePointEvaluation< dim > > rpe
std::shared_ptr< Utilities::MPI::RemotePointEvaluation< dim > > rpe
std::vector< std::pair< typename Triangulation< dim >::cell_iterator, unsigned int > > cell_face_nos
std::vector< std::pair< typename Triangulation< dim >::cell_iterator, unsigned int > > get_communication_object_pntrs() const
std::shared_ptr< Utilities::MPI::RemotePointEvaluation< dim > > rpe
std::vector< unsigned int > indices
std::vector< unsigned int > get_communication_object_pntrs() const
unsigned int get_shift(const unsigned int index) const
unsigned int size() const
std::vector< unsigned int > ptrs_ptrs
std::vector< unsigned int > ptrs
AlignedVector< value_type > values
typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, dim, n_components, value_type_ >::value_type value_type
typename internal::FEPointEvaluation::EvaluatorTypeTraits< dim, dim, n_components, value_type_ >::real_gradient_type gradient_type
AlignedVector< gradient_type > gradients