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,
234 class CellIteratorBaseType =
238 const CellIteratorType &
begin,
241 const typename identity<std::function<
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,
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) &&
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))
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) ==
499 cell_worker(cell, scratch,
copy);
582 template <
class CellIteratorType,
585 class CellIteratorBaseType =
590 const typename identity<std::function<
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 &),
722 void (MainClass::*boundary_worker)(
const CellIteratorType &,
726 void (MainClass::*face_worker)(
const CellIteratorType &,
729 const CellIteratorType &,
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,
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,
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,
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 &),
902 void (MainClass::*boundary_worker)(
const CellIteratorBaseType &,
906 void (MainClass::*face_worker)(
const CellIteratorBaseType &,
909 const CellIteratorBaseType &,
918 mesh_loop<typename IteratorRange<CellIteratorType>::IteratorOverIterators,
922 CellIteratorBaseType>(iterator_range.
begin(),
923 iterator_range.
end(),