17 #ifndef dealii_mesh_worker_mesh_loop_h 18 #define dealii_mesh_worker_mesh_loop_h 35 #include <type_traits> 53 template <
class CellIteratorType>
59 using type = CellIteratorType;
69 template <
class CellIteratorType>
89 template <
class CellIteratorType>
231 template <
class CellIteratorType,
238 const CellIteratorType &
begin,
241 const typename identity<std::function<
242 void(
const CellIteratorBaseType &, ScratchData &, CopyData &)>>::
type 244 const typename identity<std::function<
void(
const CopyData &)>>::
type 247 const ScratchData &sample_scratch_data,
248 const CopyData & sample_copy_data,
252 const typename identity<std::function<
void(
const CellIteratorBaseType &,
256 &boundary_worker = std::function<
void(
const CellIteratorBaseType &,
261 const typename identity<std::function<
void(
const CellIteratorBaseType &,
264 const CellIteratorBaseType &,
269 &face_worker = std::function<
void(
const CellIteratorBaseType &,
272 const CellIteratorBaseType &,
284 "If you specify a cell_worker, you need to set assemble_own_cells or assemble_ghost_cells."));
291 "You can only specify assemble_own_interior_faces_once OR assemble_own_interior_faces_both."));
297 "You can only specify assemble_ghost_faces_once OR assemble_ghost_faces_both."));
303 "The option cells_after_faces only makes sense if you assemble on cells."));
307 "If you specify a face_worker, assemble_face_* needs to be set."));
312 "If you specify a boundary_worker, assemble_boundary_faces needs to be set."));
314 auto cell_action = [&](
const CellIteratorBaseType &cell,
315 ScratchData & scratch,
319 copy = sample_copy_data;
321 const bool ignore_subdomain =
322 (cell->get_triangulation().locally_owned_subdomain() ==
326 (cell->is_level_cell() ? cell->level_subdomain_id() :
327 cell->subdomain_id());
329 const bool own_cell =
331 (current_subdomain_id ==
332 cell->get_triangulation().locally_owned_subdomain());
334 if ((!ignore_subdomain) &&
338 if (!(flags & (cells_after_faces)) &&
341 cell_worker(cell, scratch,
copy);
344 for (
const unsigned int face_no :
345 GeometryInfo<CellIteratorBaseType::AccessorType::Container::
346 dimension>::face_indices())
348 if (cell->at_boundary(face_no) &&
349 !cell->has_periodic_neighbor(face_no))
352 if ((flags & assemble_boundary_faces) && own_cell)
353 boundary_worker(cell, face_no, scratch,
copy);
359 neighbor = cell->neighbor_or_periodic_neighbor(face_no);
363 if (neighbor->is_level_cell())
364 neighbor_subdomain_id = neighbor->level_subdomain_id();
366 else if (neighbor->is_active())
367 neighbor_subdomain_id = neighbor->subdomain_id();
369 const bool own_neighbor =
371 (neighbor_subdomain_id ==
372 cell->get_triangulation().locally_owned_subdomain());
375 if (!own_cell && !own_neighbor)
379 if (own_cell && own_neighbor &&
385 if (own_cell != own_neighbor &&
393 const bool periodic_neighbor =
394 cell->has_periodic_neighbor(face_no);
396 if ((!periodic_neighbor &&
397 cell->neighbor_is_coarser(face_no)) ||
398 (periodic_neighbor &&
399 cell->periodic_neighbor_is_coarser(face_no)))
409 const std::pair<unsigned int, unsigned int>
412 cell->periodic_neighbor_of_coarser_periodic_neighbor(
414 cell->neighbor_of_coarser_neighbor(face_no);
420 neighbor_face_no.first,
421 neighbor_face_no.second,
431 face_worker(neighbor,
432 neighbor_face_no.first,
433 neighbor_face_no.second,
446 neighbor->has_children())
450 Assert(cell->level() == neighbor->level(),
456 if (own_cell && own_neighbor &&
469 if (own_cell && !own_neighbor &&
471 (neighbor_subdomain_id < current_subdomain_id))
474 const unsigned int neighbor_face_no =
476 cell->periodic_neighbor_face_no(face_no) :
477 cell->neighbor_face_no(face_no);
478 Assert(periodic_neighbor ||
479 neighbor->face(neighbor_face_no) ==
496 if ((flags & cells_after_faces) &&
499 cell_worker(cell, scratch,
copy);
582 template <
class CellIteratorType,
585 class CellIteratorBaseType =
590 const typename identity<std::function<
591 void(
const CellIteratorBaseType &, ScratchData &, CopyData &)>>::
type 593 const typename identity<std::function<
void(
const CopyData &)>>::
type 596 const ScratchData &sample_scratch_data,
597 const CopyData & sample_copy_data,
601 const typename identity<std::function<
void(
const CellIteratorBaseType &,
605 &boundary_worker = std::function<
void(
const CellIteratorBaseType &,
610 const typename identity<std::function<
void(
const CellIteratorBaseType &,
613 const CellIteratorBaseType &,
618 &face_worker = std::function<
void(
const CellIteratorBaseType &,
621 const CellIteratorBaseType &,
631 mesh_loop<typename IteratorRange<CellIteratorType>::IteratorOverIterators,
634 CellIteratorBaseType>(iterator_range.
begin(),
635 iterator_range.
end(),
707 template <
class CellIteratorType,
714 MainClass & main_class,
715 void (MainClass::*cell_worker)(
const CellIteratorType &,
718 void (MainClass::*copier)(
const CopyData &),
719 const ScratchData & sample_scratch_data,
720 const CopyData & sample_copy_data,
722 void (MainClass::*boundary_worker)(
const CellIteratorType &,
725 CopyData &) =
nullptr,
726 void (MainClass::*face_worker)(
const CellIteratorType &,
729 const CellIteratorType &,
733 CopyData &) =
nullptr,
737 std::function<void(const CellIteratorType &, ScratchData &, CopyData &)>
741 const CellIteratorType &,
const unsigned int, ScratchData &, CopyData &)>
744 std::function<void(
const CellIteratorType &,
747 const CellIteratorType &,
754 if (cell_worker !=
nullptr)
755 f_cell_worker = [&main_class,
756 cell_worker](
const CellIteratorType &cell_iterator,
757 ScratchData & scratch_data,
758 CopyData & copy_data) {
759 (main_class.*cell_worker)(cell_iterator, scratch_data, copy_data);
762 if (boundary_worker !=
nullptr)
764 [&main_class, boundary_worker](
const CellIteratorType &cell_iterator,
765 const unsigned int face_no,
766 ScratchData & scratch_data,
767 CopyData & copy_data) {
769 boundary_worker)(cell_iterator, face_no, scratch_data, copy_data);
772 if (face_worker !=
nullptr)
773 f_face_worker = [&main_class,
774 face_worker](
const CellIteratorType &cell_iterator_1,
775 const unsigned int face_index_1,
776 const unsigned int subface_index_1,
777 const CellIteratorType &cell_iterator_2,
778 const unsigned int face_index_2,
779 const unsigned int subface_index_2,
780 ScratchData & scratch_data,
781 CopyData & copy_data) {
782 (main_class.*face_worker)(cell_iterator_1,
795 [&main_class, copier](
const CopyData ©_data) {
796 (main_class.*copier)(copy_data);
886 template <
class CellIteratorType,
890 class CellIteratorBaseType =
894 MainClass & main_class,
895 void (MainClass::*cell_worker)(
const CellIteratorBaseType &,
898 void (MainClass::*copier)(
const CopyData &),
899 const ScratchData & sample_scratch_data,
900 const CopyData & sample_copy_data,
902 void (MainClass::*boundary_worker)(
const CellIteratorBaseType &,
905 CopyData &) =
nullptr,
906 void (MainClass::*face_worker)(
const CellIteratorBaseType &,
909 const CellIteratorBaseType &,
913 CopyData &) =
nullptr,
918 mesh_loop<typename IteratorRange<CellIteratorType>::IteratorOverIterators,
922 CellIteratorBaseType>(iterator_range.
begin(),
923 iterator_range.
end(),
static const unsigned int invalid_unsigned_int
IteratorOverIterators begin()
const types::subdomain_id invalid_subdomain_id
typename CellIteratorBaseType< CellIteratorType >::type type
void mesh_loop(const CellIteratorType &begin, const typename identity< CellIteratorType >::type &end, const typename identity< std::function< void(const CellIteratorBaseType &, ScratchData &, CopyData &)>>::type &cell_worker, const typename identity< std::function< void(const CopyData &)>>::type &copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const AssembleFlags flags=assemble_own_cells, const typename identity< std::function< void(const CellIteratorBaseType &, const unsigned int, ScratchData &, CopyData &)>>::type &boundary_worker=std::function< void(const CellIteratorBaseType &, const unsigned int, ScratchData &, CopyData &)>(), const typename identity< std::function< void(const CellIteratorBaseType &, const unsigned int, const unsigned int, const CellIteratorBaseType &, const unsigned int, const unsigned int, ScratchData &, CopyData &)>>::type &face_worker=std::function< void(const CellIteratorBaseType &, const unsigned int, const unsigned int, const CellIteratorBaseType &, const unsigned int, const unsigned int, ScratchData &, CopyData &)>(), 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)
bool is_active_iterator(const DI &)
#define DEAL_II_NAMESPACE_CLOSE
VectorType::value_type * end(VectorType &V)
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