17 #ifndef dealii_face_setup_internal_h
18 #define dealii_face_setup_internal_h
41 namespace MatrixFreeFunctions
84 template <
typename MFAddData>
88 const MFAddData & additional_data,
89 std::vector<std::pair<unsigned int, unsigned int>> &cell_levels);
100 const std::vector<std::pair<unsigned int, unsigned int>> &cell_levels,
111 const unsigned int face_no,
112 const typename ::Triangulation<dim>::cell_iterator &cell,
113 const unsigned int number_cell_interior,
114 const typename ::Triangulation<dim>::cell_iterator &neighbor,
115 const unsigned int number_cell_exterior);
145 template <
int vectorization_w
idth>
149 const std::vector<bool> & hard_vectorization_boundary,
150 std::vector<unsigned int> & face_partition_data,
161 : use_active_cells(true)
167 template <
typename MFAddData>
171 const MFAddData & additional_data,
172 std::vector<std::pair<unsigned int, unsigned int>> &cell_levels)
179 if (use_active_cells)
180 for (
const auto &cell_level : cell_levels)
182 typename ::Triangulation<dim>::cell_iterator dcell(
191 at_processor_boundary.resize(cell_levels.size(),
false);
194 FaceCategory::locally_active_done_elsewhere);
198 std::map<types::subdomain_id, FaceIdentifier>
199 inner_faces_at_proc_boundary;
205 for (
unsigned int i = 0; i < cell_levels.size(); ++i)
207 if (i > 0 && cell_levels[i] == cell_levels[i - 1])
209 typename ::Triangulation<dim>::cell_iterator dcell(
213 if (dcell->at_boundary(f) && !dcell->has_periodic_neighbor(f))
215 typename ::Triangulation<dim>::cell_iterator neighbor =
216 dcell->neighbor_or_periodic_neighbor(f);
222 const CellId id_mine = dcell->id();
223 if (use_active_cells && neighbor->has_children())
224 for (
unsigned int c = 0;
225 c < (dcell->has_periodic_neighbor(f) ?
226 dcell->periodic_neighbor(f)
227 ->face(dcell->periodic_neighbor_face_no(f))
229 dcell->face(f)->n_children());
232 typename ::Triangulation<dim>::cell_iterator
234 dcell->at_boundary(f) ?
235 dcell->periodic_neighbor_child_on_subface(f, c) :
236 dcell->neighbor_child_on_subface(f, c);
238 neighbor_c->subdomain_id();
239 if (my_domain < neigh_domain)
240 inner_faces_at_proc_boundary[neigh_domain]
241 .n_hanging_faces_larger_subdomain++;
242 else if (my_domain > neigh_domain)
243 inner_faces_at_proc_boundary[neigh_domain]
244 .n_hanging_faces_smaller_subdomain++;
249 use_active_cells ? neighbor->subdomain_id() :
250 neighbor->level_subdomain_id();
251 if (neighbor->level() < dcell->level() &&
254 if (my_domain < neigh_domain)
255 inner_faces_at_proc_boundary[neigh_domain]
256 .n_hanging_faces_smaller_subdomain++;
257 else if (my_domain > neigh_domain)
258 inner_faces_at_proc_boundary[neigh_domain]
259 .n_hanging_faces_larger_subdomain++;
261 else if (neighbor->level() == dcell->level() &&
262 my_domain != neigh_domain)
268 const CellId id_neigh = neighbor->id();
269 if (my_domain < neigh_domain)
270 inner_faces_at_proc_boundary[neigh_domain]
271 .shared_faces.emplace_back(id_mine, id_neigh);
273 inner_faces_at_proc_boundary[neigh_domain]
274 .shared_faces.emplace_back(id_neigh, id_mine);
283 for (
auto &inner_face : inner_faces_at_proc_boundary)
285 Assert(inner_face.first != my_domain,
287 std::sort(inner_face.second.shared_faces.begin(),
288 inner_face.second.shared_faces.end());
289 inner_face.second.shared_faces.erase(
290 std::unique(inner_face.second.shared_faces.begin(),
291 inner_face.second.shared_faces.end()),
292 inner_face.second.shared_faces.end());
297 # if defined(DEAL_II_WITH_MPI) && defined(DEBUG)
299 if (const ::parallel::TriangulationBase<dim> *ptria =
300 dynamic_cast<const ::parallel::TriangulationBase<dim>
302 comm = ptria->get_communicator();
305 unsigned int mysize = inner_face.second.shared_faces.size();
307 MPI_Sendrecv(&mysize,
316 600 + inner_face.first,
320 mysize = inner_face.second.n_hanging_faces_smaller_subdomain;
321 MPI_Sendrecv(&mysize,
330 700 + inner_face.first,
334 mysize = inner_face.second.n_hanging_faces_larger_subdomain;
335 MPI_Sendrecv(&mysize,
344 800 + inner_face.first,
365 std::vector<std::tuple<CellId, CellId, unsigned int>> other_range(
366 inner_face.second.shared_faces.size());
367 for (
unsigned int i = 0; i < other_range.size(); ++i)
369 std::make_tuple(inner_face.second.shared_faces[i].second,
370 inner_face.second.shared_faces[i].first,
372 std::sort(other_range.begin(), other_range.end());
380 unsigned int n_faces_lower_proc = 0, n_faces_higher_proc = 0;
381 std::vector<char> assignment(other_range.size(), 0);
382 if (inner_face.second.shared_faces.size() > 0)
386 unsigned int count = 0;
387 for (
unsigned int i = 1;
388 i < inner_face.second.shared_faces.size();
390 if (inner_face.second.shared_faces[i].first ==
391 inner_face.second.shared_faces[i - 1 - count].first)
398 for (
unsigned int k = 0; k <= count; ++k)
399 assignment[i - 1 - k] = 1;
400 n_faces_higher_proc += count + 1;
410 for (
unsigned int i = 1; i < other_range.size(); ++i)
411 if (std::get<0>(other_range[i]) ==
412 std::get<0>(other_range[i - 1 - count]))
419 for (
unsigned int k = 0; k <= count; ++k)
422 .shared_faces[std::get<2>(
426 .shared_faces[std::get<2>(
427 other_range[i - 1 - k])]
432 if (assignment[std::get<2>(
433 other_range[i - 1 - k])] == 0)
435 assignment[std::get<2>(
436 other_range[i - 1 - k])] = -1;
437 ++n_faces_lower_proc;
451 n_faces_lower_proc +=
452 inner_face.second.n_hanging_faces_smaller_subdomain;
453 n_faces_higher_proc +=
454 inner_face.second.n_hanging_faces_larger_subdomain;
455 const unsigned int n_total_faces_at_proc_boundary =
456 (inner_face.second.shared_faces.size() +
457 inner_face.second.n_hanging_faces_smaller_subdomain +
458 inner_face.second.n_hanging_faces_larger_subdomain);
459 unsigned int split_index = n_total_faces_at_proc_boundary / 2;
460 if (split_index < n_faces_lower_proc)
462 else if (split_index <
463 n_total_faces_at_proc_boundary - n_faces_higher_proc)
464 split_index -= n_faces_lower_proc;
466 split_index = n_total_faces_at_proc_boundary -
467 n_faces_higher_proc - n_faces_lower_proc;
470 # if defined(DEAL_II_WITH_MPI) && defined(DEBUG)
471 MPI_Sendrecv(&split_index,
480 900 + inner_face.first,
484 MPI_Sendrecv(&n_faces_lower_proc,
493 1000 + inner_face.first,
497 MPI_Sendrecv(&n_faces_higher_proc,
506 1100 + inner_face.first,
513 std::vector<std::pair<CellId, CellId>> owned_faces_lower,
515 for (
unsigned int i = 0; i < assignment.size(); ++i)
516 if (assignment[i] < 0)
517 owned_faces_lower.push_back(
518 inner_face.second.shared_faces[i]);
519 else if (assignment[i] > 0)
520 owned_faces_higher.push_back(
521 inner_face.second.shared_faces[i]);
523 inner_face.second.shared_faces.size() + 1 -
524 owned_faces_lower.size() -
525 owned_faces_higher.size());
527 unsigned int i = 0, c = 0;
528 for (; i < assignment.size() && c < split_index; ++i)
529 if (assignment[i] == 0)
531 owned_faces_lower.push_back(
532 inner_face.second.shared_faces[i]);
535 for (; i < assignment.size(); ++i)
536 if (assignment[i] == 0)
538 owned_faces_higher.push_back(
539 inner_face.second.shared_faces[i]);
544 std::vector<std::pair<CellId, CellId>> check_faces;
545 check_faces.insert(check_faces.end(),
546 owned_faces_lower.begin(),
547 owned_faces_lower.end());
548 check_faces.insert(check_faces.end(),
549 owned_faces_higher.begin(),
550 owned_faces_higher.end());
551 std::sort(check_faces.begin(), check_faces.end());
553 inner_face.second.shared_faces.size());
554 for (
unsigned int i = 0; i < check_faces.size(); ++i)
555 Assert(check_faces[i] == inner_face.second.shared_faces[i],
560 if (my_domain < inner_face.first)
561 inner_face.second.shared_faces.swap(owned_faces_lower);
563 inner_face.second.shared_faces.swap(owned_faces_higher);
565 std::sort(inner_face.second.shared_faces.begin(),
566 inner_face.second.shared_faces.end());
572 std::set<std::pair<unsigned int, unsigned int>> ghost_cells;
573 for (
unsigned int i = 0; i < cell_levels.size(); ++i)
575 typename ::Triangulation<dim>::cell_iterator dcell(
577 if (use_active_cells)
581 if (dcell->at_boundary(f) && !dcell->has_periodic_neighbor(f))
582 face_is_owned[dcell->face(f)->index()] =
583 FaceCategory::locally_active_at_boundary;
587 else if ((dcell->at_boundary(f) ==
false ||
588 dcell->has_periodic_neighbor(f)) &&
589 additional_data.mg_level !=
591 dcell->neighbor_or_periodic_neighbor(f)->level() <
594 face_is_owned[dcell->face(f)->index()] =
595 FaceCategory::multigrid_refinement_edge;
599 typename ::Triangulation<dim>::cell_iterator neighbor =
600 dcell->neighbor_or_periodic_neighbor(f);
603 if (use_active_cells && neighbor->has_children() &&
604 additional_data.hold_all_faces_to_owned_cells ==
false)
607 bool add_to_ghost =
false;
609 id1 = use_active_cells ? dcell->subdomain_id() :
610 dcell->level_subdomain_id(),
611 id2 = use_active_cells ?
612 (neighbor->has_children() ?
613 dcell->neighbor_child_on_subface(f, 0)
615 neighbor->subdomain_id()) :
616 neighbor->level_subdomain_id();
624 (use_active_cells ==
false || neighbor->is_active())) ||
625 dcell->level() > neighbor->level() ||
627 inner_faces_at_proc_boundary[id2].shared_faces.begin(),
628 inner_faces_at_proc_boundary[id2].shared_faces.end(),
629 std::make_pair(id1 < id2 ? dcell->
id() : neighbor->id(),
630 id1 < id2 ? neighbor->
id() :
633 face_is_owned[dcell->face(f)->index()] =
634 FaceCategory::locally_active_done_here;
635 if (dcell->level() == neighbor->level())
638 ->face(dcell->has_periodic_neighbor(f) ?
639 dcell->periodic_neighbor_face_no(f) :
640 dcell->neighbor_face_no(f))
642 FaceCategory::locally_active_done_here;
648 if (use_active_cells)
650 (dcell->subdomain_id() != neighbor->subdomain_id());
652 add_to_ghost = (dcell->level_subdomain_id() !=
653 neighbor->level_subdomain_id());
655 else if (additional_data.hold_all_faces_to_owned_cells ==
659 face_is_owned[dcell->face(f)->index()] =
660 FaceCategory::ghosted;
661 if (use_active_cells)
663 if (neighbor->has_children())
664 for (
unsigned int s = 0;
665 s < dcell->face(f)->n_children();
667 if (dcell->at_boundary(f))
670 ->periodic_neighbor_child_on_subface(f,
673 dcell->subdomain_id())
678 if (dcell->neighbor_child_on_subface(f, s)
680 dcell->subdomain_id())
684 add_to_ghost = (dcell->subdomain_id() !=
685 neighbor->subdomain_id());
688 add_to_ghost = (dcell->level_subdomain_id() !=
689 neighbor->level_subdomain_id());
694 if (use_active_cells && neighbor->has_children())
695 for (
unsigned int s = 0;
696 s < dcell->face(f)->n_children();
699 typename ::Triangulation<dim>::cell_iterator
701 dcell->at_boundary(f) ?
702 dcell->periodic_neighbor_child_on_subface(f,
704 dcell->neighbor_child_on_subface(f, s);
705 if (neighbor_child->subdomain_id() !=
706 dcell->subdomain_id())
708 std::pair<unsigned int, unsigned int>(
709 neighbor_child->level(),
710 neighbor_child->index()));
714 std::pair<unsigned int, unsigned int>(
715 neighbor->level(), neighbor->index()));
716 at_processor_boundary[i] =
true;
724 for (
const auto &ghost_cell : ghost_cells)
725 cell_levels.push_back(ghost_cell);
734 const std::vector<std::pair<unsigned int, unsigned int>> &cell_levels,
735 TaskInfo & task_info)
739 std::map<std::pair<unsigned int, unsigned int>,
unsigned int>
741 for (
unsigned int cell = 0; cell < cell_levels.size(); ++cell)
742 if (cell == 0 || cell_levels[cell] != cell_levels[cell - 1])
744 typename ::Triangulation<dim>::cell_iterator dcell(
746 cell_levels[cell].
first,
747 cell_levels[cell].
second);
748 std::pair<unsigned int, unsigned int> level_index(dcell->level(),
750 map_to_vectorized[level_index] = cell;
754 const unsigned int vectorization_length = task_info.vectorization_length;
755 task_info.face_partition_data.resize(
756 task_info.cell_partition_data.size() - 1, 0);
757 task_info.boundary_partition_data.resize(
758 task_info.cell_partition_data.size() - 1, 0);
759 std::vector<unsigned char> face_visited(face_is_owned.size(), 0);
761 partition < task_info.cell_partition_data.size() - 2;
764 unsigned int boundary_counter = 0;
765 unsigned int inner_counter = 0;
766 for (
unsigned int cell = task_info.cell_partition_data[
partition] *
767 vectorization_length;
768 cell < task_info.cell_partition_data[
partition + 1] *
769 vectorization_length;
771 if (cell == 0 || cell_levels[cell] != cell_levels[cell - 1])
773 typename ::Triangulation<dim>::cell_iterator dcell(
775 cell_levels[cell].
first,
776 cell_levels[cell].
second);
780 if (face_is_owned[dcell->face(f)->index()] ==
781 FaceCategory::locally_active_at_boundary)
785 FaceToCellTopology<1> info;
786 info.cells_interior[0] = cell;
788 info.interior_face_no = f;
789 info.exterior_face_no = dcell->face(f)->boundary_id();
792 info.face_orientation = 0;
793 boundary_faces.push_back(info);
795 face_visited[dcell->face(f)->index()]++;
800 typename ::Triangulation<dim>::cell_iterator
801 neighbor = dcell->neighbor_or_periodic_neighbor(f);
802 if (use_active_cells && neighbor->has_children())
804 for (
unsigned int c = 0;
805 c < dcell->face(f)->n_children();
809 dim>::cell_iterator neighbor_c =
810 dcell->at_boundary(f) ?
811 dcell->periodic_neighbor_child_on_subface(
813 dcell->neighbor_child_on_subface(f, c);
815 neighbor_c->subdomain_id();
816 const unsigned int neighbor_face_no =
817 dcell->has_periodic_neighbor(f) ?
818 dcell->periodic_neighbor_face_no(f) :
819 dcell->neighbor_face_no(f);
820 if (neigh_domain != dcell->subdomain_id() ||
822 [dcell->face(f)->child(c)->index()] ==
825 std::pair<unsigned int, unsigned int>
826 level_index(neighbor_c->level(),
827 neighbor_c->index());
829 [dcell->face(f)->child(c)->index()] ==
830 FaceCategory::locally_active_done_here)
833 inner_faces.push_back(create_face(
836 map_to_vectorized[level_index],
840 else if (face_is_owned[dcell->face(f)
843 FaceCategory::ghosted)
845 inner_ghost_faces.push_back(create_face(
848 map_to_vectorized[level_index],
854 face_is_owned[dcell->face(f)
857 locally_active_done_elsewhere ||
858 face_is_owned[dcell->face(f)
860 FaceCategory::ghosted,
866 [dcell->face(f)->child(c)->index()] = 1;
873 use_active_cells ? dcell->subdomain_id() :
874 dcell->level_subdomain_id();
876 use_active_cells ? neighbor->subdomain_id() :
877 neighbor->level_subdomain_id();
878 if (neigh_domain != my_domain ||
879 face_visited[dcell->face(f)->index()] == 1)
881 std::pair<unsigned int, unsigned int>
882 level_index(neighbor->level(),
884 if (face_is_owned[dcell->face(f)->index()] ==
885 FaceCategory::locally_active_done_here)
887 Assert(use_active_cells ||
892 inner_faces.push_back(create_face(
897 map_to_vectorized[level_index]));
899 else if (face_is_owned[dcell->face(f)
901 FaceCategory::ghosted)
903 inner_ghost_faces.push_back(create_face(
908 map_to_vectorized[level_index]));
913 face_visited[dcell->face(f)->index()] = 1;
914 if (dcell->has_periodic_neighbor(f))
918 dcell->periodic_neighbor_face_no(f))
921 if (face_is_owned[dcell->face(f)->index()] ==
922 FaceCategory::multigrid_refinement_edge)
924 refinement_edge_faces.push_back(
929 refinement_edge_faces.size()));
935 task_info.face_partition_data[
partition + 1] =
936 task_info.face_partition_data[
partition] + inner_counter;
937 task_info.boundary_partition_data[
partition + 1] =
938 task_info.boundary_partition_data[
partition] + boundary_counter;
940 task_info.ghost_face_partition_data.resize(2);
941 task_info.ghost_face_partition_data[0] = 0;
942 task_info.ghost_face_partition_data[1] = inner_ghost_faces.size();
943 task_info.refinement_edge_face_partition_data.resize(2);
944 task_info.refinement_edge_face_partition_data[0] = 0;
945 task_info.refinement_edge_face_partition_data[1] =
946 refinement_edge_faces.size();
952 FaceToCellTopology<1>
954 const unsigned int face_no,
955 const typename ::Triangulation<dim>::cell_iterator &cell,
956 const unsigned int number_cell_interior,
957 const typename ::Triangulation<dim>::cell_iterator &neighbor,
958 const unsigned int number_cell_exterior)
960 FaceToCellTopology<1> info;
962 info.cells_exterior[0] = number_cell_exterior;
963 info.interior_face_no = face_no;
964 if (cell->has_periodic_neighbor(face_no))
965 info.exterior_face_no = cell->periodic_neighbor_face_no(face_no);
967 info.exterior_face_no = cell->neighbor_face_no(face_no);
971 if (cell->level() > neighbor->level())
973 if (cell->has_periodic_neighbor(face_no))
975 cell->periodic_neighbor_of_coarser_periodic_neighbor(face_no)
979 cell->neighbor_of_coarser_neighbor(face_no).second;
982 info.face_orientation = 0;
983 const unsigned int left_face_orientation =
984 !cell->face_orientation(face_no) + 2 * cell->face_flip(face_no) +
985 4 * cell->face_rotation(face_no);
986 const unsigned int right_face_orientation =
987 !neighbor->face_orientation(info.exterior_face_no) +
988 2 * neighbor->face_flip(info.exterior_face_no) +
989 4 * neighbor->face_rotation(info.exterior_face_no);
990 if (left_face_orientation != 0)
992 info.face_orientation = 8 + left_face_orientation;
993 Assert(right_face_orientation == 0,
995 "Face seems to be wrongly oriented from both sides"));
998 info.face_orientation = right_face_orientation;
1011 compare_faces_for_vectorization(
const FaceToCellTopology<1> &face1,
1012 const FaceToCellTopology<1> &face2)
1014 if (face1.interior_face_no != face2.interior_face_no)
1016 if (face1.exterior_face_no != face2.exterior_face_no)
1018 if (face1.subface_index != face2.subface_index)
1020 if (face1.face_orientation != face2.face_orientation)
1033 template <
int length>
1034 struct FaceComparator
1037 operator()(
const FaceToCellTopology<length> &face1,
1038 const FaceToCellTopology<length> &face2)
const
1040 for (
unsigned int i = 0; i < length; ++i)
1041 if (face1.cells_interior[i] < face2.cells_interior[i])
1043 else if (face1.cells_interior[i] > face2.cells_interior[i])
1045 for (
unsigned int i = 0; i < length; ++i)
1046 if (face1.cells_exterior[i] < face2.cells_exterior[i])
1048 else if (face1.cells_exterior[i] > face2.cells_exterior[i])
1050 if (face1.interior_face_no < face2.interior_face_no)
1052 else if (face1.interior_face_no > face2.interior_face_no)
1054 if (face1.exterior_face_no < face2.exterior_face_no)
1056 else if (face1.exterior_face_no > face2.exterior_face_no)
1071 template <
int vectorization_w
idth>
1074 const std::vector<FaceToCellTopology<1>> &faces_in,
1075 const std::vector<bool> & hard_vectorization_boundary,
1076 std::vector<unsigned int> & face_partition_data,
1080 std::vector<std::vector<unsigned int>> faces_type;
1082 unsigned int face_start = face_partition_data[0],
1083 face_end = face_partition_data[0];
1085 face_partition_data[0] = faces_out.size();
1087 partition < face_partition_data.size() - 1;
1090 std::vector<std::vector<unsigned int>> new_faces_type;
1093 face_start = face_end;
1094 face_end = face_partition_data[
partition + 1];
1101 for (
unsigned int face = face_start; face < face_end; ++face)
1103 for (
auto &face_type : faces_type)
1106 if (compare_faces_for_vectorization(faces_in[face],
1107 faces_in[face_type[0]]))
1109 face_type.push_back(face);
1113 faces_type.emplace_back(1, face);
1119 std::set<FaceToCellTopology<vectorization_width>,
1120 FaceComparator<vectorization_width>>
1122 for (
const auto &face_type : faces_type)
1124 macro_face.interior_face_no =
1125 faces_in[face_type[0]].interior_face_no;
1126 macro_face.exterior_face_no =
1127 faces_in[face_type[0]].exterior_face_no;
1128 macro_face.subface_index = faces_in[face_type[0]].subface_index;
1129 macro_face.face_orientation =
1130 faces_in[face_type[0]].face_orientation;
1131 unsigned int no_faces = face_type.size();
1132 std::vector<unsigned char> touched(no_faces, 0);
1138 unsigned int n_vectorized = 0;
1139 for (
unsigned int f = 0; f < no_faces; ++f)
1140 if (faces_in[face_type[f]].cells_interior[0] %
1141 vectorization_width ==
1144 bool is_contiguous =
true;
1145 if (f + vectorization_width > no_faces)
1146 is_contiguous =
false;
1148 for (
unsigned int v = 1; v < vectorization_width; ++v)
1149 if (faces_in[face_type[f + v]].cells_interior[0] !=
1150 faces_in[face_type[f]].cells_interior[0] + v)
1151 is_contiguous =
false;
1156 vectorization_width + 1);
1157 for (
unsigned int v = 0; v < vectorization_width; ++v)
1159 macro_face.cells_interior[v] =
1160 faces_in[face_type[f + v]].cells_interior[0];
1161 macro_face.cells_exterior[v] =
1162 faces_in[face_type[f + v]].cells_exterior[0];
1165 new_faces.insert(macro_face);
1166 f += vectorization_width - 1;
1167 n_vectorized += vectorization_width;
1171 std::vector<unsigned int> untouched;
1172 untouched.reserve(no_faces - n_vectorized);
1173 for (
unsigned int f = 0; f < no_faces; ++f)
1174 if (touched[f] == 0)
1175 untouched.push_back(f);
1177 for (
const auto f : untouched)
1179 macro_face.cells_interior[v] =
1180 faces_in[face_type[f]].cells_interior[0];
1181 macro_face.cells_exterior[v] =
1182 faces_in[face_type[f]].cells_exterior[0];
1184 if (v == vectorization_width)
1186 new_faces.insert(macro_face);
1190 if (v > 0 && v < vectorization_width)
1193 if (hard_vectorization_boundary[
partition + 1] ||
1194 partition == face_partition_data.size() - 2)
1196 for (; v < vectorization_width; ++v)
1199 macro_face.cells_interior[v] =
1201 macro_face.cells_exterior[v] =
1204 new_faces.insert(macro_face);
1209 std::vector<unsigned int> untreated(v);
1210 for (
unsigned int f = 0; f < v; ++f)
1211 untreated[f] = face_type[*(untouched.end() - 1 - f)];
1212 new_faces_type.push_back(untreated);
1218 for (
auto it = new_faces.begin(); it != new_faces.end(); ++it)
1219 faces_out.push_back(*it);
1220 face_partition_data[
partition + 1] += new_faces.size();
1223 faces_type = std::move(new_faces_type);
1228 for (
const auto &face_type : faces_type)
1232 unsigned int nfaces = 0;
1233 for (
unsigned int i = face_partition_data[0];
1234 i < face_partition_data.back();
1236 for (
unsigned int v = 0; v < vectorization_width; ++v)
1241 std::vector<std::pair<unsigned int, unsigned int>> in_faces, out_faces;
1242 for (
const auto &face_in : faces_in)
1243 in_faces.emplace_back(face_in.cells_interior[0],
1244 face_in.cells_exterior[0]);
1245 for (
unsigned int i = face_partition_data[0];
1246 i < face_partition_data.back();
1248 for (
unsigned int v = 0;
1249 v < vectorization_width &&
1252 out_faces.emplace_back(faces_out[i].cells_interior[v],
1253 faces_out[i].cells_exterior[v]);
1254 std::sort(in_faces.begin(), in_faces.end());
1255 std::sort(out_faces.begin(), out_faces.end());
1257 for (
unsigned int i = 0; i < in_faces.size(); ++i)
1265 #endif // ifndef DOXYGEN