17 #ifndef dealii_face_setup_internal_h 18 #define dealii_face_setup_internal_h 20 #include <deal.II/base/memory_consumption.h> 21 #include <deal.II/base/utilities.h> 23 #include <deal.II/grid/tria.h> 24 #include <deal.II/grid/tria_accessor.h> 26 #include <deal.II/matrix_free/face_info.h> 27 #include <deal.II/matrix_free/task_info.h> 32 DEAL_II_NAMESPACE_OPEN
37 namespace MatrixFreeFunctions
48 : n_hanging_faces_smaller_subdomain(0)
49 , n_hanging_faces_larger_subdomain(0)
52 std::vector<std::pair<CellId, CellId>> shared_faces;
53 unsigned int n_hanging_faces_smaller_subdomain;
54 unsigned int n_hanging_faces_larger_subdomain;
80 template <
typename MFAddData>
83 const ::Triangulation<dim> & triangulation,
84 const MFAddData & additional_data,
85 std::vector<std::pair<unsigned int, unsigned int>> &cell_levels);
95 const ::Triangulation<dim> & triangulation,
96 const std::vector<std::pair<unsigned int, unsigned int>> &cell_levels,
107 const unsigned int face_no,
108 const typename ::Triangulation<dim>::cell_iterator &cell,
109 const unsigned int number_cell_interior,
110 const typename ::Triangulation<dim>::cell_iterator &neighbor,
111 const unsigned int number_cell_exterior);
113 bool use_active_cells;
121 locally_active_at_boundary,
122 locally_active_done_here,
123 locally_active_done_elsewhere,
125 multigrid_refinement_edge
128 std::vector<FaceCategory> face_is_owned;
129 std::vector<bool> at_processor_boundary;
130 std::vector<unsigned int> cells_close_to_boundary;
131 std::vector<FaceToCellTopology<1>> inner_faces;
132 std::vector<FaceToCellTopology<1>> boundary_faces;
133 std::vector<FaceToCellTopology<1>> inner_ghost_faces;
134 std::vector<FaceToCellTopology<1>> refinement_edge_faces;
142 template <
int vectorization_w
idth>
144 collect_faces_vectorization(
145 const std::vector<FaceToCellTopology<1>> &faces_in,
146 const std::vector<bool> & hard_vectorization_boundary,
147 std::vector<unsigned int> & face_partition_data,
148 std::vector<FaceToCellTopology<vectorization_width>> &faces_out);
157 FaceSetup<dim>::FaceSetup()
158 : use_active_cells(true)
164 template <
typename MFAddData>
167 const ::Triangulation<dim> & triangulation,
168 const MFAddData & additional_data,
169 std::vector<std::pair<unsigned int, unsigned int>> &cell_levels)
176 if (use_active_cells)
177 for (
const auto &cell_level : cell_levels)
179 typename ::Triangulation<dim>::cell_iterator dcell(
180 &triangulation, cell_level.first, cell_level.second);
188 at_processor_boundary.resize(cell_levels.size(),
false);
189 cells_close_to_boundary.clear();
190 face_is_owned.resize(dim > 1 ? triangulation.n_raw_faces() :
191 triangulation.n_vertices(),
192 FaceCategory::locally_active_done_elsewhere);
196 std::map<types::subdomain_id, FaceIdentifier>
197 inner_faces_at_proc_boundary;
201 triangulation.locally_owned_subdomain();
202 for (
unsigned int i = 0; i < cell_levels.size(); ++i)
204 if (i > 0 && cell_levels[i] == cell_levels[i - 1])
206 typename ::Triangulation<dim>::cell_iterator dcell(
207 &triangulation, cell_levels[i].first, cell_levels[i].second);
208 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell;
211 if (dcell->at_boundary(f) && !dcell->has_periodic_neighbor(f))
213 typename ::Triangulation<dim>::cell_iterator neighbor =
214 dcell->neighbor_or_periodic_neighbor(f);
220 const CellId id_mine = dcell->id();
221 if (use_active_cells && neighbor->has_children())
222 for (
unsigned int c = 0; c < dcell->face(f)->n_children();
225 typename ::Triangulation<dim>::cell_iterator
227 dcell->at_boundary(f) ?
228 dcell->periodic_neighbor_child_on_subface(f, c) :
229 dcell->neighbor_child_on_subface(f, c);
231 neighbor_c->subdomain_id();
232 if (my_domain < neigh_domain)
233 inner_faces_at_proc_boundary[neigh_domain]
234 .n_hanging_faces_larger_subdomain++;
235 else if (my_domain > neigh_domain)
236 inner_faces_at_proc_boundary[neigh_domain]
237 .n_hanging_faces_smaller_subdomain++;
242 use_active_cells ? neighbor->subdomain_id() :
243 neighbor->level_subdomain_id();
244 if (neighbor->level() < dcell->level() &&
247 if (my_domain < neigh_domain)
248 inner_faces_at_proc_boundary[neigh_domain]
249 .n_hanging_faces_smaller_subdomain++;
250 else if (my_domain > neigh_domain)
251 inner_faces_at_proc_boundary[neigh_domain]
252 .n_hanging_faces_larger_subdomain++;
254 else if (neighbor->level() == dcell->level() &&
255 my_domain != neigh_domain)
261 const CellId id_neigh = neighbor->id();
262 if (my_domain < neigh_domain)
263 inner_faces_at_proc_boundary[neigh_domain]
264 .shared_faces.emplace_back(id_mine, id_neigh);
266 inner_faces_at_proc_boundary[neigh_domain]
267 .shared_faces.emplace_back(id_neigh, id_mine);
276 for (
auto &inner_face : inner_faces_at_proc_boundary)
278 Assert(inner_face.first != my_domain,
280 std::sort(inner_face.second.shared_faces.begin(),
281 inner_face.second.shared_faces.end());
282 inner_face.second.shared_faces.erase(
283 std::unique(inner_face.second.shared_faces.begin(),
284 inner_face.second.shared_faces.end()),
285 inner_face.second.shared_faces.end());
290 # if defined(DEAL_II_WITH_MPI) && defined(DEBUG) 291 MPI_Comm comm = MPI_COMM_SELF;
295 comm = ptria->get_communicator();
298 unsigned int mysize = inner_face.second.shared_faces.size();
300 MPI_Sendrecv(&mysize,
309 600 + inner_face.first,
313 mysize = inner_face.second.n_hanging_faces_smaller_subdomain;
314 MPI_Sendrecv(&mysize,
323 700 + inner_face.first,
327 mysize = inner_face.second.n_hanging_faces_larger_subdomain;
328 MPI_Sendrecv(&mysize,
337 800 + inner_face.first,
358 std::vector<std::tuple<CellId, CellId, unsigned int>> other_range(
359 inner_face.second.shared_faces.size());
360 for (
unsigned int i = 0; i < other_range.size(); ++i)
362 std::make_tuple(inner_face.second.shared_faces[i].second,
363 inner_face.second.shared_faces[i].first,
365 std::sort(other_range.begin(), other_range.end());
373 unsigned int n_faces_lower_proc = 0, n_faces_higher_proc = 0;
374 std::vector<char> assignment(other_range.size(), 0);
375 if (inner_face.second.shared_faces.size() > 0)
379 unsigned int count = 0;
380 for (
unsigned int i = 1;
381 i < inner_face.second.shared_faces.size();
383 if (inner_face.second.shared_faces[i].first ==
384 inner_face.second.shared_faces[i - 1 - count].first)
391 for (
unsigned int k = 0; k <= count; ++k)
392 assignment[i - 1 - k] = 1;
393 n_faces_higher_proc += count + 1;
403 for (
unsigned int i = 1; i < other_range.size(); ++i)
404 if (std::get<0>(other_range[i]) ==
405 std::get<0>(other_range[i - 1 - count]))
412 for (
unsigned int k = 0; k <= count; ++k)
415 .shared_faces[std::get<2>(
419 .shared_faces[std::get<2>(
420 other_range[i - 1 - k])]
425 if (assignment[std::get<2>(
426 other_range[i - 1 - k])] == 0)
428 assignment[std::get<2>(
429 other_range[i - 1 - k])] = -1;
430 ++n_faces_lower_proc;
444 n_faces_lower_proc +=
445 inner_face.second.n_hanging_faces_smaller_subdomain;
446 n_faces_higher_proc +=
447 inner_face.second.n_hanging_faces_larger_subdomain;
448 const unsigned int n_total_faces_at_proc_boundary =
449 (inner_face.second.shared_faces.size() +
450 inner_face.second.n_hanging_faces_smaller_subdomain +
451 inner_face.second.n_hanging_faces_larger_subdomain);
452 unsigned int split_index = n_total_faces_at_proc_boundary / 2;
453 if (split_index < n_faces_lower_proc)
455 else if (split_index <
456 n_total_faces_at_proc_boundary - n_faces_higher_proc)
457 split_index -= n_faces_lower_proc;
459 split_index = n_total_faces_at_proc_boundary -
460 n_faces_higher_proc - n_faces_lower_proc;
463 # if defined(DEAL_II_WITH_MPI) && defined(DEBUG) 464 MPI_Sendrecv(&split_index,
473 900 + inner_face.first,
477 MPI_Sendrecv(&n_faces_lower_proc,
486 1000 + inner_face.first,
490 MPI_Sendrecv(&n_faces_higher_proc,
499 1100 + inner_face.first,
506 std::vector<std::pair<CellId, CellId>> owned_faces_lower,
508 for (
unsigned int i = 0; i < assignment.size(); ++i)
509 if (assignment[i] < 0)
510 owned_faces_lower.push_back(
511 inner_face.second.shared_faces[i]);
512 else if (assignment[i] > 0)
513 owned_faces_higher.push_back(
514 inner_face.second.shared_faces[i]);
516 inner_face.second.shared_faces.size() + 1 -
517 owned_faces_lower.size() -
518 owned_faces_higher.size());
520 unsigned int i = 0, c = 0;
521 for (; i < assignment.size() && c < split_index; ++i)
522 if (assignment[i] == 0)
524 owned_faces_lower.push_back(
525 inner_face.second.shared_faces[i]);
528 for (; i < assignment.size(); ++i)
529 if (assignment[i] == 0)
531 owned_faces_higher.push_back(
532 inner_face.second.shared_faces[i]);
537 std::vector<std::pair<CellId, CellId>> check_faces;
538 check_faces.insert(check_faces.end(),
539 owned_faces_lower.begin(),
540 owned_faces_lower.end());
541 check_faces.insert(check_faces.end(),
542 owned_faces_higher.begin(),
543 owned_faces_higher.end());
544 std::sort(check_faces.begin(), check_faces.end());
546 inner_face.second.shared_faces.size());
547 for (
unsigned int i = 0; i < check_faces.size(); ++i)
548 Assert(check_faces[i] == inner_face.second.shared_faces[i],
553 if (my_domain < inner_face.first)
554 inner_face.second.shared_faces.swap(owned_faces_lower);
556 inner_face.second.shared_faces.swap(owned_faces_higher);
558 std::sort(inner_face.second.shared_faces.begin(),
559 inner_face.second.shared_faces.end());
565 std::set<std::pair<unsigned int, unsigned int>> ghost_cells;
566 for (
unsigned int i = 0; i < cell_levels.size(); ++i)
568 typename ::Triangulation<dim>::cell_iterator dcell(
569 &triangulation, cell_levels[i].first, cell_levels[i].second);
570 if (use_active_cells)
572 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
574 if (dcell->at_boundary(f) && !dcell->has_periodic_neighbor(f))
575 face_is_owned[dcell->face(f)->index()] =
576 FaceCategory::locally_active_at_boundary;
580 else if ((dcell->at_boundary(f) ==
false ||
581 dcell->has_periodic_neighbor(f)) &&
582 additional_data.level_mg_handler !=
584 dcell->neighbor_or_periodic_neighbor(f)->level() <
587 face_is_owned[dcell->face(f)->index()] =
588 FaceCategory::multigrid_refinement_edge;
592 typename ::Triangulation<dim>::cell_iterator neighbor =
593 dcell->neighbor_or_periodic_neighbor(f);
596 if (use_active_cells && neighbor->has_children() &&
597 additional_data.hold_all_faces_to_owned_cells ==
false)
600 bool add_to_ghost =
false;
602 id1 = use_active_cells ? dcell->subdomain_id() :
603 dcell->level_subdomain_id(),
604 id2 = use_active_cells ?
605 (neighbor->has_children() ?
606 dcell->neighbor_child_on_subface(f, 0)
608 neighbor->subdomain_id()) :
609 neighbor->level_subdomain_id();
616 if ((id1 == id2 && (use_active_cells ==
false ||
617 neighbor->has_children() ==
false)) ||
618 dcell->level() > neighbor->level() ||
620 inner_faces_at_proc_boundary[id2].shared_faces.begin(),
621 inner_faces_at_proc_boundary[id2].shared_faces.end(),
622 std::make_pair(id1 < id2 ? dcell->
id() : neighbor->id(),
623 id1 < id2 ? neighbor->id() :
626 face_is_owned[dcell->face(f)->index()] =
627 FaceCategory::locally_active_done_here;
628 if (dcell->level() == neighbor->level())
631 ->face(dcell->has_periodic_neighbor(f) ?
632 dcell->periodic_neighbor_face_no(f) :
633 dcell->neighbor_face_no(f))
635 FaceCategory::locally_active_done_here;
641 if (use_active_cells)
643 (dcell->subdomain_id() != neighbor->subdomain_id());
645 add_to_ghost = (dcell->level_subdomain_id() !=
646 neighbor->level_subdomain_id());
648 else if (additional_data.hold_all_faces_to_owned_cells ==
652 cells_close_to_boundary.emplace_back(i);
657 face_is_owned[dcell->face(f)->index()] =
658 FaceCategory::ghosted;
659 if (use_active_cells)
661 if (neighbor->has_children())
662 for (
unsigned int s = 0;
663 s < dcell->face(f)->n_children();
665 if (dcell->at_boundary(f))
668 ->periodic_neighbor_child_on_subface(f,
671 dcell->subdomain_id())
676 if (dcell->neighbor_child_on_subface(f, s)
678 dcell->subdomain_id())
682 add_to_ghost = (dcell->subdomain_id() !=
683 neighbor->subdomain_id());
686 add_to_ghost = (dcell->level_subdomain_id() !=
687 neighbor->level_subdomain_id());
692 if (use_active_cells && neighbor->has_children())
693 for (
unsigned int s = 0;
694 s < dcell->face(f)->n_children();
697 typename ::Triangulation<dim>::cell_iterator
699 dcell->at_boundary(f) ?
700 dcell->periodic_neighbor_child_on_subface(f,
702 dcell->neighbor_child_on_subface(f, s);
703 if (neighbor_child->subdomain_id() !=
704 dcell->subdomain_id())
706 std::pair<unsigned int, unsigned int>(
707 neighbor_child->level(),
708 neighbor_child->index()));
712 std::pair<unsigned int, unsigned int>(
713 neighbor->level(), neighbor->index()));
714 at_processor_boundary[i] =
true;
722 for (
const auto &ghost_cell : ghost_cells)
723 cell_levels.push_back(ghost_cell);
726 std::sort(cells_close_to_boundary.begin(), cells_close_to_boundary.end());
727 cells_close_to_boundary.erase(std::unique(cells_close_to_boundary.begin(),
728 cells_close_to_boundary.end()),
729 cells_close_to_boundary.end());
730 std::vector<unsigned int> final_cells;
731 final_cells.reserve(cells_close_to_boundary.size());
732 for (
unsigned int i = 0; i < cells_close_to_boundary.size(); ++i)
733 if (at_processor_boundary[cells_close_to_boundary[i]] ==
false)
734 final_cells.push_back(cells_close_to_boundary[i]);
735 cells_close_to_boundary = std::move(final_cells);
743 const ::Triangulation<dim> & triangulation,
744 const std::vector<std::pair<unsigned int, unsigned int>> &cell_levels,
745 TaskInfo & task_info)
749 std::map<std::pair<unsigned int, unsigned int>,
unsigned int>
751 for (
unsigned int cell = 0; cell < cell_levels.size(); ++cell)
752 if (cell == 0 || cell_levels[cell] != cell_levels[cell - 1])
754 typename ::Triangulation<dim>::cell_iterator dcell(
756 cell_levels[cell].first,
757 cell_levels[cell].second);
758 std::pair<unsigned int, unsigned int> level_index(dcell->level(),
760 map_to_vectorized[level_index] = cell;
764 const unsigned int vectorization_length = task_info.vectorization_length;
765 task_info.face_partition_data.resize(
766 task_info.cell_partition_data.size() - 1, 0);
767 task_info.boundary_partition_data.resize(
768 task_info.cell_partition_data.size() - 1, 0);
769 std::vector<unsigned char> face_visited(face_is_owned.size(), 0);
770 for (
unsigned int partition = 0;
771 partition < task_info.cell_partition_data.size() - 2;
774 unsigned int boundary_counter = 0;
775 unsigned int inner_counter = 0;
776 for (
unsigned int cell = task_info.cell_partition_data[partition] *
777 vectorization_length;
778 cell < task_info.cell_partition_data[partition + 1] *
779 vectorization_length;
781 if (cell == 0 || cell_levels[cell] != cell_levels[cell - 1])
783 typename ::Triangulation<dim>::cell_iterator dcell(
785 cell_levels[cell].first,
786 cell_levels[cell].second);
787 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell;
791 if (face_is_owned[dcell->face(f)->index()] ==
792 FaceCategory::locally_active_at_boundary)
796 FaceToCellTopology<1> info;
797 info.cells_interior[0] = cell;
799 info.interior_face_no = f;
800 info.exterior_face_no = dcell->face(f)->boundary_id();
803 info.face_orientation = 0;
804 boundary_faces.push_back(info);
806 face_visited[dcell->face(f)->index()]++;
811 typename ::Triangulation<dim>::cell_iterator
812 neighbor = dcell->neighbor_or_periodic_neighbor(f);
813 if (use_active_cells && neighbor->has_children())
815 for (
unsigned int c = 0;
816 c < dcell->face(f)->n_children();
819 typename ::Triangulation<
820 dim>::cell_iterator neighbor_c =
821 dcell->at_boundary(f) ?
822 dcell->periodic_neighbor_child_on_subface(
824 dcell->neighbor_child_on_subface(f, c);
826 neighbor_c->subdomain_id();
827 const unsigned int neighbor_face_no =
828 dcell->has_periodic_neighbor(f) ?
829 dcell->periodic_neighbor_face_no(f) :
830 dcell->neighbor_face_no(f);
831 if (neigh_domain != dcell->subdomain_id() ||
833 [dcell->face(f)->child(c)->index()] ==
836 std::pair<unsigned int, unsigned int>
837 level_index(neighbor_c->level(),
838 neighbor_c->index());
840 [dcell->face(f)->child(c)->index()] ==
841 FaceCategory::locally_active_done_here)
844 inner_faces.push_back(create_face(
847 map_to_vectorized[level_index],
851 else if (face_is_owned[dcell->face(f)
854 FaceCategory::ghosted)
856 inner_ghost_faces.push_back(create_face(
859 map_to_vectorized[level_index],
865 face_is_owned[dcell->face(f)
868 locally_active_done_elsewhere ||
869 face_is_owned[dcell->face(f)
871 FaceCategory::ghosted,
877 [dcell->face(f)->child(c)->index()] = 1;
884 use_active_cells ? dcell->subdomain_id() :
885 dcell->level_subdomain_id();
887 use_active_cells ? neighbor->subdomain_id() :
888 neighbor->level_subdomain_id();
889 if (neigh_domain != my_domain ||
890 face_visited[dcell->face(f)->index()] == 1)
892 std::pair<unsigned int, unsigned int>
893 level_index(neighbor->level(),
895 if (face_is_owned[dcell->face(f)->index()] ==
896 FaceCategory::locally_active_done_here)
899 inner_faces.push_back(create_face(
904 map_to_vectorized[level_index]));
906 else if (face_is_owned[dcell->face(f)
908 FaceCategory::ghosted)
910 inner_ghost_faces.push_back(create_face(
915 map_to_vectorized[level_index]));
920 face_visited[dcell->face(f)->index()] = 1;
921 if (dcell->has_periodic_neighbor(f))
925 dcell->periodic_neighbor_face_no(f))
928 if (face_is_owned[dcell->face(f)->index()] ==
929 FaceCategory::multigrid_refinement_edge)
931 refinement_edge_faces.push_back(
936 refinement_edge_faces.size()));
942 task_info.face_partition_data[
partition + 1] =
943 task_info.face_partition_data[
partition] + inner_counter;
944 task_info.boundary_partition_data[
partition + 1] =
945 task_info.boundary_partition_data[
partition] + boundary_counter;
947 task_info.ghost_face_partition_data.resize(2);
948 task_info.ghost_face_partition_data[0] = 0;
949 task_info.ghost_face_partition_data[1] = inner_ghost_faces.size();
950 task_info.refinement_edge_face_partition_data.resize(2);
951 task_info.refinement_edge_face_partition_data[0] = 0;
952 task_info.refinement_edge_face_partition_data[1] =
953 refinement_edge_faces.size();
959 FaceToCellTopology<1>
961 const unsigned int face_no,
962 const typename ::Triangulation<dim>::cell_iterator &cell,
963 const unsigned int number_cell_interior,
964 const typename ::Triangulation<dim>::cell_iterator &neighbor,
965 const unsigned int number_cell_exterior)
967 FaceToCellTopology<1> info;
969 info.cells_exterior[0] = number_cell_exterior;
970 info.interior_face_no = face_no;
971 if (cell->has_periodic_neighbor(face_no))
972 info.exterior_face_no = cell->periodic_neighbor_face_no(face_no);
974 info.exterior_face_no = cell->neighbor_face_no(face_no);
978 if (cell->level() > neighbor->level())
980 if (cell->has_periodic_neighbor(face_no))
982 cell->periodic_neighbor_of_coarser_periodic_neighbor(face_no)
986 cell->neighbor_of_coarser_neighbor(face_no).second;
989 info.face_orientation = 0;
990 const unsigned int left_face_orientation =
991 !cell->face_orientation(face_no) + 2 * cell->face_flip(face_no) +
992 4 * cell->face_rotation(face_no);
993 const unsigned int right_face_orientation =
994 !neighbor->face_orientation(info.exterior_face_no) +
995 2 * neighbor->face_flip(info.exterior_face_no) +
996 4 * neighbor->face_rotation(info.exterior_face_no);
997 if (left_face_orientation != 0)
999 info.face_orientation = 8 + left_face_orientation;
1000 Assert(right_face_orientation == 0,
1002 "Face seems to be wrongly oriented from both sides"));
1005 info.face_orientation = right_face_orientation;
1018 compare_faces_for_vectorization(
const FaceToCellTopology<1> &face1,
1019 const FaceToCellTopology<1> &face2)
1021 if (face1.interior_face_no != face2.interior_face_no)
1023 if (face1.exterior_face_no != face2.exterior_face_no)
1025 if (face1.subface_index != face2.subface_index)
1027 if (face1.face_orientation != face2.face_orientation)
1040 template <
int length>
1041 struct FaceComparator
1044 operator()(
const FaceToCellTopology<length> &face1,
1045 const FaceToCellTopology<length> &face2)
const 1047 for (
unsigned int i = 0; i < length; ++i)
1048 if (face1.cells_interior[i] < face2.cells_interior[i])
1050 else if (face1.cells_interior[i] > face2.cells_interior[i])
1052 for (
unsigned int i = 0; i < length; ++i)
1053 if (face1.cells_exterior[i] < face2.cells_exterior[i])
1055 else if (face1.cells_exterior[i] > face2.cells_exterior[i])
1057 if (face1.interior_face_no < face2.interior_face_no)
1059 else if (face1.interior_face_no > face2.interior_face_no)
1061 if (face1.exterior_face_no < face2.exterior_face_no)
1063 else if (face1.exterior_face_no > face2.exterior_face_no)
1078 template <
int vectorization_w
idth>
1080 collect_faces_vectorization(
1081 const std::vector<FaceToCellTopology<1>> &faces_in,
1082 const std::vector<bool> & hard_vectorization_boundary,
1083 std::vector<unsigned int> & face_partition_data,
1084 std::vector<FaceToCellTopology<vectorization_width>> &faces_out)
1086 FaceToCellTopology<vectorization_width> macro_face;
1087 std::vector<std::vector<unsigned int>> faces_type;
1089 unsigned int face_start = face_partition_data[0],
1090 face_end = face_partition_data[0];
1092 face_partition_data[0] = faces_out.size();
1093 for (
unsigned int partition = 0;
1094 partition < face_partition_data.size() - 1;
1097 std::vector<std::vector<unsigned int>> new_faces_type;
1100 face_start = face_end;
1101 face_end = face_partition_data[
partition + 1];
1108 for (
unsigned int face = face_start; face < face_end; ++face)
1110 for (
auto &face_type : faces_type)
1113 if (compare_faces_for_vectorization(faces_in[face],
1114 faces_in[face_type[0]]))
1116 face_type.push_back(face);
1120 faces_type.emplace_back(1, face);
1126 std::set<FaceToCellTopology<vectorization_width>,
1127 FaceComparator<vectorization_width>>
1129 for (
const auto &face_type : faces_type)
1131 macro_face.interior_face_no =
1132 faces_in[face_type[0]].interior_face_no;
1133 macro_face.exterior_face_no =
1134 faces_in[face_type[0]].exterior_face_no;
1135 macro_face.subface_index = faces_in[face_type[0]].subface_index;
1136 macro_face.face_orientation =
1137 faces_in[face_type[0]].face_orientation;
1138 unsigned int no_faces = face_type.size();
1139 std::vector<unsigned char> touched(no_faces, 0);
1145 unsigned int n_vectorized = 0;
1146 for (
unsigned int f = 0; f < no_faces; ++f)
1147 if (faces_in[face_type[f]].cells_interior[0] %
1148 vectorization_width ==
1151 bool is_contiguous =
true;
1152 if (f + vectorization_width > no_faces)
1153 is_contiguous =
false;
1155 for (
unsigned int v = 1; v < vectorization_width; ++v)
1156 if (faces_in[face_type[f + v]].cells_interior[0] !=
1157 faces_in[face_type[f]].cells_interior[0] + v)
1158 is_contiguous =
false;
1163 vectorization_width + 1);
1164 for (
unsigned int v = 0; v < vectorization_width; ++v)
1166 macro_face.cells_interior[v] =
1167 faces_in[face_type[f + v]].cells_interior[0];
1168 macro_face.cells_exterior[v] =
1169 faces_in[face_type[f + v]].cells_exterior[0];
1172 new_faces.insert(macro_face);
1173 f += vectorization_width - 1;
1174 n_vectorized += vectorization_width;
1178 std::vector<unsigned int> untouched;
1179 untouched.reserve(no_faces - n_vectorized);
1180 for (
unsigned int f = 0; f < no_faces; ++f)
1181 if (touched[f] == 0)
1182 untouched.push_back(f);
1184 for (
const auto f : untouched)
1186 macro_face.cells_interior[v] =
1187 faces_in[face_type[f]].cells_interior[0];
1188 macro_face.cells_exterior[v] =
1189 faces_in[face_type[f]].cells_exterior[0];
1191 if (v == vectorization_width)
1193 new_faces.insert(macro_face);
1197 if (v > 0 && v < vectorization_width)
1200 if (hard_vectorization_boundary[partition + 1] ||
1201 partition == face_partition_data.size() - 2)
1203 for (; v < vectorization_width; ++v)
1206 macro_face.cells_interior[v] =
1208 macro_face.cells_exterior[v] =
1211 new_faces.insert(macro_face);
1216 std::vector<unsigned int> untreated(v);
1217 for (
unsigned int f = 0; f < v; ++f)
1218 untreated[f] = face_type[*(untouched.end() - 1 - f)];
1219 new_faces_type.push_back(untreated);
1225 for (
auto it = new_faces.begin(); it != new_faces.end(); ++it)
1226 faces_out.push_back(*it);
1227 face_partition_data[
partition + 1] += new_faces.size();
1230 faces_type = std::move(new_faces_type);
1235 for (
const auto &face_type : faces_type)
1239 unsigned int nfaces = 0;
1240 for (
unsigned int i = face_partition_data[0];
1241 i < face_partition_data.back();
1243 for (
unsigned int v = 0; v < vectorization_width; ++v)
1248 std::vector<std::pair<unsigned int, unsigned int>> in_faces, out_faces;
1249 for (
const auto &face_in : faces_in)
1250 in_faces.emplace_back(face_in.cells_interior[0],
1251 face_in.cells_exterior[0]);
1252 for (
unsigned int i = face_partition_data[0];
1253 i < face_partition_data.back();
1255 for (
unsigned int v = 0;
1256 v < vectorization_width &&
1259 out_faces.emplace_back(faces_out[i].cells_interior[v],
1260 faces_out[i].cells_exterior[v]);
1261 std::sort(in_faces.begin(), in_faces.end());
1262 std::sort(out_faces.begin(), out_faces.end());
1264 for (
unsigned int i = 0; i < in_faces.size(); ++i)
1272 #endif // ifndef DOXYGEN 1278 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define AssertThrow(cond, exc)
unsigned int cells_interior[vectorization_width]
static ::ExceptionBase & ExcMessage(std::string arg1)
FaceToCellTopology< 1 > create_face(const unsigned int face_no, const typename ::Triangulation< dim >::cell_iterator &cell, const unsigned int number_cell_interior, const typename ::Triangulation< dim >::cell_iterator &neighbor, const unsigned int number_cell_exterior)
unsigned int subdomain_id
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotImplemented()
void generate_faces(const ::Triangulation< dim > &triangulation, const std::vector< std::pair< unsigned int, unsigned int >> &cell_levels, TaskInfo &task_info)
static ::ExceptionBase & ExcInternalError()
void initialize(const ::Triangulation< dim > &triangulation, const MFAddData &additional_data, std::vector< std::pair< unsigned int, unsigned int >> &cell_levels)