55 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
59 const std::vector<bool> & marked_vertices)
70 marked_vertices.size() == 0,
72 marked_vertices.size()));
82 marked_vertices.size() == 0 ||
83 std::equal(marked_vertices.begin(),
84 marked_vertices.end(),
86 [](
bool p,
bool q) { return !p || q; }),
88 "marked_vertices should be a subset of used vertices in the triangulation "
89 "but marked_vertices contains one or more vertices that are not used vertices!"));
97 const std::vector<bool> &used = (marked_vertices.size() == 0) ?
103 std::vector<bool>::const_iterator
first =
104 std::find(used.begin(), used.end(),
true);
110 unsigned int best_vertex = std::distance(used.begin(),
first);
111 double best_dist = (p -
vertices[best_vertex]).norm_square();
115 for (
unsigned int j = best_vertex + 1; j <
vertices.size(); j++)
118 double dist = (p -
vertices[j]).norm_square();
119 if (dist < best_dist)
131 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
134 const MeshType<dim, spacedim> &mesh,
136 const std::vector<bool> & marked_vertices)
151 marked_vertices.size() == 0,
153 marked_vertices.size()));
163 marked_vertices.size() == 0 ||
164 std::equal(marked_vertices.begin(),
165 marked_vertices.end(),
167 [](
bool p,
bool q) { return !p || q; }),
169 "marked_vertices should be a subset of used vertices in the triangulation "
170 "but marked_vertices contains one or more vertices that are not used vertices!"));
173 if (marked_vertices.size())
176 if (marked_vertices[it->first] ==
false)
191 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
193 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
196 typename ::internal::
197 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
200 const unsigned int vertex)
206 Assert(mesh.get_triangulation().get_used_vertices()[vertex],
213 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
216 typename ::internal::
217 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type
218 cell = mesh.begin_active(),
254 for (; cell != endc; ++cell)
257 if (cell->vertex_index(v) == vertex)
262 adjacent_cells.insert(cell);
269 for (
unsigned int vface = 0; vface < dim; vface++)
271 const unsigned int face =
274 if (!cell->at_boundary(face) &&
275 cell->neighbor(face)->is_active())
287 adjacent_cells.insert(cell->neighbor(face));
298 for (
unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++
e)
299 if (cell->line(
e)->has_children())
303 if (cell->line(
e)->child(0)->vertex_index(1) == vertex)
305 adjacent_cells.insert(cell);
327 typename ::internal::
328 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>(
329 adjacent_cells.begin(), adjacent_cells.end());
336 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
338 find_active_cell_around_point_internal(
339 const MeshType<dim, spacedim> &mesh,
341 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator>
343 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator>
347 typename ::internal::
348 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
351 typename ::internal::
352 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
357 using cell_iterator =
358 typename MeshType<dim, spacedim>::active_cell_iterator;
360 using cell_iterator = typename ::internal::
361 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type;
365 searched_cells.insert(adjacent_cells.begin(), adjacent_cells.end());
369 std::set<cell_iterator> adjacent_cells_new;
371 typename std::set<cell_iterator>::const_iterator cell =
372 adjacent_cells.begin(),
374 adjacent_cells.end();
375 for (; cell != endc; ++cell)
377 std::vector<cell_iterator> active_neighbors;
378 get_active_neighbors<MeshType<dim, spacedim>>(*cell,
380 for (
unsigned int i = 0; i < active_neighbors.size(); ++i)
381 if (searched_cells.find(active_neighbors[i]) ==
382 searched_cells.end())
383 adjacent_cells_new.insert(active_neighbors[i]);
385 adjacent_cells.clear();
386 adjacent_cells.insert(adjacent_cells_new.begin(),
387 adjacent_cells_new.end());
388 if (adjacent_cells.size() == 0)
396 cell_iterator it = mesh.begin_active();
397 for (; it != mesh.end(); ++it)
398 if (searched_cells.find(it) == searched_cells.end())
400 adjacent_cells.insert(it);
408 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
410 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
414 typename ::internal::
415 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
418 find_active_cell_around_point_tolerance(
420 const MeshType<dim, spacedim> &mesh,
422 const std::vector<bool> & marked_vertices,
423 const double tolerance)
425 using active_cell_iterator = typename ::internal::
426 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type;
432 double best_distance = tolerance;
434 std::pair<active_cell_iterator, Point<dim>> best_cell;
438 std::vector<active_cell_iterator> adjacent_cells_tmp =
447 std::set<active_cell_iterator> adjacent_cells(adjacent_cells_tmp.begin(),
448 adjacent_cells_tmp.end());
449 std::set<active_cell_iterator> searched_cells;
458 mesh.get_triangulation().n_active_cells();
460 unsigned int cells_searched = 0;
463 typename std::set<active_cell_iterator>::const_iterator
464 cell = adjacent_cells.begin(),
465 endc = adjacent_cells.end();
466 for (; cell != endc; ++cell)
482 if ((dist < best_distance) ||
483 ((dist == best_distance) &&
484 ((*cell)->level() > best_level)))
487 best_distance = dist;
488 best_level = (*cell)->level();
489 best_cell = std::make_pair(*cell, p_cell);
511 cells_searched += adjacent_cells.size();
516 if (marked_vertices.size() > 0)
528 find_active_cell_around_point_internal<dim, MeshType, spacedim>(
529 mesh, searched_cells, adjacent_cells);
534 ExcPointNotFound<spacedim>(p));
542 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
544 typename MeshType<dim, spacedim>::active_cell_iterator
546 typename ::internal::
547 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type
551 const std::vector<bool> & marked_vertices)
553 return find_active_cell_around_point<dim, MeshType, spacedim>(
560 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
562 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim>>
564 std::pair<typename ::internal::
565 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
569 const MeshType<dim, spacedim> &mesh,
571 const std::vector<bool> & marked_vertices)
573 return find_active_cell_around_point_tolerance(
574 mapping, mesh, p, marked_vertices, 1
e-10);
579 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
581 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
584 std::vector<std::pair<
585 typename ::internal::
586 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
590 const MeshType<dim, spacedim> &mesh,
592 const double tolerance,
593 const std::vector<bool> &marked_vertices)
601 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
606 cells_and_points.push_back(find_active_cell_around_point_tolerance(
607 mapping, mesh, p, marked_vertices, tolerance));
609 catch (ExcPointNotFound<spacedim> &)
612 if (!cells_and_points.empty())
616 const Point<dim> unit_point = cells_and_points.front().second;
617 const auto my_cell = cells_and_points.front().first;
619 unsigned int n_dirs_at_threshold = 0;
621 for (
unsigned int d = 0;
d < dim; ++
d)
623 distance_to_center[
d] = std::abs(unit_point[
d] - 0.5);
624 if (distance_to_center[
d] > 0.5 - tolerance)
626 ++n_dirs_at_threshold;
627 last_point_at_threshold =
d;
631 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
634 if (n_dirs_at_threshold == 1)
636 unsigned int neighbor_index =
637 2 * last_point_at_threshold +
638 (unit_point[last_point_at_threshold] > 0.5 ? 1 : 0);
639 if (!my_cell->at_boundary(neighbor_index))
640 cells_to_add.push_back(my_cell->neighbor(neighbor_index));
643 else if (n_dirs_at_threshold == dim)
645 unsigned int local_vertex_index = 0;
646 for (
unsigned int d = 0;
d < dim; ++
d)
647 local_vertex_index += (unit_point[
d] > 0.5 ? 1 : 0) <<
d;
648 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
650 mesh, my_cell->vertex_index(local_vertex_index));
651 for (
const auto &cell : cells)
653 cells_to_add.push_back(cell);
660 else if (n_dirs_at_threshold == 2)
663 unsigned int count_vertex_indices = 0;
665 for (
unsigned int d = 0;
d < dim; ++
d)
667 if (distance_to_center[
d] > 0.5 - tolerance)
671 unit_point[
d] > 0.5 ? 1 : 0;
672 count_vertex_indices++;
682 const unsigned int first_vertex =
685 for (
unsigned int d = 0;
d < 2; ++
d)
689 my_cell->vertex_index(first_vertex + (
d << free_direction)));
690 for (
const auto &cell : tentative_cells)
692 bool cell_not_yet_present =
true;
693 for (
const auto &other_cell : cells_to_add)
694 if (cell == other_cell)
696 cell_not_yet_present =
false;
699 if (cell_not_yet_present)
700 cells_to_add.push_back(cell);
705 const double original_distance_to_unit_cell =
707 for (
const auto &cell : cells_to_add)
715 original_distance_to_unit_cell + tolerance)
716 cells_and_points.emplace_back(cell, p_unit);
723 cells_and_points.begin(),
724 cells_and_points.end(),
725 [](
const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
727 const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
730 return cells_and_points;
735 template <
class MeshType>
736 std::vector<typename MeshType::active_cell_iterator>
738 const MeshType &mesh,
739 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
742 std::vector<typename MeshType::active_cell_iterator> active_halo_layer;
743 std::vector<bool> locally_active_vertices_on_subdomain(
744 mesh.get_triangulation().n_vertices(),
false);
749 for (
const auto &cell : mesh.active_cell_iterators())
751 for (
const unsigned int v :
753 locally_active_vertices_on_subdomain[cell->vertex_index(v)] =
true;
758 for (
const auto &cell : mesh.active_cell_iterators())
759 if (!predicate(cell))
760 for (
const unsigned int v :
762 if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] ==
765 active_halo_layer.push_back(cell);
769 return active_halo_layer;
774 template <
class MeshType>
775 std::vector<typename MeshType::cell_iterator>
777 const MeshType &mesh,
778 const std::function<
bool(
const typename MeshType::cell_iterator &)>
780 const unsigned int level)
782 std::vector<typename MeshType::cell_iterator> level_halo_layer;
783 std::vector<bool> locally_active_vertices_on_level_subdomain(
784 mesh.get_triangulation().n_vertices(),
false);
789 for (
typename MeshType::cell_iterator cell = mesh.begin(
level);
790 cell != mesh.end(
level);
793 for (
const unsigned int v :
795 locally_active_vertices_on_level_subdomain[cell->vertex_index(v)] =
801 for (
typename MeshType::cell_iterator cell = mesh.begin(
level);
802 cell != mesh.end(
level);
804 if (!predicate(cell))
805 for (
const unsigned int v :
807 if (locally_active_vertices_on_level_subdomain[cell->vertex_index(
810 level_halo_layer.push_back(cell);
814 return level_halo_layer;
820 template <
class MeshType>
822 contains_locally_owned_cells(
823 const std::vector<typename MeshType::active_cell_iterator> &cells)
825 for (
typename std::vector<
826 typename MeshType::active_cell_iterator>::const_iterator it =
831 if ((*it)->is_locally_owned())
837 template <
class MeshType>
839 contains_artificial_cells(
840 const std::vector<typename MeshType::active_cell_iterator> &cells)
842 for (
typename std::vector<
843 typename MeshType::active_cell_iterator>::const_iterator it =
848 if ((*it)->is_artificial())
857 template <
class MeshType>
858 std::vector<typename MeshType::active_cell_iterator>
861 std::function<
bool(
const typename MeshType::active_cell_iterator &)>
864 const std::vector<typename MeshType::active_cell_iterator>
869 Assert(contains_locally_owned_cells<MeshType>(active_halo_layer) ==
false,
870 ExcMessage(
"Halo layer contains locally owned cells"));
871 Assert(contains_artificial_cells<MeshType>(active_halo_layer) ==
false,
872 ExcMessage(
"Halo layer contains artificial cells"));
874 return active_halo_layer;
879 template <
class MeshType>
880 std::vector<typename MeshType::active_cell_iterator>
882 const MeshType &mesh,
883 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
885 const double layer_thickness)
887 std::vector<typename MeshType::active_cell_iterator>
888 subdomain_boundary_cells, active_cell_layer_within_distance;
889 std::vector<bool> vertices_outside_subdomain(
890 mesh.get_triangulation().n_vertices(),
false);
892 const unsigned int spacedim = MeshType::space_dimension;
894 unsigned int n_non_predicate_cells = 0;
902 for (
const auto &cell : mesh.active_cell_iterators())
903 if (!predicate(cell))
905 for (
const unsigned int v :
907 vertices_outside_subdomain[cell->vertex_index(v)] =
true;
908 n_non_predicate_cells++;
915 if (n_non_predicate_cells == 0 ||
916 n_non_predicate_cells == mesh.get_triangulation().n_active_cells())
917 return std::vector<typename MeshType::active_cell_iterator>();
921 for (
const auto &cell : mesh.active_cell_iterators())
924 for (
const unsigned int v :
926 if (vertices_outside_subdomain[cell->vertex_index(v)] ==
true)
928 subdomain_boundary_cells.push_back(cell);
941 for (
unsigned int d = 0;
d < spacedim; ++
d)
943 bounding_box.first[
d] -= (layer_thickness + DOUBLE_EPSILON);
944 bounding_box.second[
d] += (layer_thickness + DOUBLE_EPSILON);
947 std::vector<Point<spacedim>>
948 subdomain_boundary_cells_centers;
951 subdomain_boundary_cells_radii;
953 subdomain_boundary_cells_centers.reserve(subdomain_boundary_cells.size());
954 subdomain_boundary_cells_radii.reserve(subdomain_boundary_cells.size());
956 for (
typename std::vector<typename MeshType::active_cell_iterator>::
957 const_iterator subdomain_boundary_cell_iterator =
958 subdomain_boundary_cells.begin();
959 subdomain_boundary_cell_iterator != subdomain_boundary_cells.end();
960 ++subdomain_boundary_cell_iterator)
962 const std::pair<Point<spacedim>,
double>
963 &subdomain_boundary_cell_enclosing_ball =
964 (*subdomain_boundary_cell_iterator)->enclosing_ball();
966 subdomain_boundary_cells_centers.push_back(
967 subdomain_boundary_cell_enclosing_ball.first);
968 subdomain_boundary_cells_radii.push_back(
969 subdomain_boundary_cell_enclosing_ball.second);
971 AssertThrow(subdomain_boundary_cells_radii.size() ==
972 subdomain_boundary_cells_centers.size(),
981 for (
const auto &cell : mesh.active_cell_iterators())
987 const std::pair<Point<spacedim>,
double> &cell_enclosing_ball =
988 cell->enclosing_ball();
991 cell_enclosing_ball.first;
992 const double cell_enclosing_ball_radius = cell_enclosing_ball.second;
994 bool cell_inside =
true;
996 for (
unsigned int d = 0;
d < spacedim; ++
d)
998 (cell_enclosing_ball_center[
d] + cell_enclosing_ball_radius >
999 bounding_box.first[
d]) &&
1000 (cell_enclosing_ball_center[
d] - cell_enclosing_ball_radius <
1001 bounding_box.second[
d]);
1007 for (
unsigned int i = 0; i < subdomain_boundary_cells_radii.size();
1010 subdomain_boundary_cells_centers[i]) <
1011 Utilities::fixed_power<2>(cell_enclosing_ball_radius +
1012 subdomain_boundary_cells_radii[i] +
1013 layer_thickness + DOUBLE_EPSILON))
1015 active_cell_layer_within_distance.push_back(cell);
1020 return active_cell_layer_within_distance;
1025 template <
class MeshType>
1026 std::vector<typename MeshType::active_cell_iterator>
1028 const double layer_thickness)
1031 std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1032 predicate(locally_owned_cell_predicate);
1034 const std::vector<typename MeshType::active_cell_iterator>
1035 ghost_cell_layer_within_distance =
1043 contains_locally_owned_cells<MeshType>(
1044 ghost_cell_layer_within_distance) ==
false,
1046 "Ghost cells within layer_thickness contains locally owned cells."));
1048 contains_artificial_cells<MeshType>(ghost_cell_layer_within_distance) ==
1051 "Ghost cells within layer_thickness contains artificial cells. "
1052 "The function compute_ghost_cell_layer_within_distance "
1053 "is probably called while using parallel::distributed::Triangulation. "
1054 "In such case please refer to the description of this function."));
1056 return ghost_cell_layer_within_distance;
1061 template <
class MeshType>
1064 const MeshType &mesh,
1065 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1068 std::vector<bool> locally_active_vertices_on_subdomain(
1069 mesh.get_triangulation().n_vertices(),
false);
1071 const unsigned int spacedim = MeshType::space_dimension;
1078 for (
const auto &cell : mesh.active_cell_iterators())
1079 if (predicate(cell))
1081 minp = cell->center();
1082 maxp = cell->center();
1088 for (
const auto &cell : mesh.active_cell_iterators())
1089 if (predicate(cell))
1090 for (
const unsigned int v :
1092 if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] ==
1095 locally_active_vertices_on_subdomain[cell->vertex_index(v)] =
1097 for (
unsigned int d = 0;
d < spacedim; ++
d)
1104 return std::make_pair(minp, maxp);
1109 template <
typename MeshType>
1110 std::list<std::pair<
typename MeshType::cell_iterator,
1111 typename MeshType::cell_iterator>>
1115 ExcMessage(
"The two meshes must be represent triangulations that "
1116 "have the same coarse meshes"));
1123 bool remove_ghost_cells =
false;
1124 #ifdef DEAL_II_WITH_MPI
1126 constexpr
int dim = MeshType::dimension;
1127 constexpr
int spacedim = MeshType::space_dimension;
1129 *
>(&mesh_1.get_triangulation()) !=
nullptr ||
1131 *
>(&mesh_2.get_triangulation()) !=
nullptr)
1133 Assert(&mesh_1.get_triangulation() == &mesh_2.get_triangulation(),
1134 ExcMessage(
"This function can only be used with meshes "
1135 "corresponding to distributed Triangulations when "
1136 "both Triangulations are equal."));
1137 remove_ghost_cells =
true;
1149 using CellList = std::list<std::pair<
typename MeshType::cell_iterator,
1150 typename MeshType::cell_iterator>>;
1154 typename MeshType::cell_iterator cell_1 = mesh_1.begin(0),
1155 cell_2 = mesh_2.begin(0);
1156 for (; cell_1 != mesh_1.end(0); ++cell_1, ++cell_2)
1157 cell_list.emplace_back(cell_1, cell_2);
1160 typename CellList::iterator cell_pair = cell_list.begin();
1161 while (cell_pair != cell_list.end())
1165 if (cell_pair->first->has_children() &&
1166 cell_pair->second->has_children())
1168 Assert(cell_pair->first->refinement_case() ==
1169 cell_pair->second->refinement_case(),
1171 for (
unsigned int c = 0; c < cell_pair->first->n_children(); ++c)
1172 cell_list.emplace_back(cell_pair->first->child(c),
1173 cell_pair->second->child(c));
1178 const auto previous_cell_pair = cell_pair;
1180 cell_list.erase(previous_cell_pair);
1185 if (remove_ghost_cells &&
1186 ((cell_pair->first->is_active() &&
1187 !cell_pair->first->is_locally_owned()) ||
1188 (cell_pair->second->is_active() &&
1189 !cell_pair->second->is_locally_owned())))
1192 const auto previous_cell_pair = cell_pair;
1194 cell_list.erase(previous_cell_pair);
1203 for (cell_pair = cell_list.begin(); cell_pair != cell_list.end();
1205 Assert(cell_pair->first->is_active() || cell_pair->second->is_active() ||
1206 (cell_pair->first->refinement_case() !=
1207 cell_pair->second->refinement_case()),
1215 template <
int dim,
int spacedim>
1232 endc = mesh_1.
end(0);
1233 for (; cell_1 != endc; ++cell_1, ++cell_2)
1235 if (cell_1->vertex(v) != cell_2->vertex(v))
1247 template <
typename MeshType>
1252 mesh_2.get_triangulation());
1257 template <
int dim,
int spacedim>
1258 std::pair<typename hp::DoFHandler<dim, spacedim>::active_cell_iterator,
1267 ExcMessage(
"Mapping collection needs to have either size 1 "
1268 "or size equal to the number of elements in "
1269 "the FECollection."));
1271 using cell_iterator =
1274 std::pair<cell_iterator, Point<dim>> best_cell;
1278 if (mapping.
size() == 1)
1286 double best_distance = 1
e-10;
1287 int best_level = -1;
1294 std::vector<cell_iterator> adjacent_cells_tmp =
1302 std::set<cell_iterator> adjacent_cells(adjacent_cells_tmp.begin(),
1303 adjacent_cells_tmp.end());
1304 std::set<cell_iterator> searched_cells;
1314 unsigned int cells_searched = 0;
1315 while (!found && cells_searched <
n_cells)
1317 typename std::set<cell_iterator>::const_iterator
1318 cell = adjacent_cells.begin(),
1319 endc = adjacent_cells.end();
1320 for (; cell != endc; ++cell)
1325 mapping[(*cell)->active_fe_index()]
1326 .transform_real_to_unit_cell(*cell, p);
1338 if (dist < best_distance || (dist == best_distance &&
1339 (*cell)->level() > best_level))
1342 best_distance = dist;
1343 best_level = (*cell)->level();
1344 best_cell = std::make_pair(*cell, p_cell);
1349 spacedim>::ExcTransformationFailed &)
1365 cells_searched += adjacent_cells.size();
1371 if (!found && cells_searched <
n_cells)
1373 find_active_cell_around_point_internal<dim,
1376 mesh, searched_cells, adjacent_cells);
1382 ExcPointNotFound<spacedim>(p));
1388 template <
class MeshType>
1389 std::vector<typename MeshType::active_cell_iterator>
1392 Assert(cell->is_locally_owned(),
1393 ExcMessage(
"This function only makes sense if the cell for "
1394 "which you are asking for a patch, is locally "
1397 std::vector<typename MeshType::active_cell_iterator> patch;
1398 patch.push_back(cell);
1399 for (
const unsigned int face_number :
1401 if (cell->face(face_number)->at_boundary() ==
false)
1403 if (cell->neighbor(face_number)->has_children() ==
false)
1404 patch.push_back(cell->neighbor(face_number));
1409 if (MeshType::dimension > 1)
1411 for (
unsigned int subface = 0;
1412 subface < cell->face(face_number)->n_children();
1415 cell->neighbor_child_on_subface(face_number, subface));
1421 typename MeshType::cell_iterator neighbor =
1422 cell->neighbor(face_number);
1423 while (neighbor->has_children())
1424 neighbor = neighbor->child(1 - face_number);
1426 Assert(neighbor->neighbor(1 - face_number) == cell,
1428 patch.push_back(neighbor);
1436 template <
class Container>
1437 std::vector<typename Container::cell_iterator>
1439 const std::vector<typename Container::active_cell_iterator> &patch)
1443 "Vector containing patch cells should not be an empty vector!"));
1447 int min_level = patch[0]->level();
1449 for (
unsigned int i = 0; i < patch.size(); ++i)
1451 std::set<typename Container::cell_iterator> uniform_cells;
1452 typename std::vector<
1453 typename Container::active_cell_iterator>::const_iterator patch_cell;
1455 for (patch_cell = patch.begin(); patch_cell != patch.end(); ++patch_cell)
1460 if ((*patch_cell)->level() == min_level)
1461 uniform_cells.insert(*patch_cell);
1468 typename Container::cell_iterator parent = *patch_cell;
1470 while (parent->level() > min_level)
1471 parent = parent->parent();
1472 uniform_cells.insert(parent);
1476 return std::vector<typename Container::cell_iterator>(uniform_cells.begin(),
1477 uniform_cells.end());
1482 template <
class Container>
1485 const std::vector<typename Container::active_cell_iterator> &patch,
1487 &local_triangulation,
1490 Container::space_dimension>::active_cell_iterator,
1491 typename Container::active_cell_iterator> &patch_to_global_tria_map)
1494 const std::vector<typename Container::cell_iterator> uniform_cells =
1495 get_cells_at_coarsest_common_level<Container>(patch);
1497 local_triangulation.
clear();
1498 std::vector<Point<Container::space_dimension>>
vertices;
1499 const unsigned int n_uniform_cells = uniform_cells.size();
1500 std::vector<CellData<Container::dimension>> cells(n_uniform_cells);
1503 typename std::vector<typename Container::cell_iterator>::const_iterator
1505 for (uniform_cell = uniform_cells.begin();
1506 uniform_cell != uniform_cells.end();
1509 for (
const unsigned int v :
1513 (*uniform_cell)->vertex(v);
1514 bool repeat_vertex =
false;
1516 for (
unsigned int m = 0; m < i; ++m)
1520 repeat_vertex =
true;
1521 cells[k].vertices[v] = m;
1525 if (repeat_vertex ==
false)
1528 cells[k].vertices[v] = i;
1539 unsigned int index = 0;
1542 Container::space_dimension>::cell_iterator,
1543 typename Container::cell_iterator>
1544 patch_to_global_tria_map_tmp;
1546 Container::space_dimension>::cell_iterator
1547 coarse_cell = local_triangulation.
begin();
1548 coarse_cell != local_triangulation.
end();
1549 ++coarse_cell, ++index)
1551 patch_to_global_tria_map_tmp.insert(
1552 std::make_pair(coarse_cell, uniform_cells[index]));
1556 Assert(coarse_cell->center().distance(uniform_cells[index]->center()) <=
1557 1
e-15 * coarse_cell->diameter(),
1560 bool refinement_necessary;
1565 refinement_necessary =
false;
1566 for (
const auto &active_tria_cell :
1569 if (patch_to_global_tria_map_tmp[active_tria_cell]->has_children())
1571 active_tria_cell->set_refine_flag();
1572 refinement_necessary =
true;
1575 for (
unsigned int i = 0; i < patch.size(); ++i)
1580 if (patch_to_global_tria_map_tmp[active_tria_cell] ==
1585 for (
const unsigned int v :
1587 active_tria_cell->vertex(v) = patch[i]->vertex(v);
1589 Assert(active_tria_cell->center().distance(
1590 patch_to_global_tria_map_tmp[active_tria_cell]
1592 1
e-15 * active_tria_cell->diameter(),
1595 active_tria_cell->set_user_flag();
1601 if (refinement_necessary)
1606 Container::dimension,
1607 Container::space_dimension>::cell_iterator cell =
1608 local_triangulation.
begin();
1609 cell != local_triangulation.
end();
1612 if (patch_to_global_tria_map_tmp.find(cell) !=
1613 patch_to_global_tria_map_tmp.end())
1615 if (cell->has_children())
1622 for (
unsigned int c = 0; c < cell->n_children(); ++c)
1624 if (patch_to_global_tria_map_tmp.find(cell->child(
1625 c)) == patch_to_global_tria_map_tmp.end())
1627 patch_to_global_tria_map_tmp.insert(
1630 patch_to_global_tria_map_tmp[cell]->child(
1652 patch_to_global_tria_map_tmp.erase(cell);
1658 while (refinement_necessary);
1664 Container::space_dimension>::cell_iterator
1665 cell = local_triangulation.
begin();
1666 cell != local_triangulation.
end();
1669 if (cell->user_flag_set())
1671 Assert(patch_to_global_tria_map_tmp.find(cell) !=
1672 patch_to_global_tria_map_tmp.end(),
1675 Assert(cell->center().distance(
1676 patch_to_global_tria_map_tmp[cell]->center()) <=
1677 1
e-15 * cell->diameter(),
1685 Container::space_dimension>::cell_iterator,
1686 typename Container::cell_iterator>::iterator
1687 map_tmp_it = patch_to_global_tria_map_tmp.
begin(),
1688 map_tmp_end = patch_to_global_tria_map_tmp.end();
1692 for (; map_tmp_it != map_tmp_end; ++map_tmp_it)
1693 patch_to_global_tria_map[map_tmp_it->first] = map_tmp_it->second;
1698 template <
class DoFHandlerType>
1700 std::vector<typename DoFHandlerType::active_cell_iterator>>
1714 std::set<typename DoFHandlerType::active_cell_iterator>>
1715 dof_to_set_of_cells_map;
1717 std::vector<types::global_dof_index> local_dof_indices;
1718 std::vector<types::global_dof_index> local_face_dof_indices;
1719 std::vector<types::global_dof_index> local_line_dof_indices;
1723 std::vector<bool> user_flags;
1728 std::map<
typename DoFHandlerType::active_line_iterator,
1729 typename DoFHandlerType::line_iterator>
1730 lines_to_parent_lines_map;
1731 if (DoFHandlerType::dimension == 3)
1734 dof_handler.get_triangulation().save_user_flags(user_flags);
1736 DoFHandlerType::space_dimension
> &>(
1737 dof_handler.get_triangulation())
1738 .clear_user_flags();
1741 typename DoFHandlerType::active_cell_iterator cell = dof_handler
1743 endc = dof_handler.end();
1744 for (; cell != endc; ++cell)
1750 if (cell->is_artificial() ==
false)
1752 for (
unsigned int l = 0;
1756 if (cell->line(
l)->has_children())
1757 for (
unsigned int c = 0; c < cell->line(
l)->n_children();
1760 lines_to_parent_lines_map[cell->line(
l)->child(c)] =
1764 cell->line(
l)->child(c)->set_user_flag();
1777 typename DoFHandlerType::active_cell_iterator cell =
1778 dof_handler.begin_active(),
1779 endc = dof_handler.end();
1780 for (; cell != endc; ++cell)
1785 if (cell->is_artificial() ==
false)
1787 const unsigned int n_dofs_per_cell = cell->get_fe().dofs_per_cell;
1788 local_dof_indices.resize(n_dofs_per_cell);
1792 cell->get_dof_indices(local_dof_indices);
1793 for (
unsigned int i = 0; i < n_dofs_per_cell; ++i)
1794 dof_to_set_of_cells_map[local_dof_indices[i]].insert(cell);
1804 for (
const unsigned int f :
1807 if (cell->face(f)->has_children())
1809 for (
unsigned int c = 0; c < cell->face(f)->n_children();
1824 Assert(cell->face(f)->child(c)->has_children() ==
false,
1827 const unsigned int n_dofs_per_face =
1828 cell->get_fe().dofs_per_face;
1829 local_face_dof_indices.resize(n_dofs_per_face);
1831 cell->face(f)->child(c)->get_dof_indices(
1832 local_face_dof_indices);
1833 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1834 dof_to_set_of_cells_map[local_face_dof_indices[i]]
1838 else if ((cell->face(f)->at_boundary() ==
false) &&
1839 (cell->neighbor_is_coarser(f)))
1856 std::pair<unsigned int, unsigned int>
1857 neighbor_face_no_subface_no =
1858 cell->neighbor_of_coarser_neighbor(f);
1859 unsigned int face_no = neighbor_face_no_subface_no.first;
1860 unsigned int subface = neighbor_face_no_subface_no.second;
1862 const unsigned int n_dofs_per_face =
1863 cell->get_fe().dofs_per_face;
1864 local_face_dof_indices.resize(n_dofs_per_face);
1866 cell->neighbor(f)->face(face_no)->get_dof_indices(
1867 local_face_dof_indices);
1868 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1869 dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(
1874 for (
unsigned int c = 0;
1875 c < cell->neighbor(f)->face(face_no)->n_children();
1881 const unsigned int n_dofs_per_face =
1882 cell->get_fe().dofs_per_face;
1883 local_face_dof_indices.resize(n_dofs_per_face);
1888 ->has_children() ==
false,
1893 ->get_dof_indices(local_face_dof_indices);
1894 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1895 dof_to_set_of_cells_map[local_face_dof_indices[i]]
1910 if (DoFHandlerType::dimension == 3)
1912 for (
unsigned int l = 0;
1917 if (cell->line(
l)->has_children())
1919 for (
unsigned int c = 0;
1920 c < cell->line(
l)->n_children();
1923 Assert(cell->line(
l)->child(c)->has_children() ==
1929 const unsigned int n_dofs_per_line =
1930 2 * cell->get_fe().dofs_per_vertex +
1931 cell->get_fe().dofs_per_line;
1932 local_line_dof_indices.resize(n_dofs_per_line);
1934 cell->line(
l)->child(c)->get_dof_indices(
1935 local_line_dof_indices);
1936 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
1937 dof_to_set_of_cells_map[local_line_dof_indices[i]]
1945 else if (cell->line(
l)->user_flag_set() ==
true)
1947 typename DoFHandlerType::line_iterator parent_line =
1948 lines_to_parent_lines_map[cell->line(
l)];
1953 const unsigned int n_dofs_per_line =
1954 2 * cell->get_fe().dofs_per_vertex +
1955 cell->get_fe().dofs_per_line;
1956 local_line_dof_indices.resize(n_dofs_per_line);
1958 parent_line->get_dof_indices(local_line_dof_indices);
1959 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
1960 dof_to_set_of_cells_map[local_line_dof_indices[i]]
1963 for (
unsigned int c = 0; c < parent_line->n_children();
1966 Assert(parent_line->child(c)->has_children() ==
1970 const unsigned int n_dofs_per_line =
1971 2 * cell->get_fe().dofs_per_vertex +
1972 cell->get_fe().dofs_per_line;
1973 local_line_dof_indices.resize(n_dofs_per_line);
1975 parent_line->child(c)->get_dof_indices(
1976 local_line_dof_indices);
1977 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
1978 dof_to_set_of_cells_map[local_line_dof_indices[i]]
1988 if (DoFHandlerType::dimension == 3)
1994 DoFHandlerType::space_dimension
> &>(
1995 dof_handler.get_triangulation())
1996 .load_user_flags(user_flags);
2002 std::vector<typename DoFHandlerType::active_cell_iterator>>
2003 dof_to_cell_patches;
2006 std::set<typename DoFHandlerType::active_cell_iterator>>::
2007 iterator it = dof_to_set_of_cells_map.begin(),
2008 it_end = dof_to_set_of_cells_map.end();
2009 for (; it != it_end; ++it)
2010 dof_to_cell_patches[it->first].assign(it->second.begin(),
2013 return dof_to_cell_patches;
2019 template <
typename CellIterator>
2022 std::set<std::pair<CellIterator, unsigned int>> &pairs1,
2025 const int direction,
2027 const ::Tensor<1, CellIterator::AccessorType::space_dimension>
2031 static const int space_dim = CellIterator::AccessorType::space_dimension;
2037 constexpr
int dim = CellIterator::AccessorType::dimension;
2038 constexpr
int spacedim = CellIterator::AccessorType::space_dimension;
2043 if (!(((pairs1.size() > 0) &&
2044 (
dynamic_cast<const parallel::fullydistributed::
2045 Triangulation<dim, spacedim> *
>(
2046 &pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2047 ((pairs2.size() > 0) &&
2050 *
>(&pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2051 Assert(pairs1.size() == pairs2.size(),
2052 ExcMessage(
"Unmatched faces on periodic boundaries"));
2056 unsigned int n_matches = 0;
2059 std::bitset<3> orientation;
2060 using PairIterator =
2061 typename std::set<std::pair<CellIterator, unsigned int>>::const_iterator;
2062 for (PairIterator it1 = pairs1.begin(); it1 != pairs1.end(); ++it1)
2064 for (PairIterator it2 = pairs2.begin(); it2 != pairs2.end(); ++it2)
2066 const CellIterator cell1 = it1->first;
2067 const CellIterator cell2 = it2->first;
2068 const unsigned int face_idx1 = it1->second;
2069 const unsigned int face_idx2 = it2->second;
2071 cell1->face(face_idx1),
2072 cell2->face(face_idx2),
2081 {cell1, cell2}, {face_idx1, face_idx2}, orientation,
matrix};
2082 matched_pairs.push_back(matched_face);
2096 constexpr
int dim = CellIterator::AccessorType::dimension;
2097 constexpr
int spacedim = CellIterator::AccessorType::space_dimension;
2098 if (!(((pairs1.size() > 0) &&
2099 (
dynamic_cast<const parallel::fullydistributed::
2100 Triangulation<dim, spacedim> *
>(
2101 &pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2102 ((pairs2.size() > 0) &&
2105 *
>(&pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2106 AssertThrow(n_matches == pairs1.size() && pairs2.size() == 0,
2107 ExcMessage(
"Unmatched faces on periodic boundaries"));
2113 template <
typename MeshType>
2116 const MeshType & mesh,
2118 const int direction,
2124 static const int dim = MeshType::dimension;
2125 static const int space_dim = MeshType::space_dimension;
2135 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs1;
2136 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs2;
2138 for (
typename MeshType::cell_iterator cell = mesh.begin(0);
2139 cell != mesh.end(0);
2142 const typename MeshType::face_iterator face_1 =
2143 cell->face(2 * direction);
2144 const typename MeshType::face_iterator face_2 =
2145 cell->face(2 * direction + 1);
2147 if (face_1->at_boundary() && face_1->boundary_id() == b_id)
2149 const std::pair<typename MeshType::cell_iterator, unsigned int>
2150 pair1 = std::make_pair(cell, 2 * direction);
2151 pairs1.insert(pair1);
2154 if (face_2->at_boundary() && face_2->boundary_id() == b_id)
2156 const std::pair<typename MeshType::cell_iterator, unsigned int>
2157 pair2 = std::make_pair(cell, 2 * direction + 1);
2158 pairs2.insert(pair2);
2162 Assert(pairs1.size() == pairs2.size(),
2163 ExcMessage(
"Unmatched faces on periodic boundaries"));
2165 Assert(pairs1.size() > 0,
2166 ExcMessage(
"No new periodic face pairs have been found. "
2167 "Are you sure that you've selected the correct boundary "
2168 "id's and that the coarsest level mesh is colorized?"));
2171 const unsigned int size_old = matched_pairs.size();
2176 pairs1, pairs2, direction, matched_pairs, offset,
matrix);
2180 const unsigned int size_new = matched_pairs.size();
2181 for (
unsigned int i = size_old; i < size_new; ++i)
2183 Assert(matched_pairs[i].orientation == 1,
2185 "Found a face match with non standard orientation. "
2186 "This function is only suitable for meshes with cells "
2187 "in default orientation"));
2194 template <
typename MeshType>
2197 const MeshType & mesh,
2200 const int direction,
2206 static const int dim = MeshType::dimension;
2207 static const int space_dim = MeshType::space_dimension;
2215 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs1;
2216 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs2;
2218 for (
typename MeshType::cell_iterator cell = mesh.begin(0);
2219 cell != mesh.end(0);
2224 const typename MeshType::face_iterator face = cell->face(i);
2225 if (face->at_boundary() && face->boundary_id() == b_id1)
2227 const std::pair<typename MeshType::cell_iterator, unsigned int>
2228 pair1 = std::make_pair(cell, i);
2229 pairs1.insert(pair1);
2232 if (face->at_boundary() && face->boundary_id() == b_id2)
2234 const std::pair<typename MeshType::cell_iterator, unsigned int>
2235 pair2 = std::make_pair(cell, i);
2236 pairs2.insert(pair2);
2247 if (!(((pairs1.size() > 0) &&
2250 *
>(&pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2251 ((pairs2.size() > 0) &&
2254 *
>(&pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2255 Assert(pairs1.size() == pairs2.size(),
2256 ExcMessage(
"Unmatched faces on periodic boundaries"));
2259 (pairs1.size() > 0 ||
2262 &mesh.begin()->get_triangulation()) !=
nullptr)),
2263 ExcMessage(
"No new periodic face pairs have been found. "
2264 "Are you sure that you've selected the correct boundary "
2265 "id's and that the coarsest level mesh is colorized?"));
2269 pairs1, pairs2, direction, matched_pairs, offset,
matrix);
2283 template <
int spacedim>
2287 const int direction,
2297 if (
matrix.m() == spacedim)
2298 for (
int i = 0; i < spacedim; ++i)
2299 for (
int j = 0; j < spacedim; ++j)
2300 distance(i) +=
matrix(i, j) * point1(j);
2304 distance += offset - point2;
2306 for (
int i = 0; i < spacedim; ++i)
2312 if (std::abs(distance(i)) > 1.
e-10)
2338 std::array<unsigned int, GeometryInfo<1>::vertices_per_face>;
2339 static inline std::bitset<3>
2351 std::array<unsigned int, GeometryInfo<2>::vertices_per_face>;
2352 static inline std::bitset<3>
2360 static const MATCH_T m_tff = {{0, 1}};
2361 if (matching == m_tff)
2363 static const MATCH_T m_ttf = {{1, 0}};
2364 if (matching == m_ttf)
2377 std::array<unsigned int, GeometryInfo<3>::vertices_per_face>;
2378 static inline std::bitset<3>
2386 static const MATCH_T m_tff = {{0, 1, 2, 3}};
2387 if (matching == m_tff)
2389 static const MATCH_T m_tft = {{1, 3, 0, 2}};
2390 if (matching == m_tft)
2392 static const MATCH_T m_ttf = {{3, 2, 1, 0}};
2393 if (matching == m_ttf)
2395 static const MATCH_T m_ttt = {{2, 0, 3, 1}};
2396 if (matching == m_ttt)
2398 static const MATCH_T m_fff = {{0, 2, 1, 3}};
2399 if (matching == m_fff)
2401 static const MATCH_T m_fft = {{2, 3, 0, 1}};
2402 if (matching == m_fft)
2404 static const MATCH_T m_ftf = {{3, 1, 2, 0}};
2405 if (matching == m_ftf)
2407 static const MATCH_T m_ftt = {{1, 0, 3, 2}};
2408 if (matching == m_ftt)
2419 template <
typename FaceIterator>
2421 std::bitset<3> & orientation,
2422 const FaceIterator & face1,
2423 const FaceIterator & face2,
2424 const int direction,
2429 ExcMessage(
"The supplied matrix must be a square matrix"));
2431 static const int dim = FaceIterator::AccessorType::dimension;
2435 std::array<unsigned int, GeometryInfo<dim>::vertices_per_face> matching;
2437 std::set<unsigned int> face2_vertices;
2438 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face; ++i)
2439 face2_vertices.insert(i);
2441 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face; ++i)
2443 for (std::set<unsigned int>::iterator it = face2_vertices.begin();
2444 it != face2_vertices.end();
2454 face2_vertices.erase(it);
2461 if (face2_vertices.empty())
2464 return face2_vertices.empty();
2469 template <
typename FaceIterator>
2472 const FaceIterator & face1,
2473 const FaceIterator & face2,
2474 const int direction,
2479 std::bitset<3>
dummy;
2488 #include "grid_tools_dof_handlers.inst"