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)
680 std::function<void(const CellIteratorType &, ScratchData &, CopyData &)>
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
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)
unsigned int subdomain_id
#define Assert(cond, exc)
bool is_active_iterator(const DI &)
const types::subdomain_id artificial_subdomain_id
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 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