17 #ifndef dealii_mesh_worker_mesh_loop_h 18 #define dealii_mesh_worker_mesh_loop_h 36 #include <type_traits> 54 template <
class CellIteratorType>
60 using type = CellIteratorType;
70 template <
class CellIteratorType>
90 template <
class CellIteratorType>
121 std::function<void(
const CellIteratorBaseType &,
131 std::function<void(
const CellIteratorBaseType &,
134 const CellIteratorBaseType &,
274 template <
class CellIteratorType,
277 class CellIteratorBaseType =
282 const CellIteratorType &
begin,
283 const CellIteratorType &
end,
286 const CopierType & copier,
288 const ScratchData &sample_scratch_data,
289 const CopyData & sample_copy_data,
300 const CellIteratorType & begin,
303 const typename identity<std::function<
304 void(
const CellIteratorBaseType &, ScratchData &, CopyData &)>>::
type 306 const typename identity<std::function<
void(
const CopyData &)>>::
type 309 const ScratchData &sample_scratch_data,
310 const CopyData & sample_copy_data,
314 const typename identity<std::function<
void(
const CellIteratorBaseType &,
318 &boundary_worker = std::function<
void(
const CellIteratorBaseType &,
323 const typename identity<std::function<
void(
const CellIteratorBaseType &,
326 const CellIteratorBaseType &,
331 &face_worker = std::function<
void(
const CellIteratorBaseType &,
334 const CellIteratorBaseType &,
348 "If you provide a cell worker function, you also need to request " 349 "that work should be done on cells by setting the 'work_on_cells' flag. " 350 "Conversely, if you don't provide a cell worker function, you " 351 "cannot set the 'work_on_cells' flag. One of these two " 352 "conditions is not satisfied."));
359 "If you provide a face worker function, you also need to request " 360 "that work should be done on interior faces by setting either the " 361 "'assemble_own_interior_faces_once' flag or the " 362 "'assemble_own_interior_faces_both' flag. " 363 "Conversely, if you don't provide a face worker function, you " 364 "cannot set either of these two flags. One of these two " 365 "conditions is not satisfied."));
370 "You can only 'specify assemble_ghost_faces_once' " 371 "OR 'assemble_ghost_faces_both', but not both of these flags."));
377 "The option 'cells_after_faces' only makes sense if you assemble on cells."));
382 "If you provide a face worker function, you also need to request " 383 "that work should be done on faces by setting the 'work_on_faces' flag. " 384 "Conversely, if you don't provide a face worker function, you " 385 "cannot set the 'work_on_faces' flag. One of these two " 386 "conditions is not satisfied."));
391 "If you provide a boundary face worker function, you also need to request " 392 "that work should be done on boundary faces by setting the 'assemble_boundary_faces' flag. " 393 "Conversely, if you don't provide a boundary face worker function, you " 394 "cannot set the 'assemble_boundary_faces' flag. One of these two " 395 "conditions is not satisfied."));
397 auto cell_action = [&](
const CellIteratorBaseType &cell,
398 ScratchData & scratch,
402 copy = sample_copy_data;
405 const auto dim = cell->get_triangulation().dimension;
407 const bool ignore_subdomain =
408 (cell->get_triangulation().locally_owned_subdomain() ==
412 (cell->is_level_cell() ? cell->level_subdomain_id() :
413 cell->subdomain_id());
415 const bool own_cell =
417 (current_subdomain_id ==
418 cell->get_triangulation().locally_owned_subdomain());
420 if ((!ignore_subdomain) &&
424 if (!(flags & (cells_after_faces)) &&
427 cell_worker(cell, scratch,
copy);
430 for (
const unsigned int face_no : cell->face_indices())
432 if (cell->at_boundary(face_no) &&
433 !cell->has_periodic_neighbor(face_no))
436 if ((flags & assemble_boundary_faces) && own_cell)
437 boundary_worker(cell, face_no, scratch,
copy);
443 neighbor = cell->neighbor_or_periodic_neighbor(face_no);
447 if (neighbor->is_level_cell())
448 neighbor_subdomain_id = neighbor->level_subdomain_id();
450 else if (neighbor->is_active())
451 neighbor_subdomain_id = neighbor->subdomain_id();
453 const bool own_neighbor =
455 (neighbor_subdomain_id ==
456 cell->get_triangulation().locally_owned_subdomain());
459 if (!own_cell && !own_neighbor)
463 if (own_cell && own_neighbor &&
469 if (own_cell != own_neighbor &&
477 const bool periodic_neighbor =
478 cell->has_periodic_neighbor(face_no);
480 if (dim > 1 && ((!periodic_neighbor &&
481 cell->neighbor_is_coarser(face_no) &&
482 neighbor->is_active()) ||
483 (periodic_neighbor &&
484 cell->periodic_neighbor_is_coarser(face_no) &&
485 neighbor->is_active())))
494 const std::pair<unsigned int, unsigned int>
497 cell->periodic_neighbor_of_coarser_periodic_neighbor(
499 cell->neighbor_of_coarser_neighbor(face_no);
505 neighbor_face_no.first,
506 neighbor_face_no.second,
516 face_worker(neighbor,
517 neighbor_face_no.first,
518 neighbor_face_no.second,
526 else if (dim == 1 && cell->level() > neighbor->level())
529 const unsigned int neighbor_face_no =
531 cell->periodic_neighbor_face_no(face_no) :
532 cell->neighbor_face_no(face_no);
533 Assert(periodic_neighbor ||
534 neighbor->face(neighbor_face_no) ==
551 face_worker(neighbor,
566 neighbor->has_children())
571 Assert(!cell->neighbor_is_coarser(face_no),
577 if (own_cell && own_neighbor &&
590 if (own_cell && !own_neighbor &&
592 (neighbor_subdomain_id < current_subdomain_id))
595 const unsigned int neighbor_face_no =
597 cell->periodic_neighbor_face_no(face_no) :
598 cell->neighbor_face_no(face_no);
599 Assert(periodic_neighbor ||
600 neighbor->face(neighbor_face_no) ==
617 if ((flags & cells_after_faces) &&
620 cell_worker(cell, scratch,
copy);
703 template <
class CellIteratorType,
706 class CellIteratorBaseType =
711 const typename identity<std::function<
712 void(
const CellIteratorBaseType &, ScratchData &, CopyData &)>>::
type 714 const typename identity<std::function<
void(
const CopyData &)>>::
type 717 const ScratchData &sample_scratch_data,
718 const CopyData & sample_copy_data,
722 const typename identity<std::function<
void(
const CellIteratorBaseType &,
726 &boundary_worker = std::function<
void(
const CellIteratorBaseType &,
731 const typename identity<std::function<
void(
const CellIteratorBaseType &,
734 const CellIteratorBaseType &,
739 &face_worker = std::function<
void(
const CellIteratorBaseType &,
742 const CellIteratorBaseType &,
752 mesh_loop<typename IteratorRange<CellIteratorType>::IteratorOverIterators,
755 CellIteratorBaseType>(iterator_range.
begin(),
756 iterator_range.
end(),
827 template <
class CellIteratorType,
834 MainClass & main_class,
835 void (MainClass::*cell_worker)(
const CellIteratorType &,
838 void (MainClass::*copier)(
const CopyData &),
839 const ScratchData & sample_scratch_data,
840 const CopyData & sample_copy_data,
842 void (MainClass::*boundary_worker)(
const CellIteratorType &,
845 CopyData &) =
nullptr,
846 void (MainClass::*face_worker)(
const CellIteratorType &,
849 const CellIteratorType &,
853 CopyData &) =
nullptr,
857 std::function<void(const CellIteratorType &, ScratchData &, CopyData &)>
861 const CellIteratorType &,
const unsigned int, ScratchData &, CopyData &)>
864 std::function<void(
const CellIteratorType &,
867 const CellIteratorType &,
874 if (cell_worker !=
nullptr)
875 f_cell_worker = [&main_class,
876 cell_worker](
const CellIteratorType &cell_iterator,
877 ScratchData & scratch_data,
878 CopyData & copy_data) {
879 (main_class.*cell_worker)(cell_iterator, scratch_data, copy_data);
882 if (boundary_worker !=
nullptr)
884 [&main_class, boundary_worker](
const CellIteratorType &cell_iterator,
885 const unsigned int face_no,
886 ScratchData & scratch_data,
887 CopyData & copy_data) {
889 boundary_worker)(cell_iterator, face_no, scratch_data, copy_data);
892 if (face_worker !=
nullptr)
893 f_face_worker = [&main_class,
894 face_worker](
const CellIteratorType &cell_iterator_1,
895 const unsigned int face_index_1,
896 const unsigned int subface_index_1,
897 const CellIteratorType &cell_iterator_2,
898 const unsigned int face_index_2,
899 const unsigned int subface_index_2,
900 ScratchData & scratch_data,
901 CopyData & copy_data) {
902 (main_class.*face_worker)(cell_iterator_1,
915 [&main_class, copier](
const CopyData ©_data) {
916 (main_class.*copier)(copy_data);
1006 template <
class CellIteratorType,
1010 class CellIteratorBaseType =
1014 MainClass & main_class,
1015 void (MainClass::*cell_worker)(
const CellIteratorBaseType &,
1018 void (MainClass::*copier)(
const CopyData &),
1019 const ScratchData & sample_scratch_data,
1020 const CopyData & sample_copy_data,
1022 void (MainClass::*boundary_worker)(
const CellIteratorBaseType &,
1025 CopyData &) =
nullptr,
1026 void (MainClass::*face_worker)(
const CellIteratorBaseType &,
1029 const CellIteratorBaseType &,
1033 CopyData &) =
nullptr,
1038 mesh_loop<typename IteratorRange<CellIteratorType>::IteratorOverIterators,
1042 CellIteratorBaseType>(iterator_range.
begin(),
1043 iterator_range.
end(),
1047 sample_scratch_data,
static const unsigned int invalid_unsigned_int
IteratorOverIterators begin()
const types::subdomain_id invalid_subdomain_id
typename CellIteratorBaseType< CellIteratorType >::type type
std::function< void(const CopyData &)> CopierFunctionType
std::function< void(const CellIteratorBaseType &, const unsigned int, ScratchData &, CopyData &)> BoundaryWorkerFunctionType
void mesh_loop(const CellIteratorType &begin, const CellIteratorType &end, const CellWorkerFunctionType &cell_worker, const CopierType &copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const AssembleFlags flags=assemble_own_cells, const BoundaryWorkerFunctionType &boundary_worker=BoundaryWorkerFunctionType(), const FaceWorkerFunctionType &face_worker=FaceWorkerFunctionType(), const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
typename CellIteratorBaseType< CellIteratorType >::type type
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
std::function< void(const CellIteratorBaseType &, const unsigned int, const unsigned int, const CellIteratorBaseType &, const unsigned int, const unsigned int, ScratchData &, CopyData &)> FaceWorkerFunctionType
bool is_active_iterator(const DI &)
#define DEAL_II_NAMESPACE_CLOSE
VectorType::value_type * end(VectorType &V)
std::function< void(const CellIteratorBaseType &, ScratchData &, CopyData &)> CellWorkerFunctionType
const types::subdomain_id artificial_subdomain_id
#define DEAL_II_NAMESPACE_OPEN
VectorType::value_type * begin(VectorType &V)
void run(const std::vector< std::vector< Iterator >> &colored_iterators, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
static unsigned int n_threads()
void copy(const T *begin, const T *end, U *dest)
void cell_action(ITERATOR cell, DoFInfoBox< dim, DOFINFO > &dof_info, INFOBOX &info, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, const LoopControl &loop_control)
static ::ExceptionBase & ExcInternalError()
IteratorOverIterators end() const