17 #ifndef dealii_mesh_worker_mesh_loop_h
18 #define dealii_mesh_worker_mesh_loop_h
20 #include <deal.II/base/config.h>
22 #include <deal.II/base/template_constraints.h>
23 #include <deal.II/base/work_stream.h>
25 #include <deal.II/grid/filtered_iterator.h>
26 #include <deal.II/grid/tria.h>
28 #include <deal.II/meshworker/assemble_flags.h>
29 #include <deal.II/meshworker/dof_info.h>
30 #include <deal.II/meshworker/integration_info.h>
31 #include <deal.II/meshworker/local_integrator.h>
32 #include <deal.II/meshworker/loop.h>
35 #include <type_traits>
37 DEAL_II_NAMESPACE_OPEN
50 template <
class CellIteratorType>
56 using type = CellIteratorType;
66 template <
class CellIteratorType>
86 template <
class CellIteratorType>
173 template <
class CellIteratorType,
176 class CellIteratorBaseType =
180 const CellIteratorType & begin,
181 const typename identity<CellIteratorType>::type &end,
183 const typename identity<std::function<
194 const typename identity<std::function<
void(
const CellIteratorBaseType &,
198 &boundary_worker = std::function<
void(
const CellIteratorBaseType &,
203 const typename identity<std::function<
void(
const CellIteratorBaseType &,
206 const CellIteratorBaseType &,
211 &face_worker = std::function<
void(
const CellIteratorBaseType &,
214 const CellIteratorBaseType &,
221 const unsigned int chunk_size = 8)
226 "If you specify a cell_worker, you need to set assemble_own_cells or assemble_ghost_cells."));
233 "You can only specify assemble_own_interior_faces_once OR assemble_own_interior_faces_both."));
239 "You can only specify assemble_ghost_faces_once OR assemble_ghost_faces_both."));
245 "The option cells_after_faces only makes sense if you assemble on cells."));
249 "If you specify a face_worker, assemble_face_* needs to be set."));
254 "If you specify a boundary_worker, assemble_boundary_faces needs to be set."));
256 auto cell_action = [&](
const CellIteratorBaseType &cell,
261 copy = sample_copy_data;
263 const bool ignore_subdomain =
264 (cell->get_triangulation().locally_owned_subdomain() ==
268 (cell->is_level_cell() ? cell->level_subdomain_id() :
269 cell->subdomain_id());
271 const bool own_cell =
273 (current_subdomain_id ==
274 cell->get_triangulation().locally_owned_subdomain());
276 if ((!ignore_subdomain) &&
283 cell_worker(cell, scratch, copy);
286 for (
unsigned int face_no = 0;
287 face_no <
GeometryInfo<CellIteratorBaseType::AccessorType::
288 Container::dimension>::faces_per_cell;
291 if (cell->at_boundary(face_no) &&
292 !cell->has_periodic_neighbor(face_no))
296 boundary_worker(cell, face_no, scratch, copy);
302 neighbor = cell->neighbor_or_periodic_neighbor(face_no);
306 if (neighbor->is_level_cell())
307 neighbor_subdomain_id = neighbor->level_subdomain_id();
309 else if (neighbor->active())
310 neighbor_subdomain_id = neighbor->subdomain_id();
312 const bool own_neighbor =
314 (neighbor_subdomain_id ==
315 cell->get_triangulation().locally_owned_subdomain());
318 if (!own_cell && !own_neighbor)
322 if (own_cell && own_neighbor &&
328 if (own_cell != own_neighbor &&
336 const bool periodic_neighbor =
337 cell->has_periodic_neighbor(face_no);
339 if ((!periodic_neighbor &&
340 cell->neighbor_is_coarser(face_no)) ||
341 (periodic_neighbor &&
342 cell->periodic_neighbor_is_coarser(face_no)))
352 const std::pair<unsigned int, unsigned int>
355 cell->periodic_neighbor_of_coarser_periodic_neighbor(
357 cell->neighbor_of_coarser_neighbor(face_no);
363 neighbor_face_no.first,
364 neighbor_face_no.second,
374 face_worker(neighbor,
375 neighbor_face_no.first,
376 neighbor_face_no.second,
389 neighbor->has_children())
393 Assert(cell->level() == neighbor->level(),
399 if (own_cell && own_neighbor &&
412 if (own_cell && !own_neighbor &&
414 (neighbor_subdomain_id < current_subdomain_id))
417 const unsigned int neighbor_face_no =
419 cell->periodic_neighbor_face_no(face_no) :
420 cell->neighbor_face_no(face_no);
421 Assert(periodic_neighbor ||
422 neighbor->face(neighbor_face_no) ==
442 cell_worker(cell, scratch, copy);
525 template <
class CellIteratorType,
528 class CellIteratorBaseType =
533 const typename identity<std::function<
544 const typename identity<std::function<
void(
const CellIteratorBaseType &,
548 &boundary_worker = std::function<
void(
const CellIteratorBaseType &,
553 const typename identity<std::function<
void(
const CellIteratorBaseType &,
556 const CellIteratorBaseType &,
561 &face_worker = std::function<
void(
const CellIteratorBaseType &,
564 const CellIteratorBaseType &,
571 const unsigned int chunk_size = 8)
574 mesh_loop<typename IteratorRange<CellIteratorType>::IteratorOverIterators,
577 CellIteratorBaseType>(iterator_range.
begin(),
578 iterator_range.
end(),
650 template <
class CellIteratorType,
656 const typename identity<CellIteratorType>::type &end,
657 MainClass & main_class,
658 void (MainClass::*cell_worker)(
const CellIteratorType &,
661 void (MainClass::*copier)(
const CopyData &),
665 void (MainClass::*boundary_worker)(
const CellIteratorType &,
669 void (MainClass::*face_worker)(
const CellIteratorType &,
672 const CellIteratorType &,
678 const unsigned int chunk_size = 8)
687 std::function<void(
const CellIteratorType &,
690 const CellIteratorType &,
697 if (cell_worker !=
nullptr)
698 f_cell_worker = std::bind(cell_worker,
699 std::ref(main_class),
700 std::placeholders::_1,
701 std::placeholders::_2,
702 std::placeholders::_3);
704 if (boundary_worker !=
nullptr)
705 f_boundary_worker = std::bind(boundary_worker,
706 std::ref(main_class),
707 std::placeholders::_1,
708 std::placeholders::_2,
709 std::placeholders::_3,
710 std::placeholders::_4);
712 if (face_worker !=
nullptr)
713 f_face_worker = std::bind(face_worker,
714 std::ref(main_class),
715 std::placeholders::_1,
716 std::placeholders::_2,
717 std::placeholders::_3,
718 std::placeholders::_4,
719 std::placeholders::_5,
720 std::placeholders::_6,
721 std::placeholders::_7,
722 std::placeholders::_8);
727 std::bind(copier, main_class, std::placeholders::_1),
816 template <
class CellIteratorType,
820 class CellIteratorBaseType =
824 MainClass & main_class,
825 void (MainClass::*cell_worker)(
const CellIteratorBaseType &,
828 void (MainClass::*copier)(
const CopyData &),
832 void (MainClass::*boundary_worker)(
const CellIteratorBaseType &,
836 void (MainClass::*face_worker)(
const CellIteratorBaseType &,
839 const CellIteratorBaseType &,
845 const unsigned int chunk_size = 8)
848 mesh_loop<typename IteratorRange<CellIteratorType>::IteratorOverIterators,
852 CellIteratorBaseType>(iterator_range.
begin(),
853 iterator_range.
end(),
867 DEAL_II_NAMESPACE_CLOSE