54 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
58 const
Point<spacedim> &p,
59 const
std::vector<
bool> &marked_vertices)
70 marked_vertices.empty(),
72 marked_vertices.size()));
82 marked_vertices.empty() ||
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 =
102 std::vector<bool>::const_iterator
first =
103 std::find(used.begin(), used.end(),
true);
109 unsigned int best_vertex = std::distance(used.begin(),
first);
110 double best_dist = (p -
vertices[best_vertex]).norm_square();
114 for (
unsigned int j = best_vertex + 1; j <
vertices.size(); ++j)
117 double dist = (p -
vertices[j]).norm_square();
118 if (dist < best_dist)
130 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
134 const MeshType<dim, spacedim> &mesh,
135 const
Point<spacedim> &p,
136 const
std::vector<
bool> &marked_vertices)
139 if (mapping.preserves_vertex_locations() ==
true)
151 marked_vertices.empty(),
153 marked_vertices.size()));
163 marked_vertices.empty() ||
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 <
typename MeshType>
194 std::vector<typename MeshType::active_cell_iterator>
197 typename ::internal::ActiveCellIterator<MeshType::dimension,
198 MeshType::space_dimension,
202 const unsigned int vertex)
204 const int dim = MeshType::dimension;
205 const int spacedim = MeshType::space_dimension;
211 Assert(mesh.get_triangulation().get_used_vertices()[vertex],
217 std::set<typename ::internal::
218 ActiveCellIterator<dim, spacedim, MeshType>::type>
221 typename ::internal::ActiveCellIterator<dim, spacedim, MeshType>::type
222 cell = mesh.begin_active(),
258 for (; cell != endc; ++cell)
260 for (
const unsigned int v : cell->vertex_indices())
261 if (cell->vertex_index(v) == vertex)
274 const auto reference_cell = cell->reference_cell();
275 for (
const auto face :
276 reference_cell.faces_for_given_vertex(v))
277 if (!cell->at_boundary(face) &&
278 cell->neighbor(face)->is_active())
301 for (
unsigned int e = 0; e < cell->n_lines(); ++e)
302 if (cell->line(e)->has_children())
306 if (cell->line(e)->child(0)->vertex_index(1) == vertex)
329 return std::vector<typename ::internal::
330 ActiveCellIterator<dim, spacedim, MeshType>::type>(
338 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
341 void find_active_cell_around_point_internal(
342 const MeshType<dim, spacedim> &mesh,
344 std::set<typename MeshType<dim, spacedim>::active_cell_iterator>
346 std::set<typename MeshType<dim, spacedim>::active_cell_iterator>
350 typename ::internal::
351 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
355 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
360 using cell_iterator =
361 typename MeshType<dim, spacedim>::active_cell_iterator;
363 using cell_iterator = typename ::internal::
364 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type;
372 std::set<cell_iterator> adjacent_cells_new;
376 std::vector<cell_iterator> active_neighbors;
378 for (
unsigned int i = 0; i < active_neighbors.size(); ++i)
379 if (searched_cells.find(active_neighbors[i]) ==
380 searched_cells.end())
381 adjacent_cells_new.insert(active_neighbors[i]);
385 adjacent_cells_new.end());
394 cell_iterator it = mesh.begin_active();
395 for (; it != mesh.end(); ++it)
396 if (searched_cells.find(it) == searched_cells.end())
407 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
411 typename MeshType<dim, spacedim>::active_cell_iterator
413 typename ::internal::
414 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type
418 const std::vector<bool> &marked_vertices,
419 const double tolerance)
432 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
436 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim>>
438 std::pair<typename ::internal::
439 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
443 const MeshType<dim, spacedim> &mesh,
445 const std::vector<bool> &marked_vertices,
446 const double tolerance)
448 using active_cell_iterator = typename ::internal::
449 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type;
455 double best_distance = tolerance;
457 std::pair<active_cell_iterator, Point<dim>> best_cell;
460 best_cell.first = mesh.end();
464 std::vector<active_cell_iterator> adjacent_cells_tmp =
473 std::set<active_cell_iterator>
adjacent_cells(adjacent_cells_tmp.begin(),
474 adjacent_cells_tmp.end());
475 std::set<active_cell_iterator> searched_cells;
483 const auto n_active_cells = mesh.get_triangulation().n_active_cells();
485 unsigned int cells_searched = 0;
486 while (!found && cells_searched < n_active_cells)
490 if (cell->is_artificial() ==
false)
493 if (marked_vertices.size() > 0)
495 bool any_vertex_marked =
false;
496 for (
const auto &v : cell->vertex_indices())
498 if (marked_vertices[cell->vertex_index(v)])
500 any_vertex_marked =
true;
504 if (!any_vertex_marked)
516 cell->reference_cell().closest_point(p_cell).distance(
523 if ((dist < best_distance) ||
524 ((dist == best_distance) &&
525 (cell->level() > best_level)))
528 best_distance = dist;
529 best_level = cell->level();
530 best_cell = std::make_pair(cell, p_cell);
561 if (!found && cells_searched < n_active_cells)
563 find_active_cell_around_point_internal<dim, MeshType, spacedim>(
573 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
577 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
580 std::vector<std::pair<
581 typename ::internal::
582 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
586 const MeshType<dim, spacedim> &mesh,
588 const double tolerance,
589 const std::vector<bool> &marked_vertices)
592 mapping, mesh, p, marked_vertices, tolerance);
594 if (cell_and_point.first == mesh.end())
598 mapping, mesh, p, tolerance, cell_and_point);
603 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
607 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
610 std::vector<std::pair<
611 typename ::internal::
612 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
617 const MeshType<dim, spacedim> &mesh,
619 const double tolerance,
620 const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
623 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator>>
627 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
632 cells_and_points.push_back(first_cell);
634 const Point<dim> unit_point = cells_and_points.front().second;
635 const auto my_cell = cells_and_points.front().first;
637 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
640 if (my_cell->reference_cell().is_hyper_cube())
646 unsigned int n_dirs_at_threshold = 0;
648 for (
unsigned int d = 0; d < dim; ++d)
650 distance_to_center[d] =
std::abs(unit_point[d] - 0.5);
651 if (distance_to_center[d] > 0.5 - tolerance)
653 ++n_dirs_at_threshold;
654 last_point_at_threshold = d;
659 if (n_dirs_at_threshold == 1)
661 unsigned int neighbor_index =
662 2 * last_point_at_threshold +
663 (unit_point[last_point_at_threshold] > 0.5 ? 1 : 0);
664 if (!my_cell->at_boundary(neighbor_index))
666 const auto neighbor_cell = my_cell->neighbor(neighbor_index);
668 if (neighbor_cell->is_active())
669 cells_to_add.push_back(neighbor_cell);
671 for (
const auto &child_cell :
672 neighbor_cell->child_iterators())
674 if (child_cell->is_active())
675 cells_to_add.push_back(child_cell);
680 else if (n_dirs_at_threshold == dim)
682 unsigned int local_vertex_index = 0;
683 for (
unsigned int d = 0; d < dim; ++d)
684 local_vertex_index += (unit_point[d] > 0.5 ? 1 : 0) << d;
686 const auto fu = [&](
const auto &tentative_cells) {
687 for (
const auto &cell : tentative_cells)
689 cells_to_add.push_back(cell);
692 const auto vertex_index = my_cell->vertex_index(local_vertex_index);
694 if (vertex_to_cells !=
nullptr)
695 fu((*vertex_to_cells)[vertex_index]);
704 else if (n_dirs_at_threshold == 2)
707 unsigned int count_vertex_indices = 0;
709 for (
unsigned int d = 0; d < dim; ++d)
711 if (distance_to_center[d] > 0.5 - tolerance)
715 unit_point[d] > 0.5 ? 1 : 0;
716 ++count_vertex_indices;
726 const unsigned int first_vertex =
729 for (
unsigned int d = 0; d < 2; ++d)
731 const auto fu = [&](
const auto &tentative_cells) {
732 for (
const auto &cell : tentative_cells)
734 bool cell_not_yet_present =
true;
735 for (
const auto &other_cell : cells_to_add)
736 if (cell == other_cell)
738 cell_not_yet_present =
false;
741 if (cell_not_yet_present)
742 cells_to_add.push_back(cell);
746 const auto vertex_index =
747 my_cell->vertex_index(first_vertex + (d << free_direction));
749 if (vertex_to_cells !=
nullptr)
750 fu((*vertex_to_cells)[vertex_index]);
764 for (
const auto v : my_cell->vertex_indices())
766 const auto fu = [&](
const auto &tentative_cells) {
767 for (
const auto &cell : tentative_cells)
769 bool cell_not_yet_present =
true;
770 for (
const auto &other_cell : cells_to_add)
771 if (cell == other_cell)
773 cell_not_yet_present =
false;
776 if (cell_not_yet_present)
777 cells_to_add.push_back(cell);
781 const auto vertex_index = my_cell->vertex_index(v);
783 if (vertex_to_cells !=
nullptr)
784 fu((*vertex_to_cells)[vertex_index]);
790 for (
const auto &cell : cells_to_add)
797 if (cell->reference_cell().contains_point(p_unit, tolerance))
798 cells_and_points.emplace_back(cell, p_unit);
805 cells_and_points.begin(),
806 cells_and_points.end(),
807 [](
const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
809 const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
810 Point<dim>> &b) { return a.first < b.first; });
812 return cells_and_points;
817 template <
typename MeshType>
821 const MeshType &mesh,
822 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
825 std::vector<typename MeshType::active_cell_iterator> active_halo_layer;
826 std::vector<bool> locally_active_vertices_on_subdomain(
827 mesh.get_triangulation().n_vertices(),
false);
829 std::map<unsigned int, std::vector<unsigned int>> coinciding_vertex_groups;
830 std::map<unsigned int, unsigned int> vertex_to_coinciding_vertex_group;
832 coinciding_vertex_groups,
833 vertex_to_coinciding_vertex_group);
838 for (
const auto &cell : mesh.active_cell_iterators())
840 for (
const auto v : cell->vertex_indices())
842 locally_active_vertices_on_subdomain[cell->vertex_index(v)] =
true;
843 for (
const auto vv : coinciding_vertex_groups
844 [vertex_to_coinciding_vertex_group[cell->vertex_index(v)]])
845 locally_active_vertices_on_subdomain[vv] =
true;
851 for (
const auto &cell : mesh.active_cell_iterators())
852 if (!predicate(cell))
853 for (
const auto v : cell->vertex_indices())
854 if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] ==
857 active_halo_layer.push_back(cell);
861 return active_halo_layer;
866 template <
typename MeshType>
870 const MeshType &mesh,
871 const std::function<
bool(
const typename MeshType::cell_iterator &)>
873 const unsigned int level)
875 std::vector<typename MeshType::cell_iterator> level_halo_layer;
876 std::vector<bool> locally_active_vertices_on_level_subdomain(
877 mesh.get_triangulation().n_vertices(),
false);
882 for (
typename MeshType::cell_iterator cell = mesh.begin(
level);
883 cell != mesh.end(
level);
886 for (
const unsigned int v : cell->vertex_indices())
887 locally_active_vertices_on_level_subdomain[cell->vertex_index(v)] =
893 for (
typename MeshType::cell_iterator cell = mesh.begin(
level);
894 cell != mesh.end(
level);
896 if (!predicate(cell))
897 for (
const unsigned int v : cell->vertex_indices())
898 if (locally_active_vertices_on_level_subdomain[cell->vertex_index(
901 level_halo_layer.push_back(cell);
905 return level_halo_layer;
911 template <
typename MeshType>
913 bool contains_locally_owned_cells(
914 const std::vector<typename MeshType::active_cell_iterator> &cells)
916 for (
typename std::vector<
917 typename MeshType::active_cell_iterator>::const_iterator it =
922 if ((*it)->is_locally_owned())
928 template <
typename MeshType>
930 bool contains_artificial_cells(
931 const std::vector<typename MeshType::active_cell_iterator> &cells)
933 for (
typename std::vector<
934 typename MeshType::active_cell_iterator>::const_iterator it =
939 if ((*it)->is_artificial())
948 template <
typename MeshType>
954 std::function<
bool(
const typename MeshType::active_cell_iterator &)>
957 const std::vector<typename MeshType::active_cell_iterator>
962 Assert(contains_locally_owned_cells<MeshType>(active_halo_layer) ==
false,
963 ExcMessage(
"Halo layer contains locally owned cells"));
964 Assert(contains_artificial_cells<MeshType>(active_halo_layer) ==
false,
965 ExcMessage(
"Halo layer contains artificial cells"));
967 return active_halo_layer;
972 template <
typename MeshType>
976 const MeshType &mesh,
977 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
979 const double layer_thickness)
981 std::vector<typename MeshType::active_cell_iterator>
982 subdomain_boundary_cells, active_cell_layer_within_distance;
983 std::vector<bool> vertices_outside_subdomain(
984 mesh.get_triangulation().n_vertices(),
false);
986 const unsigned int spacedim = MeshType::space_dimension;
988 unsigned int n_non_predicate_cells = 0;
996 for (
const auto &cell : mesh.active_cell_iterators())
997 if (!predicate(cell))
999 for (
const unsigned int v : cell->vertex_indices())
1000 vertices_outside_subdomain[cell->vertex_index(v)] =
true;
1001 ++n_non_predicate_cells;
1008 if (n_non_predicate_cells == 0 ||
1009 n_non_predicate_cells == mesh.get_triangulation().n_active_cells())
1010 return std::vector<typename MeshType::active_cell_iterator>();
1014 for (
const auto &cell : mesh.active_cell_iterators())
1015 if (predicate(cell))
1017 for (
const unsigned int v : cell->vertex_indices())
1018 if (vertices_outside_subdomain[cell->vertex_index(v)] ==
true)
1020 subdomain_boundary_cells.push_back(cell);
1030 const double DOUBLE_EPSILON = 100. * std::numeric_limits<double>::epsilon();
1033 for (
unsigned int d = 0; d < spacedim; ++d)
1035 bounding_box.first[d] -= (layer_thickness + DOUBLE_EPSILON);
1036 bounding_box.second[d] += (layer_thickness + DOUBLE_EPSILON);
1039 std::vector<Point<spacedim>>
1040 subdomain_boundary_cells_centers;
1043 subdomain_boundary_cells_radii;
1045 subdomain_boundary_cells_centers.reserve(subdomain_boundary_cells.size());
1046 subdomain_boundary_cells_radii.reserve(subdomain_boundary_cells.size());
1048 for (
typename std::vector<typename MeshType::active_cell_iterator>::
1049 const_iterator subdomain_boundary_cell_iterator =
1050 subdomain_boundary_cells.begin();
1051 subdomain_boundary_cell_iterator != subdomain_boundary_cells.end();
1052 ++subdomain_boundary_cell_iterator)
1054 const std::pair<Point<spacedim>,
double>
1055 &subdomain_boundary_cell_enclosing_ball =
1056 (*subdomain_boundary_cell_iterator)->enclosing_ball();
1058 subdomain_boundary_cells_centers.push_back(
1059 subdomain_boundary_cell_enclosing_ball.first);
1060 subdomain_boundary_cells_radii.push_back(
1061 subdomain_boundary_cell_enclosing_ball.second);
1063 AssertThrow(subdomain_boundary_cells_radii.size() ==
1064 subdomain_boundary_cells_centers.size(),
1073 for (
const auto &cell : mesh.active_cell_iterators())
1076 if (predicate(cell))
1079 const std::pair<Point<spacedim>,
double> &cell_enclosing_ball =
1080 cell->enclosing_ball();
1083 cell_enclosing_ball.first;
1084 const double cell_enclosing_ball_radius = cell_enclosing_ball.second;
1086 bool cell_inside =
true;
1088 for (
unsigned int d = 0; d < spacedim; ++d)
1090 (cell_enclosing_ball_center[d] + cell_enclosing_ball_radius >
1091 bounding_box.first[d]) &&
1092 (cell_enclosing_ball_center[d] - cell_enclosing_ball_radius <
1093 bounding_box.second[d]);
1099 for (
unsigned int i = 0; i < subdomain_boundary_cells_radii.size();
1102 subdomain_boundary_cells_centers[i]) <
1104 subdomain_boundary_cells_radii[i] +
1105 layer_thickness + DOUBLE_EPSILON))
1107 active_cell_layer_within_distance.push_back(cell);
1112 return active_cell_layer_within_distance;
1117 template <
typename MeshType>
1127 std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1128 predicate(locally_owned_cell_predicate);
1130 const std::vector<typename MeshType::active_cell_iterator>
1131 ghost_cell_layer_within_distance =
1139 contains_locally_owned_cells<MeshType>(
1140 ghost_cell_layer_within_distance) ==
false,
1142 "Ghost cells within layer_thickness contains locally owned cells."));
1144 contains_artificial_cells<MeshType>(ghost_cell_layer_within_distance) ==
1147 "Ghost cells within layer_thickness contains artificial cells. "
1148 "The function compute_ghost_cell_layer_within_distance "
1149 "is probably called while using parallel::distributed::Triangulation. "
1150 "In such case please refer to the description of this function."));
1152 return ghost_cell_layer_within_distance;
1157 template <
typename MeshType>
1163 const std::function<
bool(
1164 const typename MeshType::
1165 active_cell_iterator &)>
1168 std::vector<bool> locally_active_vertices_on_subdomain(
1169 mesh.get_triangulation().n_vertices(),
false);
1171 const unsigned int spacedim = MeshType::space_dimension;
1178 for (
const auto &cell : mesh.active_cell_iterators())
1179 if (predicate(cell))
1181 minp = cell->center();
1182 maxp = cell->center();
1188 for (
const auto &cell : mesh.active_cell_iterators())
1189 if (predicate(cell))
1190 for (
const unsigned int v : cell->vertex_indices())
1191 if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] ==
1194 locally_active_vertices_on_subdomain[cell->vertex_index(v)] =
1196 for (
unsigned int d = 0; d < spacedim; ++d)
1198 minp[d] =
std::min(minp[d], cell->vertex(v)[d]);
1199 maxp[d] =
std::max(maxp[d], cell->vertex(v)[d]);
1203 return std::make_pair(minp, maxp);
1208 template <
typename MeshType>
1210 std::list<std::pair<
1211 typename MeshType::cell_iterator,
1218 ExcMessage(
"The two meshes must be represent triangulations that "
1219 "have the same coarse meshes"));
1226 bool remove_ghost_cells =
false;
1227#ifdef DEAL_II_WITH_MPI
1229 constexpr int dim = MeshType::dimension;
1230 constexpr int spacedim = MeshType::space_dimension;
1232 *
>(&mesh_1.get_triangulation()) !=
nullptr ||
1234 *
>(&mesh_2.get_triangulation()) !=
nullptr)
1236 Assert(&mesh_1.get_triangulation() == &mesh_2.get_triangulation(),
1237 ExcMessage(
"This function can only be used with meshes "
1238 "corresponding to distributed Triangulations when "
1239 "both Triangulations are equal."));
1240 remove_ghost_cells =
true;
1252 using CellList = std::list<std::pair<
typename MeshType::cell_iterator,
1253 typename MeshType::cell_iterator>>;
1257 typename MeshType::cell_iterator cell_1 = mesh_1.begin(0),
1258 cell_2 = mesh_2.begin(0);
1259 for (; cell_1 != mesh_1.end(0); ++cell_1, ++cell_2)
1260 cell_list.emplace_back(cell_1, cell_2);
1263 typename CellList::iterator cell_pair = cell_list.begin();
1264 while (cell_pair != cell_list.end())
1268 if (cell_pair->first->has_children() &&
1269 cell_pair->second->has_children())
1271 Assert(cell_pair->first->refinement_case() ==
1272 cell_pair->second->refinement_case(),
1274 for (
unsigned int c = 0; c < cell_pair->first->n_children(); ++c)
1275 cell_list.emplace_back(cell_pair->first->child(c),
1276 cell_pair->second->child(c));
1281 const auto previous_cell_pair = cell_pair;
1283 cell_list.erase(previous_cell_pair);
1288 if (remove_ghost_cells &&
1289 ((cell_pair->first->is_active() &&
1290 !cell_pair->first->is_locally_owned()) ||
1291 (cell_pair->second->is_active() &&
1292 !cell_pair->second->is_locally_owned())))
1295 const auto previous_cell_pair = cell_pair;
1297 cell_list.erase(previous_cell_pair);
1306 for (cell_pair = cell_list.begin(); cell_pair != cell_list.end();
1308 Assert(cell_pair->first->is_active() || cell_pair->second->is_active() ||
1309 (cell_pair->first->refinement_case() !=
1310 cell_pair->second->refinement_case()),
1318 template <
int dim,
int spacedim>
1335 endc = mesh_1.
end(0);
1336 for (; cell_1 != endc; ++cell_1, ++cell_2)
1338 if (cell_1->n_vertices() != cell_2->n_vertices())
1340 for (
const unsigned int v : cell_1->vertex_indices())
1341 if (cell_1->vertex(v) != cell_2->vertex(v))
1354 template <
typename MeshType>
1359 mesh_2.get_triangulation());
1364 template <
int dim,
int spacedim>
1365 std::pair<typename DoFHandler<dim, spacedim>::active_cell_iterator,
1371 const double tolerance)
1375 ExcMessage(
"Mapping collection needs to have either size 1 "
1376 "or size equal to the number of elements in "
1377 "the FECollection."));
1379 using cell_iterator =
1382 std::pair<cell_iterator, Point<dim>> best_cell;
1386 if (mapping.
size() == 1)
1388 const std::vector<bool> marked_vertices = {};
1390 mapping[0], mesh, p, marked_vertices, tolerance);
1397 double best_distance = tolerance;
1398 int best_level = -1;
1405 std::vector<cell_iterator> adjacent_cells_tmp =
1413 std::set<cell_iterator>
adjacent_cells(adjacent_cells_tmp.begin(),
1414 adjacent_cells_tmp.end());
1415 std::set<cell_iterator> searched_cells;
1425 unsigned int cells_searched = 0;
1426 while (!found && cells_searched < n_cells)
1433 mapping[cell->active_fe_index()]
1434 .transform_real_to_unit_cell(cell, p);
1440 cell->reference_cell().closest_point(p_cell).distance(
1447 if (dist < best_distance ||
1448 (dist == best_distance && cell->level() > best_level))
1451 best_distance = dist;
1452 best_level = cell->level();
1453 best_cell = std::make_pair(cell, p_cell);
1479 if (!found && cells_searched < n_cells)
1481 find_active_cell_around_point_internal<dim,
1493 template <
typename MeshType>
1496 const typename MeshType::active_cell_iterator &cell)
1498 Assert(cell->is_locally_owned(),
1499 ExcMessage(
"This function only makes sense if the cell for "
1500 "which you are asking for a patch, is locally "
1503 std::vector<typename MeshType::active_cell_iterator> patch;
1504 patch.push_back(cell);
1505 for (
const unsigned int face_number : cell->face_indices())
1506 if (cell->face(face_number)->at_boundary() ==
false)
1508 if (cell->neighbor(face_number)->has_children() ==
false)
1509 patch.push_back(cell->neighbor(face_number));
1514 if (MeshType::dimension > 1)
1516 for (
unsigned int subface = 0;
1517 subface < cell->face(face_number)->n_children();
1520 cell->neighbor_child_on_subface(face_number, subface));
1526 typename MeshType::cell_iterator neighbor =
1527 cell->neighbor(face_number);
1528 while (neighbor->has_children())
1529 neighbor = neighbor->child(1 - face_number);
1531 Assert(neighbor->neighbor(1 - face_number) == cell,
1533 patch.push_back(neighbor);
1541 template <
class Container>
1542 std::vector<typename Container::cell_iterator>
1544 const std::vector<typename Container::active_cell_iterator> &patch)
1548 "Vector containing patch cells should not be an empty vector!"));
1552 int min_level = patch[0]->level();
1554 for (
unsigned int i = 0; i < patch.size(); ++i)
1556 std::set<typename Container::cell_iterator> uniform_cells;
1557 typename std::vector<
1558 typename Container::active_cell_iterator>::const_iterator patch_cell;
1560 for (patch_cell = patch.begin(); patch_cell != patch.end(); ++patch_cell)
1565 if ((*patch_cell)->level() == min_level)
1566 uniform_cells.insert(*patch_cell);
1573 typename Container::cell_iterator parent = *patch_cell;
1575 while (parent->level() > min_level)
1576 parent = parent->parent();
1577 uniform_cells.insert(parent);
1581 return std::vector<typename Container::cell_iterator>(uniform_cells.begin(),
1582 uniform_cells.end());
1587 template <
class Container>
1590 const std::vector<typename Container::active_cell_iterator> &patch,
1592 &local_triangulation,
1595 Container::space_dimension>::active_cell_iterator,
1596 typename Container::active_cell_iterator> &patch_to_global_tria_map)
1599 const std::vector<typename Container::cell_iterator> uniform_cells =
1602 local_triangulation.
clear();
1603 std::vector<Point<Container::space_dimension>>
vertices;
1604 const unsigned int n_uniform_cells = uniform_cells.size();
1605 std::vector<CellData<Container::dimension>> cells(n_uniform_cells);
1608 typename std::vector<typename Container::cell_iterator>::const_iterator
1610 for (uniform_cell = uniform_cells.begin();
1611 uniform_cell != uniform_cells.end();
1614 for (
const unsigned int v : (*uniform_cell)->vertex_indices())
1617 (*uniform_cell)->vertex(v);
1618 bool repeat_vertex =
false;
1620 for (
unsigned int m = 0; m < i; ++m)
1624 repeat_vertex =
true;
1625 cells[k].vertices[v] = m;
1629 if (repeat_vertex ==
false)
1632 cells[k].vertices[v] = i;
1643 unsigned int index = 0;
1646 Container::space_dimension>::cell_iterator,
1647 typename Container::cell_iterator>
1648 patch_to_global_tria_map_tmp;
1650 Container::space_dimension>::cell_iterator
1651 coarse_cell = local_triangulation.
begin();
1652 coarse_cell != local_triangulation.
end();
1653 ++coarse_cell, ++index)
1655 patch_to_global_tria_map_tmp.insert(
1656 std::make_pair(coarse_cell, uniform_cells[index]));
1660 Assert(coarse_cell->center().distance(uniform_cells[index]->center()) <=
1661 1e-15 * coarse_cell->diameter(),
1664 bool refinement_necessary;
1669 refinement_necessary =
false;
1670 for (
const auto &active_tria_cell :
1673 if (patch_to_global_tria_map_tmp[active_tria_cell]->has_children())
1675 active_tria_cell->set_refine_flag();
1676 refinement_necessary =
true;
1679 for (
unsigned int i = 0; i < patch.size(); ++i)
1684 if (patch_to_global_tria_map_tmp[active_tria_cell] ==
1689 for (
const unsigned int v :
1690 active_tria_cell->vertex_indices())
1691 active_tria_cell->vertex(v) = patch[i]->vertex(v);
1693 Assert(active_tria_cell->center().distance(
1694 patch_to_global_tria_map_tmp[active_tria_cell]
1696 1e-15 * active_tria_cell->diameter(),
1699 active_tria_cell->set_user_flag();
1705 if (refinement_necessary)
1710 Container::dimension,
1711 Container::space_dimension>::cell_iterator cell =
1712 local_triangulation.
begin();
1713 cell != local_triangulation.
end();
1716 if (patch_to_global_tria_map_tmp.find(cell) !=
1717 patch_to_global_tria_map_tmp.end())
1719 if (cell->has_children())
1726 for (
unsigned int c = 0; c < cell->n_children(); ++c)
1728 if (patch_to_global_tria_map_tmp.find(cell->child(
1729 c)) == patch_to_global_tria_map_tmp.end())
1731 patch_to_global_tria_map_tmp.insert(
1734 patch_to_global_tria_map_tmp[cell]->child(
1756 patch_to_global_tria_map_tmp.erase(cell);
1762 while (refinement_necessary);
1768 Container::space_dimension>::cell_iterator
1769 cell = local_triangulation.
begin();
1770 cell != local_triangulation.
end();
1773 if (cell->user_flag_set())
1775 Assert(patch_to_global_tria_map_tmp.find(cell) !=
1776 patch_to_global_tria_map_tmp.end(),
1779 Assert(cell->center().distance(
1780 patch_to_global_tria_map_tmp[cell]->center()) <=
1781 1e-15 * cell->diameter(),
1789 Container::space_dimension>::cell_iterator,
1790 typename Container::cell_iterator>::iterator
1791 map_tmp_it = patch_to_global_tria_map_tmp.
begin(),
1792 map_tmp_end = patch_to_global_tria_map_tmp.end();
1796 for (; map_tmp_it != map_tmp_end; ++map_tmp_it)
1797 patch_to_global_tria_map[map_tmp_it->first] = map_tmp_it->second;
1802 template <
int dim,
int spacedim>
1805 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
1819 std::set<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
1820 dof_to_set_of_cells_map;
1822 std::vector<types::global_dof_index> local_dof_indices;
1823 std::vector<types::global_dof_index> local_face_dof_indices;
1824 std::vector<types::global_dof_index> local_line_dof_indices;
1828 std::vector<bool> user_flags;
1833 std::map<typename DoFHandler<dim, spacedim>::active_line_iterator,
1835 lines_to_parent_lines_map;
1842 .clear_user_flags();
1847 endc = dof_handler.
end();
1848 for (; cell != endc; ++cell)
1854 if (cell->is_artificial() ==
false)
1856 for (
unsigned int l = 0; l < cell->n_lines(); ++l)
1857 if (cell->line(l)->has_children())
1858 for (
unsigned int c = 0; c < cell->line(l)->n_children();
1861 lines_to_parent_lines_map[cell->line(l)->child(c)] =
1865 cell->line(l)->child(c)->set_user_flag();
1880 endc = dof_handler.
end();
1881 for (; cell != endc; ++cell)
1886 if (cell->is_artificial() ==
false)
1888 const unsigned int n_dofs_per_cell =
1890 local_dof_indices.resize(n_dofs_per_cell);
1894 cell->get_dof_indices(local_dof_indices);
1895 for (
unsigned int i = 0; i < n_dofs_per_cell; ++i)
1896 dof_to_set_of_cells_map[local_dof_indices[i]].insert(cell);
1906 for (
const unsigned int f : cell->face_indices())
1908 if (cell->face(f)->has_children())
1910 for (
unsigned int c = 0; c < cell->face(f)->n_children();
1925 Assert(cell->face(f)->child(c)->has_children() ==
false,
1928 const unsigned int n_dofs_per_face =
1930 local_face_dof_indices.resize(n_dofs_per_face);
1932 cell->face(f)->child(c)->get_dof_indices(
1933 local_face_dof_indices);
1934 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1935 dof_to_set_of_cells_map[local_face_dof_indices[i]]
1939 else if ((cell->face(f)->at_boundary() ==
false) &&
1940 (cell->neighbor_is_coarser(f)))
1957 std::pair<unsigned int, unsigned int>
1958 neighbor_face_no_subface_no =
1959 cell->neighbor_of_coarser_neighbor(f);
1960 unsigned int face_no = neighbor_face_no_subface_no.first;
1961 unsigned int subface = neighbor_face_no_subface_no.second;
1963 const unsigned int n_dofs_per_face =
1965 local_face_dof_indices.resize(n_dofs_per_face);
1967 cell->neighbor(f)->face(face_no)->get_dof_indices(
1968 local_face_dof_indices);
1969 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1970 dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(
1975 for (
unsigned int c = 0;
1976 c < cell->neighbor(f)->face(face_no)->n_children();
1982 const unsigned int n_dofs_per_face =
1984 local_face_dof_indices.resize(n_dofs_per_face);
1989 ->has_children() ==
false,
1994 ->get_dof_indices(local_face_dof_indices);
1995 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1996 dof_to_set_of_cells_map[local_face_dof_indices[i]]
2013 for (
unsigned int l = 0; l < cell->n_lines(); ++l)
2015 if (cell->line(l)->has_children())
2017 for (
unsigned int c = 0;
2018 c < cell->line(l)->n_children();
2021 Assert(cell->line(l)->child(c)->has_children() ==
2027 const unsigned int n_dofs_per_line =
2030 local_line_dof_indices.resize(n_dofs_per_line);
2032 cell->line(l)->child(c)->get_dof_indices(
2033 local_line_dof_indices);
2034 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
2035 dof_to_set_of_cells_map[local_line_dof_indices[i]]
2043 else if (cell->line(l)->user_flag_set() ==
true)
2047 lines_to_parent_lines_map[cell->line(l)];
2052 const unsigned int n_dofs_per_line =
2055 local_line_dof_indices.resize(n_dofs_per_line);
2057 parent_line->get_dof_indices(local_line_dof_indices);
2058 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
2059 dof_to_set_of_cells_map[local_line_dof_indices[i]]
2062 for (
unsigned int c = 0; c < parent_line->n_children();
2065 Assert(parent_line->child(c)->has_children() ==
2069 const unsigned int n_dofs_per_line =
2072 local_line_dof_indices.resize(n_dofs_per_line);
2074 parent_line->child(c)->get_dof_indices(
2075 local_line_dof_indices);
2076 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
2077 dof_to_set_of_cells_map[local_line_dof_indices[i]]
2094 .load_user_flags(user_flags);
2101 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
2102 dof_to_cell_patches;
2106 std::set<typename DoFHandler<dim, spacedim>::active_cell_iterator>>::
2107 iterator it = dof_to_set_of_cells_map.begin(),
2108 it_end = dof_to_set_of_cells_map.end();
2109 for (; it != it_end; ++it)
2110 dof_to_cell_patches[it->first].assign(it->second.begin(),
2113 return dof_to_cell_patches;
2119 template <
typename CellIterator>
2122 std::set<std::pair<CellIterator, unsigned int>> &pairs1,
2125 const unsigned int direction,
2127 const ::Tensor<1, CellIterator::AccessorType::space_dimension>
2131 static const int space_dim = CellIterator::AccessorType::space_dimension;
2137 constexpr int dim = CellIterator::AccessorType::dimension;
2138 constexpr int spacedim = CellIterator::AccessorType::space_dimension;
2143 if (!(((pairs1.size() > 0) &&
2144 (
dynamic_cast<const parallel::fullydistributed::
2145 Triangulation<dim, spacedim> *
>(
2146 &pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2147 ((pairs2.size() > 0) &&
2150 *
>(&pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2151 Assert(pairs1.size() == pairs2.size(),
2152 ExcMessage(
"Unmatched faces on periodic boundaries"));
2156 unsigned int n_matches = 0;
2159 using PairIterator =
2160 typename std::set<std::pair<CellIterator, unsigned int>>::const_iterator;
2161 for (PairIterator it1 = pairs1.begin(); it1 != pairs1.end(); ++it1)
2163 for (PairIterator it2 = pairs2.begin(); it2 != pairs2.end(); ++it2)
2165 const CellIterator cell1 = it1->first;
2166 const CellIterator cell2 = it2->first;
2167 const unsigned int face_idx1 = it1->second;
2168 const unsigned int face_idx2 = it2->second;
2169 if (
const std::optional<unsigned char> orientation =
2171 cell2->face(face_idx2),
2181 {face_idx1, face_idx2},
2182 orientation.value(),
2184 matched_pairs.push_back(matched_face);
2198 constexpr int dim = CellIterator::AccessorType::dimension;
2199 constexpr int spacedim = CellIterator::AccessorType::space_dimension;
2200 if (!(((pairs1.size() > 0) &&
2201 (
dynamic_cast<const parallel::fullydistributed::
2202 Triangulation<dim, spacedim> *
>(
2203 &pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2204 ((pairs2.size() > 0) &&
2207 *
>(&pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2208 AssertThrow(n_matches == pairs1.size() && pairs2.empty(),
2209 ExcMessage(
"Unmatched faces on periodic boundaries"));
2215 template <
typename MeshType>
2218 const MeshType &mesh,
2219 const
types::boundary_id b_id,
2220 const
unsigned int direction,
2223 const
Tensor<1, MeshType::space_dimension> &offset,
2226 static const int dim = MeshType::dimension;
2227 static const int space_dim = MeshType::space_dimension;
2237 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs1;
2238 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs2;
2240 for (
typename MeshType::cell_iterator cell = mesh.begin(0);
2241 cell != mesh.end(0);
2244 const typename MeshType::face_iterator face_1 =
2245 cell->face(2 * direction);
2246 const typename MeshType::face_iterator face_2 =
2247 cell->face(2 * direction + 1);
2249 if (face_1->at_boundary() && face_1->boundary_id() == b_id)
2251 const std::pair<typename MeshType::cell_iterator, unsigned int>
2252 pair1 = std::make_pair(cell, 2 * direction);
2253 pairs1.insert(pair1);
2256 if (face_2->at_boundary() && face_2->boundary_id() == b_id)
2258 const std::pair<typename MeshType::cell_iterator, unsigned int>
2259 pair2 = std::make_pair(cell, 2 * direction + 1);
2260 pairs2.insert(pair2);
2264 Assert(pairs1.size() == pairs2.size(),
2265 ExcMessage(
"Unmatched faces on periodic boundaries"));
2267 Assert(pairs1.size() > 0,
2268 ExcMessage(
"No new periodic face pairs have been found. "
2269 "Are you sure that you've selected the correct boundary "
2270 "id's and that the coarsest level mesh is colorized?"));
2273 const unsigned int size_old = matched_pairs.size();
2278 pairs1, pairs2, direction, matched_pairs, offset, matrix);
2282 const unsigned int size_new = matched_pairs.size();
2283 for (
unsigned int i = size_old; i < size_new; ++i)
2285 Assert(matched_pairs[i].orientation ==
2288 "Found a face match with non standard orientation. "
2289 "This function is only suitable for meshes with cells "
2290 "in default orientation"));
2297 template <
typename MeshType>
2300 const MeshType &mesh,
2301 const
types::boundary_id b_id1,
2302 const
types::boundary_id b_id2,
2303 const
unsigned int direction,
2306 const
Tensor<1, MeshType::space_dimension> &offset,
2309 static const int dim = MeshType::dimension;
2310 static const int space_dim = MeshType::space_dimension;
2318 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs1;
2319 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs2;
2321 for (
typename MeshType::cell_iterator cell = mesh.begin(0);
2322 cell != mesh.end(0);
2325 for (
const unsigned int i : cell->face_indices())
2327 const typename MeshType::face_iterator face = cell->face(i);
2328 if (face->at_boundary() && face->boundary_id() == b_id1)
2330 const std::pair<typename MeshType::cell_iterator, unsigned int>
2331 pair1 = std::make_pair(cell, i);
2332 pairs1.insert(pair1);
2335 if (face->at_boundary() && face->boundary_id() == b_id2)
2337 const std::pair<typename MeshType::cell_iterator, unsigned int>
2338 pair2 = std::make_pair(cell, i);
2339 pairs2.insert(pair2);
2350 if (!(((pairs1.size() > 0) &&
2353 *
>(&pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2354 ((pairs2.size() > 0) &&
2357 *
>(&pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2358 Assert(pairs1.size() == pairs2.size(),
2359 ExcMessage(
"Unmatched faces on periodic boundaries"));
2362 (pairs1.size() > 0 ||
2365 &mesh.begin()->get_triangulation()) !=
nullptr)),
2366 ExcMessage(
"No new periodic face pairs have been found. "
2367 "Are you sure that you've selected the correct boundary "
2368 "id's and that the coarsest level mesh is colorized?"));
2372 pairs1, pairs2, direction, matched_pairs, offset, matrix);
2386 template <
int spacedim>
2390 const unsigned int direction,
2400 if (matrix.m() == spacedim)
2401 for (
unsigned int i = 0; i < spacedim; ++i)
2402 for (
unsigned int j = 0; j < spacedim; ++j)
2403 distance[i] += matrix(i, j) * point1[j];
2407 distance += offset - point2;
2409 for (
unsigned int i = 0; i < spacedim; ++i)
2415 if (
std::abs(distance[i]) > 1.e-10)
2424 template <
typename FaceIterator>
2425 std::optional<unsigned char>
2427 const FaceIterator &face1,
2428 const FaceIterator &face2,
2429 const unsigned int direction,
2433 Assert(matrix.m() == matrix.n(),
2434 ExcMessage(
"The supplied matrix must be a square matrix"));
2436 static const int dim = FaceIterator::AccessorType::dimension;
2440 std::array<unsigned int, GeometryInfo<dim>::vertices_per_face>
2441 face1_vertices, face2_vertices;
2448 std::set<unsigned int> face2_vertices_set;
2449 for (
unsigned int i = 0; i < face1->n_vertices(); ++i)
2450 face2_vertices_set.insert(i);
2452 for (
unsigned int i = 0; i < face1->n_vertices(); ++i)
2454 for (
auto it = face2_vertices_set.begin();
2455 it != face2_vertices_set.end();
2464 face1_vertices[i] = *it;
2465 face2_vertices[i] = i;
2466 face2_vertices_set.erase(it);
2472 if (face2_vertices_set.empty())
2475 Assert(face1_vertices.end() ==
2476 std::find(face1_vertices.begin(),
2477 face1_vertices.begin() + face1->n_vertices(),
2480 Assert(face2_vertices.end() ==
2481 std::find(face2_vertices.begin(),
2482 face2_vertices.begin() + face1->n_vertices(),
2486 const auto reference_cell = face1->reference_cell();
2489 return std::make_optional(reference_cell.get_combined_orientation(
2491 face2_vertices.cbegin() + face2->n_vertices()),
2493 face1_vertices.cbegin() + face1->n_vertices())));
2496 return std::nullopt;
2501#include "grid_tools_dof_handlers.inst"
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
cell_iterator end() const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const Triangulation< dim, spacedim > & get_triangulation() const
active_cell_iterator begin_active(const unsigned int level=0) const
unsigned int n_dofs_per_vertex() const
unsigned int n_dofs_per_cell() const
unsigned int n_dofs_per_line() const
unsigned int n_dofs_per_face(unsigned int face_no=0, unsigned int child=0) const
Abstract base class for mapping classes.
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const =0
constexpr numbers::NumberTraits< Number >::real_type distance_square(const Point< dim, Number > &p) const
static constexpr unsigned char default_combined_face_orientation()
cell_iterator begin(const unsigned int level=0) const
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
unsigned int n_active_cells() const
void save_user_flags(std::ostream &out) const
const std::vector< Point< spacedim > > & get_vertices() const
cell_iterator end() const
virtual void execute_coarsening_and_refinement()
unsigned int n_cells() const
const std::vector< bool > & get_used_vertices() const
Triangulation< dim, spacedim > & get_triangulation()
unsigned int size() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators() const
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcVertexNotUsed(unsigned int arg1)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::line_iterator line_iterator
typename ActiveSelector::active_cell_iterator active_cell_iterator
const Mapping< dim, spacedim > & get_default_linear_mapping(const Triangulation< dim, spacedim > &triangulation)
constexpr T fixed_power(const T t)
static const unsigned int invalid_unsigned_int
typename type_identity< T >::type type_identity_t
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index