53 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
57 const
Point<spacedim> &p,
58 const
std::vector<
bool> &marked_vertices)
66 const std::vector<Point<spacedim>> &vertices = tria.
get_vertices();
69 marked_vertices.empty(),
71 marked_vertices.size()));
81 marked_vertices.empty() ||
82 std::equal(marked_vertices.begin(),
83 marked_vertices.end(),
85 [](
bool p,
bool q) { return !p || q; }),
87 "marked_vertices should be a subset of used vertices in the triangulation "
88 "but marked_vertices contains one or more vertices that are not used vertices!"));
96 const std::vector<bool> &used =
101 std::vector<bool>::const_iterator
first =
102 std::find(used.begin(), used.end(),
true);
108 unsigned int best_vertex = std::distance(used.begin(),
first);
109 double best_dist = (p - vertices[best_vertex]).norm_square();
113 for (
unsigned int j = best_vertex + 1; j < vertices.size(); ++j)
116 double dist = (p - vertices[j]).norm_square();
117 if (dist < best_dist)
129 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
133 const MeshType<dim, spacedim> &mesh,
134 const
Point<spacedim> &p,
135 const
std::vector<
bool> &marked_vertices)
138 if (mapping.preserves_vertex_locations() ==
true)
150 marked_vertices.empty(),
152 marked_vertices.size()));
162 marked_vertices.empty() ||
163 std::equal(marked_vertices.begin(),
164 marked_vertices.end(),
166 [](
bool p,
bool q) { return !p || q; }),
168 "marked_vertices should be a subset of used vertices in the triangulation "
169 "but marked_vertices contains one or more vertices that are not used vertices!"));
172 if (marked_vertices.size())
173 for (
auto it = vertices.begin(); it != vertices.end();)
175 if (marked_vertices[it->first] ==
false)
177 vertices.erase(it++);
190 template <
typename MeshType>
193 std::vector<typename MeshType::active_cell_iterator>
196 typename ::internal::ActiveCellIterator<MeshType::dimension,
197 MeshType::space_dimension,
201 const unsigned int vertex)
203 const int dim = MeshType::dimension;
204 const int spacedim = MeshType::space_dimension;
210 Assert(mesh.get_triangulation().get_used_vertices()[vertex],
216 std::set<typename ::internal::
217 ActiveCellIterator<dim, spacedim, MeshType>::type>
220 typename ::internal::ActiveCellIterator<dim, spacedim, MeshType>::type
221 cell = mesh.begin_active(),
257 for (; cell != endc; ++cell)
259 for (
const unsigned int v : cell->vertex_indices())
260 if (cell->vertex_index(v) == vertex)
273 const auto reference_cell = cell->reference_cell();
274 for (
const auto face :
275 reference_cell.faces_for_given_vertex(v))
276 if (!cell->at_boundary(face) &&
277 cell->neighbor(face)->is_active())
300 for (
unsigned int e = 0; e < cell->n_lines(); ++e)
301 if (cell->line(e)->has_children())
305 if (cell->line(e)->child(0)->vertex_index(1) == vertex)
328 return std::vector<typename ::internal::
329 ActiveCellIterator<dim, spacedim, MeshType>::type>(
337 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
340 void find_active_cell_around_point_internal(
341 const MeshType<dim, spacedim> &mesh,
343 std::set<typename MeshType<dim, spacedim>::active_cell_iterator>
345 std::set<typename MeshType<dim, spacedim>::active_cell_iterator>
349 typename ::internal::
350 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
354 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
359 using cell_iterator =
360 typename MeshType<dim, spacedim>::active_cell_iterator;
362 using cell_iterator = typename ::internal::
363 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type;
371 std::set<cell_iterator> adjacent_cells_new;
375 std::vector<cell_iterator> active_neighbors;
376 get_active_neighbors<MeshType<dim, spacedim>>(cell, active_neighbors);
377 for (
unsigned int i = 0; i < active_neighbors.size(); ++i)
378 if (searched_cells.find(active_neighbors[i]) ==
379 searched_cells.end())
380 adjacent_cells_new.insert(active_neighbors[i]);
384 adjacent_cells_new.end());
393 cell_iterator it = mesh.begin_active();
394 for (; it != mesh.end(); ++it)
395 if (searched_cells.find(it) == searched_cells.end())
406 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
410 typename MeshType<dim, spacedim>::active_cell_iterator
412 typename ::internal::
413 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type
417 const std::vector<bool> &marked_vertices,
418 const double tolerance)
420 return find_active_cell_around_point<dim, MeshType, spacedim>(
431 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
435 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim>>
437 std::pair<typename ::internal::
438 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
442 const MeshType<dim, spacedim> &mesh,
444 const std::vector<bool> &marked_vertices,
445 const double tolerance)
447 using active_cell_iterator = typename ::internal::
448 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type;
454 double best_distance = tolerance;
456 std::pair<active_cell_iterator, Point<dim>> best_cell;
459 best_cell.first = mesh.end();
463 std::vector<active_cell_iterator> adjacent_cells_tmp =
472 std::set<active_cell_iterator>
adjacent_cells(adjacent_cells_tmp.begin(),
473 adjacent_cells_tmp.end());
474 std::set<active_cell_iterator> searched_cells;
482 const auto n_active_cells = mesh.get_triangulation().n_active_cells();
484 unsigned int cells_searched = 0;
485 while (!found && cells_searched < n_active_cells)
489 if (cell->is_artificial() ==
false)
492 if (marked_vertices.size() > 0)
494 bool any_vertex_marked =
false;
495 for (
const auto &v : cell->vertex_indices())
497 if (marked_vertices[cell->vertex_index(v)])
499 any_vertex_marked =
true;
503 if (!any_vertex_marked)
515 cell->reference_cell().closest_point(p_cell).distance(
522 if ((dist < best_distance) ||
523 ((dist == best_distance) &&
524 (cell->level() > best_level)))
527 best_distance = dist;
528 best_level = cell->level();
529 best_cell = std::make_pair(cell, p_cell);
560 if (!found && cells_searched < n_active_cells)
562 find_active_cell_around_point_internal<dim, MeshType, spacedim>(
572 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
576 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
579 std::vector<std::pair<
580 typename ::internal::
581 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
585 const MeshType<dim, spacedim> &mesh,
587 const double tolerance,
588 const std::vector<bool> &marked_vertices)
591 mapping, mesh, p, marked_vertices, tolerance);
593 if (cell_and_point.first == mesh.end())
597 mapping, mesh, p, tolerance, cell_and_point);
602 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
606 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
609 std::vector<std::pair<
610 typename ::internal::
611 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
616 const MeshType<dim, spacedim> &mesh,
618 const double tolerance,
619 const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
622 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator>>
626 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
631 cells_and_points.push_back(first_cell);
633 const Point<dim> unit_point = cells_and_points.front().second;
634 const auto my_cell = cells_and_points.front().first;
636 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
639 if (my_cell->reference_cell().is_hyper_cube())
645 unsigned int n_dirs_at_threshold = 0;
647 for (
unsigned int d = 0; d < dim; ++d)
649 distance_to_center[d] =
std::abs(unit_point[d] - 0.5);
650 if (distance_to_center[d] > 0.5 - tolerance)
652 ++n_dirs_at_threshold;
653 last_point_at_threshold = d;
658 if (n_dirs_at_threshold == 1)
660 unsigned int neighbor_index =
661 2 * last_point_at_threshold +
662 (unit_point[last_point_at_threshold] > 0.5 ? 1 : 0);
663 if (!my_cell->at_boundary(neighbor_index))
665 const auto neighbor_cell = my_cell->neighbor(neighbor_index);
667 if (neighbor_cell->is_active())
668 cells_to_add.push_back(neighbor_cell);
670 for (
const auto &child_cell :
671 neighbor_cell->child_iterators())
673 if (child_cell->is_active())
674 cells_to_add.push_back(child_cell);
679 else if (n_dirs_at_threshold == dim)
681 unsigned int local_vertex_index = 0;
682 for (
unsigned int d = 0; d < dim; ++d)
683 local_vertex_index += (unit_point[d] > 0.5 ? 1 : 0) << d;
685 const auto fu = [&](
const auto &tentative_cells) {
686 for (
const auto &cell : tentative_cells)
688 cells_to_add.push_back(cell);
691 const auto vertex_index = my_cell->vertex_index(local_vertex_index);
693 if (vertex_to_cells !=
nullptr)
694 fu((*vertex_to_cells)[vertex_index]);
703 else if (n_dirs_at_threshold == 2)
706 unsigned int count_vertex_indices = 0;
708 for (
unsigned int d = 0; d < dim; ++d)
710 if (distance_to_center[d] > 0.5 - tolerance)
714 unit_point[d] > 0.5 ? 1 : 0;
715 ++count_vertex_indices;
725 const unsigned int first_vertex =
728 for (
unsigned int d = 0; d < 2; ++d)
730 const auto fu = [&](
const auto &tentative_cells) {
731 for (
const auto &cell : tentative_cells)
733 bool cell_not_yet_present =
true;
734 for (
const auto &other_cell : cells_to_add)
735 if (cell == other_cell)
737 cell_not_yet_present =
false;
740 if (cell_not_yet_present)
741 cells_to_add.push_back(cell);
745 const auto vertex_index =
746 my_cell->vertex_index(first_vertex + (d << free_direction));
748 if (vertex_to_cells !=
nullptr)
749 fu((*vertex_to_cells)[vertex_index]);
763 for (
const auto v : my_cell->vertex_indices())
765 const auto fu = [&](
const auto &tentative_cells) {
766 for (
const auto &cell : tentative_cells)
768 bool cell_not_yet_present =
true;
769 for (
const auto &other_cell : cells_to_add)
770 if (cell == other_cell)
772 cell_not_yet_present =
false;
775 if (cell_not_yet_present)
776 cells_to_add.push_back(cell);
780 const auto vertex_index = my_cell->vertex_index(v);
782 if (vertex_to_cells !=
nullptr)
783 fu((*vertex_to_cells)[vertex_index]);
789 for (
const auto &cell : cells_to_add)
796 if (cell->reference_cell().contains_point(p_unit, tolerance))
797 cells_and_points.emplace_back(cell, p_unit);
804 cells_and_points.begin(),
805 cells_and_points.end(),
806 [](
const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
808 const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
809 Point<dim>> &b) { return a.first < b.first; });
811 return cells_and_points;
816 template <
typename MeshType>
820 const MeshType &mesh,
821 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
824 std::vector<typename MeshType::active_cell_iterator> active_halo_layer;
825 std::vector<bool> locally_active_vertices_on_subdomain(
826 mesh.get_triangulation().n_vertices(),
false);
828 std::map<unsigned int, std::vector<unsigned int>> coinciding_vertex_groups;
829 std::map<unsigned int, unsigned int> vertex_to_coinciding_vertex_group;
831 coinciding_vertex_groups,
832 vertex_to_coinciding_vertex_group);
837 for (
const auto &cell : mesh.active_cell_iterators())
839 for (
const auto v : cell->vertex_indices())
841 locally_active_vertices_on_subdomain[cell->vertex_index(v)] =
true;
842 for (
const auto vv : coinciding_vertex_groups
843 [vertex_to_coinciding_vertex_group[cell->vertex_index(v)]])
844 locally_active_vertices_on_subdomain[vv] =
true;
850 for (
const auto &cell : mesh.active_cell_iterators())
851 if (!predicate(cell))
852 for (
const auto v : cell->vertex_indices())
853 if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] ==
856 active_halo_layer.push_back(cell);
860 return active_halo_layer;
865 template <
typename MeshType>
869 const MeshType &mesh,
870 const std::function<
bool(
const typename MeshType::cell_iterator &)>
872 const unsigned int level)
874 std::vector<typename MeshType::cell_iterator> level_halo_layer;
875 std::vector<bool> locally_active_vertices_on_level_subdomain(
876 mesh.get_triangulation().n_vertices(),
false);
881 for (
typename MeshType::cell_iterator cell = mesh.begin(
level);
882 cell != mesh.end(
level);
885 for (
const unsigned int v : cell->vertex_indices())
886 locally_active_vertices_on_level_subdomain[cell->vertex_index(v)] =
892 for (
typename MeshType::cell_iterator cell = mesh.begin(
level);
893 cell != mesh.end(
level);
895 if (!predicate(cell))
896 for (
const unsigned int v : cell->vertex_indices())
897 if (locally_active_vertices_on_level_subdomain[cell->vertex_index(
900 level_halo_layer.push_back(cell);
904 return level_halo_layer;
910 template <
typename MeshType>
912 bool contains_locally_owned_cells(
913 const std::vector<typename MeshType::active_cell_iterator> &cells)
915 for (
typename std::vector<
916 typename MeshType::active_cell_iterator>::const_iterator it =
921 if ((*it)->is_locally_owned())
927 template <
typename MeshType>
929 bool contains_artificial_cells(
930 const std::vector<typename MeshType::active_cell_iterator> &cells)
932 for (
typename std::vector<
933 typename MeshType::active_cell_iterator>::const_iterator it =
938 if ((*it)->is_artificial())
947 template <
typename MeshType>
953 std::function<
bool(
const typename MeshType::active_cell_iterator &)>
956 const std::vector<typename MeshType::active_cell_iterator>
961 Assert(contains_locally_owned_cells<MeshType>(active_halo_layer) ==
false,
962 ExcMessage(
"Halo layer contains locally owned cells"));
963 Assert(contains_artificial_cells<MeshType>(active_halo_layer) ==
false,
964 ExcMessage(
"Halo layer contains artificial cells"));
966 return active_halo_layer;
971 template <
typename MeshType>
975 const MeshType &mesh,
976 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
978 const double layer_thickness)
980 std::vector<typename MeshType::active_cell_iterator>
981 subdomain_boundary_cells, active_cell_layer_within_distance;
982 std::vector<bool> vertices_outside_subdomain(
983 mesh.get_triangulation().n_vertices(),
false);
985 const unsigned int spacedim = MeshType::space_dimension;
987 unsigned int n_non_predicate_cells = 0;
995 for (
const auto &cell : mesh.active_cell_iterators())
996 if (!predicate(cell))
998 for (
const unsigned int v : cell->vertex_indices())
999 vertices_outside_subdomain[cell->vertex_index(v)] =
true;
1000 ++n_non_predicate_cells;
1007 if (n_non_predicate_cells == 0 ||
1008 n_non_predicate_cells == mesh.get_triangulation().n_active_cells())
1009 return std::vector<typename MeshType::active_cell_iterator>();
1013 for (
const auto &cell : mesh.active_cell_iterators())
1014 if (predicate(cell))
1016 for (
const unsigned int v : cell->vertex_indices())
1017 if (vertices_outside_subdomain[cell->vertex_index(v)] ==
true)
1019 subdomain_boundary_cells.push_back(cell);
1029 const double DOUBLE_EPSILON = 100. * std::numeric_limits<double>::epsilon();
1032 for (
unsigned int d = 0; d < spacedim; ++d)
1034 bounding_box.first[d] -= (layer_thickness + DOUBLE_EPSILON);
1035 bounding_box.second[d] += (layer_thickness + DOUBLE_EPSILON);
1038 std::vector<Point<spacedim>>
1039 subdomain_boundary_cells_centers;
1042 subdomain_boundary_cells_radii;
1044 subdomain_boundary_cells_centers.reserve(subdomain_boundary_cells.size());
1045 subdomain_boundary_cells_radii.reserve(subdomain_boundary_cells.size());
1047 for (
typename std::vector<typename MeshType::active_cell_iterator>::
1049 subdomain_boundary_cells.begin();
1050 subdomain_boundary_cell_iterator != subdomain_boundary_cells.end();
1051 ++subdomain_boundary_cell_iterator)
1053 const std::pair<Point<spacedim>,
double>
1054 &subdomain_boundary_cell_enclosing_ball =
1055 (*subdomain_boundary_cell_iterator)->enclosing_ball();
1057 subdomain_boundary_cells_centers.push_back(
1058 subdomain_boundary_cell_enclosing_ball.first);
1059 subdomain_boundary_cells_radii.push_back(
1060 subdomain_boundary_cell_enclosing_ball.second);
1062 AssertThrow(subdomain_boundary_cells_radii.size() ==
1063 subdomain_boundary_cells_centers.size(),
1072 for (
const auto &cell : mesh.active_cell_iterators())
1075 if (predicate(cell))
1078 const std::pair<Point<spacedim>,
double> &cell_enclosing_ball =
1079 cell->enclosing_ball();
1082 cell_enclosing_ball.first;
1083 const double cell_enclosing_ball_radius = cell_enclosing_ball.second;
1085 bool cell_inside =
true;
1087 for (
unsigned int d = 0; d < spacedim; ++d)
1089 (cell_enclosing_ball_center[d] + cell_enclosing_ball_radius >
1090 bounding_box.first[d]) &&
1091 (cell_enclosing_ball_center[d] - cell_enclosing_ball_radius <
1092 bounding_box.second[d]);
1098 for (
unsigned int i = 0; i < subdomain_boundary_cells_radii.size();
1101 subdomain_boundary_cells_centers[i]) <
1102 Utilities::fixed_power<2>(cell_enclosing_ball_radius +
1103 subdomain_boundary_cells_radii[i] +
1104 layer_thickness + DOUBLE_EPSILON))
1106 active_cell_layer_within_distance.push_back(cell);
1111 return active_cell_layer_within_distance;
1116 template <
typename MeshType>
1126 std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1127 predicate(locally_owned_cell_predicate);
1129 const std::vector<typename MeshType::active_cell_iterator>
1130 ghost_cell_layer_within_distance =
1138 contains_locally_owned_cells<MeshType>(
1139 ghost_cell_layer_within_distance) ==
false,
1141 "Ghost cells within layer_thickness contains locally owned cells."));
1143 contains_artificial_cells<MeshType>(ghost_cell_layer_within_distance) ==
1146 "Ghost cells within layer_thickness contains artificial cells. "
1147 "The function compute_ghost_cell_layer_within_distance "
1148 "is probably called while using parallel::distributed::Triangulation. "
1149 "In such case please refer to the description of this function."));
1151 return ghost_cell_layer_within_distance;
1156 template <
typename MeshType>
1162 const std::function<
bool(
1163 const typename MeshType::
1164 active_cell_iterator &)>
1167 std::vector<bool> locally_active_vertices_on_subdomain(
1168 mesh.get_triangulation().n_vertices(),
false);
1170 const unsigned int spacedim = MeshType::space_dimension;
1177 for (
const auto &cell : mesh.active_cell_iterators())
1178 if (predicate(cell))
1180 minp = cell->center();
1181 maxp = cell->center();
1187 for (
const auto &cell : mesh.active_cell_iterators())
1188 if (predicate(cell))
1189 for (
const unsigned int v : cell->vertex_indices())
1190 if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] ==
1193 locally_active_vertices_on_subdomain[cell->vertex_index(v)] =
1195 for (
unsigned int d = 0; d < spacedim; ++d)
1197 minp[d] =
std::min(minp[d], cell->vertex(v)[d]);
1198 maxp[d] =
std::max(maxp[d], cell->vertex(v)[d]);
1202 return std::make_pair(minp, maxp);
1207 template <
typename MeshType>
1209 std::list<std::pair<
1210 typename MeshType::cell_iterator,
1217 ExcMessage(
"The two meshes must be represent triangulations that "
1218 "have the same coarse meshes"));
1225 bool remove_ghost_cells =
false;
1226#ifdef DEAL_II_WITH_MPI
1228 constexpr int dim = MeshType::dimension;
1229 constexpr int spacedim = MeshType::space_dimension;
1231 *
>(&mesh_1.get_triangulation()) !=
nullptr ||
1233 *
>(&mesh_2.get_triangulation()) !=
nullptr)
1235 Assert(&mesh_1.get_triangulation() == &mesh_2.get_triangulation(),
1236 ExcMessage(
"This function can only be used with meshes "
1237 "corresponding to distributed Triangulations when "
1238 "both Triangulations are equal."));
1239 remove_ghost_cells =
true;
1251 using CellList = std::list<std::pair<
typename MeshType::cell_iterator,
1252 typename MeshType::cell_iterator>>;
1256 typename MeshType::cell_iterator cell_1 = mesh_1.begin(0),
1257 cell_2 = mesh_2.begin(0);
1258 for (; cell_1 != mesh_1.end(0); ++cell_1, ++cell_2)
1259 cell_list.emplace_back(cell_1, cell_2);
1262 typename CellList::iterator cell_pair = cell_list.begin();
1263 while (cell_pair != cell_list.end())
1267 if (cell_pair->first->has_children() &&
1268 cell_pair->second->has_children())
1270 Assert(cell_pair->first->refinement_case() ==
1271 cell_pair->second->refinement_case(),
1273 for (
unsigned int c = 0; c < cell_pair->first->n_children(); ++c)
1274 cell_list.emplace_back(cell_pair->first->child(c),
1275 cell_pair->second->child(c));
1280 const auto previous_cell_pair = cell_pair;
1282 cell_list.erase(previous_cell_pair);
1287 if (remove_ghost_cells &&
1288 ((cell_pair->first->is_active() &&
1289 !cell_pair->first->is_locally_owned()) ||
1290 (cell_pair->second->is_active() &&
1291 !cell_pair->second->is_locally_owned())))
1294 const auto previous_cell_pair = cell_pair;
1296 cell_list.erase(previous_cell_pair);
1305 for (cell_pair = cell_list.begin(); cell_pair != cell_list.end();
1307 Assert(cell_pair->first->is_active() || cell_pair->second->is_active() ||
1308 (cell_pair->first->refinement_case() !=
1309 cell_pair->second->refinement_case()),
1317 template <
int dim,
int spacedim>
1334 endc = mesh_1.
end(0);
1335 for (; cell_1 != endc; ++cell_1, ++cell_2)
1337 if (cell_1->n_vertices() != cell_2->n_vertices())
1339 for (
const unsigned int v : cell_1->vertex_indices())
1340 if (cell_1->vertex(v) != cell_2->vertex(v))
1353 template <
typename MeshType>
1358 mesh_2.get_triangulation());
1363 template <
int dim,
int spacedim>
1364 std::pair<typename DoFHandler<dim, spacedim>::active_cell_iterator,
1370 const double tolerance)
1374 ExcMessage(
"Mapping collection needs to have either size 1 "
1375 "or size equal to the number of elements in "
1376 "the FECollection."));
1378 using cell_iterator =
1381 std::pair<cell_iterator, Point<dim>> best_cell;
1385 if (mapping.
size() == 1)
1387 const std::vector<bool> marked_vertices = {};
1389 mapping[0], mesh, p, marked_vertices, tolerance);
1396 double best_distance = tolerance;
1397 int best_level = -1;
1404 std::vector<cell_iterator> adjacent_cells_tmp =
1412 std::set<cell_iterator>
adjacent_cells(adjacent_cells_tmp.begin(),
1413 adjacent_cells_tmp.end());
1414 std::set<cell_iterator> searched_cells;
1424 unsigned int cells_searched = 0;
1425 while (!found && cells_searched < n_cells)
1432 mapping[cell->active_fe_index()]
1433 .transform_real_to_unit_cell(cell, p);
1439 cell->reference_cell().closest_point(p_cell).distance(
1446 if (dist < best_distance ||
1447 (dist == best_distance && cell->level() > best_level))
1450 best_distance = dist;
1451 best_level = cell->level();
1452 best_cell = std::make_pair(cell, p_cell);
1478 if (!found && cells_searched < n_cells)
1480 find_active_cell_around_point_internal<dim,
1492 template <
typename MeshType>
1495 const typename MeshType::active_cell_iterator &cell)
1497 Assert(cell->is_locally_owned(),
1498 ExcMessage(
"This function only makes sense if the cell for "
1499 "which you are asking for a patch, is locally "
1502 std::vector<typename MeshType::active_cell_iterator> patch;
1503 patch.push_back(cell);
1504 for (
const unsigned int face_number : cell->face_indices())
1505 if (cell->face(face_number)->at_boundary() ==
false)
1507 if (cell->neighbor(face_number)->has_children() ==
false)
1508 patch.push_back(cell->neighbor(face_number));
1513 if (MeshType::dimension > 1)
1515 for (
unsigned int subface = 0;
1516 subface < cell->face(face_number)->n_children();
1519 cell->neighbor_child_on_subface(face_number, subface));
1525 typename MeshType::cell_iterator neighbor =
1526 cell->neighbor(face_number);
1527 while (neighbor->has_children())
1528 neighbor = neighbor->child(1 - face_number);
1530 Assert(neighbor->neighbor(1 - face_number) == cell,
1532 patch.push_back(neighbor);
1540 template <
class Container>
1541 std::vector<typename Container::cell_iterator>
1543 const std::vector<typename Container::active_cell_iterator> &patch)
1547 "Vector containing patch cells should not be an empty vector!"));
1551 int min_level = patch[0]->level();
1553 for (
unsigned int i = 0; i < patch.size(); ++i)
1555 std::set<typename Container::cell_iterator> uniform_cells;
1556 typename std::vector<
1557 typename Container::active_cell_iterator>::const_iterator patch_cell;
1559 for (patch_cell = patch.begin(); patch_cell != patch.end(); ++patch_cell)
1564 if ((*patch_cell)->level() == min_level)
1565 uniform_cells.insert(*patch_cell);
1572 typename Container::cell_iterator parent = *patch_cell;
1574 while (parent->level() > min_level)
1575 parent = parent->parent();
1576 uniform_cells.insert(parent);
1580 return std::vector<typename Container::cell_iterator>(uniform_cells.begin(),
1581 uniform_cells.end());
1586 template <
class Container>
1589 const std::vector<typename Container::active_cell_iterator> &patch,
1591 &local_triangulation,
1594 Container::space_dimension>::active_cell_iterator,
1595 typename Container::active_cell_iterator> &patch_to_global_tria_map)
1598 const std::vector<typename Container::cell_iterator> uniform_cells =
1599 get_cells_at_coarsest_common_level<Container>(patch);
1601 local_triangulation.
clear();
1602 std::vector<Point<Container::space_dimension>> vertices;
1603 const unsigned int n_uniform_cells = uniform_cells.size();
1604 std::vector<CellData<Container::dimension>> cells(n_uniform_cells);
1607 typename std::vector<typename Container::cell_iterator>::const_iterator
1609 for (uniform_cell = uniform_cells.begin();
1610 uniform_cell != uniform_cells.end();
1613 for (
const unsigned int v : (*uniform_cell)->vertex_indices())
1616 (*uniform_cell)->vertex(v);
1617 bool repeat_vertex =
false;
1619 for (
unsigned int m = 0; m < i; ++m)
1621 if (position == vertices[m])
1623 repeat_vertex =
true;
1624 cells[k].vertices[v] = m;
1628 if (repeat_vertex ==
false)
1630 vertices.push_back(position);
1631 cells[k].vertices[v] = i;
1642 unsigned int index = 0;
1645 Container::space_dimension>::cell_iterator,
1646 typename Container::cell_iterator>
1647 patch_to_global_tria_map_tmp;
1649 Container::space_dimension>::cell_iterator
1650 coarse_cell = local_triangulation.
begin();
1651 coarse_cell != local_triangulation.
end();
1652 ++coarse_cell, ++index)
1654 patch_to_global_tria_map_tmp.insert(
1655 std::make_pair(coarse_cell, uniform_cells[index]));
1659 Assert(coarse_cell->center().distance(uniform_cells[index]->center()) <=
1660 1e-15 * coarse_cell->diameter(),
1663 bool refinement_necessary;
1668 refinement_necessary =
false;
1669 for (
const auto &active_tria_cell :
1672 if (patch_to_global_tria_map_tmp[active_tria_cell]->has_children())
1674 active_tria_cell->set_refine_flag();
1675 refinement_necessary =
true;
1678 for (
unsigned int i = 0; i < patch.size(); ++i)
1683 if (patch_to_global_tria_map_tmp[active_tria_cell] ==
1688 for (
const unsigned int v :
1689 active_tria_cell->vertex_indices())
1690 active_tria_cell->vertex(v) = patch[i]->vertex(v);
1692 Assert(active_tria_cell->center().distance(
1693 patch_to_global_tria_map_tmp[active_tria_cell]
1695 1e-15 * active_tria_cell->diameter(),
1698 active_tria_cell->set_user_flag();
1704 if (refinement_necessary)
1709 Container::dimension,
1710 Container::space_dimension>::cell_iterator cell =
1711 local_triangulation.
begin();
1712 cell != local_triangulation.
end();
1715 if (patch_to_global_tria_map_tmp.find(cell) !=
1716 patch_to_global_tria_map_tmp.end())
1718 if (cell->has_children())
1725 for (
unsigned int c = 0; c < cell->n_children(); ++c)
1727 if (patch_to_global_tria_map_tmp.find(cell->child(
1728 c)) == patch_to_global_tria_map_tmp.end())
1730 patch_to_global_tria_map_tmp.insert(
1733 patch_to_global_tria_map_tmp[cell]->child(
1755 patch_to_global_tria_map_tmp.erase(cell);
1761 while (refinement_necessary);
1767 Container::space_dimension>::cell_iterator
1768 cell = local_triangulation.
begin();
1769 cell != local_triangulation.
end();
1772 if (cell->user_flag_set())
1774 Assert(patch_to_global_tria_map_tmp.find(cell) !=
1775 patch_to_global_tria_map_tmp.end(),
1778 Assert(cell->center().distance(
1779 patch_to_global_tria_map_tmp[cell]->center()) <=
1780 1e-15 * cell->diameter(),
1788 Container::space_dimension>::cell_iterator,
1789 typename Container::cell_iterator>::iterator
1790 map_tmp_it = patch_to_global_tria_map_tmp.
begin(),
1791 map_tmp_end = patch_to_global_tria_map_tmp.end();
1795 for (; map_tmp_it != map_tmp_end; ++map_tmp_it)
1796 patch_to_global_tria_map[map_tmp_it->first] = map_tmp_it->second;
1801 template <
int dim,
int spacedim>
1804 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
1818 std::set<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
1819 dof_to_set_of_cells_map;
1821 std::vector<types::global_dof_index> local_dof_indices;
1822 std::vector<types::global_dof_index> local_face_dof_indices;
1823 std::vector<types::global_dof_index> local_line_dof_indices;
1827 std::vector<bool> user_flags;
1832 std::map<typename DoFHandler<dim, spacedim>::active_line_iterator,
1834 lines_to_parent_lines_map;
1841 .clear_user_flags();
1846 endc = dof_handler.
end();
1847 for (; cell != endc; ++cell)
1853 if (cell->is_artificial() ==
false)
1855 for (
unsigned int l = 0; l < cell->n_lines(); ++l)
1856 if (cell->line(l)->has_children())
1857 for (
unsigned int c = 0; c < cell->line(l)->n_children();
1860 lines_to_parent_lines_map[cell->line(l)->child(c)] =
1864 cell->line(l)->child(c)->set_user_flag();
1879 endc = dof_handler.
end();
1880 for (; cell != endc; ++cell)
1885 if (cell->is_artificial() ==
false)
1887 const unsigned int n_dofs_per_cell =
1889 local_dof_indices.resize(n_dofs_per_cell);
1893 cell->get_dof_indices(local_dof_indices);
1894 for (
unsigned int i = 0; i < n_dofs_per_cell; ++i)
1895 dof_to_set_of_cells_map[local_dof_indices[i]].insert(cell);
1905 for (
const unsigned int f : cell->face_indices())
1907 if (cell->face(f)->has_children())
1909 for (
unsigned int c = 0; c < cell->face(f)->n_children();
1924 Assert(cell->face(f)->child(c)->has_children() ==
false,
1927 const unsigned int n_dofs_per_face =
1929 local_face_dof_indices.resize(n_dofs_per_face);
1931 cell->face(f)->child(c)->get_dof_indices(
1932 local_face_dof_indices);
1933 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1934 dof_to_set_of_cells_map[local_face_dof_indices[i]]
1938 else if ((cell->face(f)->at_boundary() ==
false) &&
1939 (cell->neighbor_is_coarser(f)))
1956 auto [face_no, subface] =
1957 cell->neighbor_of_coarser_neighbor(f);
1960 const unsigned int n_dofs_per_face =
1962 local_face_dof_indices.resize(n_dofs_per_face);
1964 cell->neighbor(f)->face(face_no)->get_dof_indices(
1965 local_face_dof_indices);
1966 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1967 dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(
1972 for (
unsigned int c = 0;
1973 c < cell->neighbor(f)->face(face_no)->n_children();
1979 const unsigned int n_dofs_per_face =
1981 local_face_dof_indices.resize(n_dofs_per_face);
1986 ->has_children() ==
false,
1991 ->get_dof_indices(local_face_dof_indices);
1992 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
1993 dof_to_set_of_cells_map[local_face_dof_indices[i]]
2010 for (
unsigned int l = 0; l < cell->n_lines(); ++l)
2012 if (cell->line(l)->has_children())
2014 for (
unsigned int c = 0;
2015 c < cell->line(l)->n_children();
2018 Assert(cell->line(l)->child(c)->has_children() ==
2024 const unsigned int n_dofs_per_line =
2027 local_line_dof_indices.resize(n_dofs_per_line);
2029 cell->line(l)->child(c)->get_dof_indices(
2030 local_line_dof_indices);
2031 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
2032 dof_to_set_of_cells_map[local_line_dof_indices[i]]
2040 else if (cell->line(l)->user_flag_set() ==
true)
2044 lines_to_parent_lines_map[cell->line(l)];
2049 const unsigned int n_dofs_per_line =
2052 local_line_dof_indices.resize(n_dofs_per_line);
2054 parent_line->get_dof_indices(local_line_dof_indices);
2055 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
2056 dof_to_set_of_cells_map[local_line_dof_indices[i]]
2059 for (
unsigned int c = 0; c < parent_line->n_children();
2062 Assert(parent_line->child(c)->has_children() ==
2066 const unsigned int n_dofs_per_line =
2069 local_line_dof_indices.resize(n_dofs_per_line);
2071 parent_line->child(c)->get_dof_indices(
2072 local_line_dof_indices);
2073 for (
unsigned int i = 0; i < n_dofs_per_line; ++i)
2074 dof_to_set_of_cells_map[local_line_dof_indices[i]]
2091 .load_user_flags(user_flags);
2098 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
2099 dof_to_cell_patches;
2103 std::set<typename DoFHandler<dim, spacedim>::active_cell_iterator>>::
2104 iterator it = dof_to_set_of_cells_map.begin(),
2105 it_end = dof_to_set_of_cells_map.end();
2106 for (; it != it_end; ++it)
2107 dof_to_cell_patches[it->first].assign(it->second.begin(),
2110 return dof_to_cell_patches;
2116 template <
typename CellIterator>
2119 std::set<std::pair<CellIterator, unsigned int>> &pairs1,
2122 const unsigned int direction,
2124 const ::Tensor<1, CellIterator::AccessorType::space_dimension>
2127 const double abs_tol = 1e-10)
2129 static const int space_dim = CellIterator::AccessorType::space_dimension;
2135 constexpr int dim = CellIterator::AccessorType::dimension;
2136 constexpr int spacedim = CellIterator::AccessorType::space_dimension;
2141 if (!(((pairs1.size() > 0) &&
2142 (
dynamic_cast<const parallel::fullydistributed::
2143 Triangulation<dim, spacedim> *
>(
2144 &pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2145 ((pairs2.size() > 0) &&
2146 (
dynamic_cast<const parallel::fullydistributed::
2147 Triangulation<dim, spacedim> *
>(
2148 &pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2149 Assert(pairs1.size() == pairs2.size(),
2150 ExcMessage(
"Unmatched faces on periodic boundaries"));
2154 unsigned int n_matches = 0;
2157 using PairIterator =
2158 typename std::set<std::pair<CellIterator, unsigned int>>::const_iterator;
2159 for (PairIterator it1 = pairs1.begin(); it1 != pairs1.end(); ++it1)
2161 for (PairIterator it2 = pairs2.begin(); it2 != pairs2.end(); ++it2)
2163 const CellIterator cell1 = it1->first;
2164 const CellIterator cell2 = it2->first;
2165 const unsigned int face_idx1 = it1->second;
2166 const unsigned int face_idx2 = it2->second;
2167 if (
const std::optional<types::geometric_orientation> orientation =
2169 cell2->face(face_idx2),
2180 {face_idx1, face_idx2},
2181 orientation.value(),
2183 matched_pairs.push_back(matched_face);
2197 constexpr int dim = CellIterator::AccessorType::dimension;
2198 constexpr int spacedim = CellIterator::AccessorType::space_dimension;
2199 if (!(((pairs1.size() > 0) &&
2200 (
dynamic_cast<const parallel::fullydistributed::
2201 Triangulation<dim, spacedim> *
>(
2202 &pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2203 ((pairs2.size() > 0) &&
2206 *
>(&pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2207 AssertThrow(n_matches == pairs1.size() && pairs2.empty(),
2208 ExcMessage(
"Unmatched faces on periodic boundaries"));
2214 template <
typename MeshType>
2217 const MeshType &mesh,
2218 const
types::boundary_id b_id,
2219 const
unsigned int direction,
2222 const
Tensor<1, MeshType::space_dimension> &offset,
2224 const
double abs_tol)
2226 static const int dim = MeshType::dimension;
2227 static const int space_dim = MeshType::space_dimension;
2234 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs1;
2235 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs2;
2237 for (
typename MeshType::cell_iterator cell = mesh.begin(0);
2238 cell != mesh.end(0);
2241 const typename MeshType::face_iterator face_1 =
2242 cell->face(2 * direction);
2243 const typename MeshType::face_iterator face_2 =
2244 cell->face(2 * direction + 1);
2246 if (face_1->at_boundary() && face_1->boundary_id() == b_id)
2248 const std::pair<typename MeshType::cell_iterator, unsigned int>
2249 pair1 = std::make_pair(cell, 2 * direction);
2250 pairs1.insert(pair1);
2253 if (face_2->at_boundary() && face_2->boundary_id() == b_id)
2255 const std::pair<typename MeshType::cell_iterator, unsigned int>
2256 pair2 = std::make_pair(cell, 2 * direction + 1);
2257 pairs2.insert(pair2);
2261 Assert(pairs1.size() == pairs2.size(),
2262 ExcMessage(
"Unmatched faces on periodic boundaries"));
2264 Assert(pairs1.size() > 0,
2265 ExcMessage(
"No new periodic face pairs have been found. "
2266 "Are you sure that you've selected the correct boundary "
2267 "id's and that the coarsest level mesh is colorized?"));
2269 [[maybe_unused]]
const unsigned int size_old = matched_pairs.size();
2273 pairs1, pairs2, direction, matched_pairs, offset, matrix, abs_tol);
2278 const unsigned int size_new = matched_pairs.size();
2279 for (
unsigned int i = size_old; i < size_new; ++i)
2281 Assert(matched_pairs[i].orientation ==
2284 "Found a face match with non standard orientation. "
2285 "This function is only suitable for meshes with cells "
2286 "in default orientation"));
2293 template <
typename MeshType>
2296 const MeshType &mesh,
2297 const
types::boundary_id b_id1,
2298 const
types::boundary_id b_id2,
2299 const
unsigned int direction,
2302 const
Tensor<1, MeshType::space_dimension> &offset,
2304 const
double abs_tol)
2306 static const int dim = MeshType::dimension;
2307 static const int space_dim = MeshType::space_dimension;
2313 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs1;
2314 std::set<std::pair<typename MeshType::cell_iterator, unsigned int>> pairs2;
2316 for (
typename MeshType::cell_iterator cell = mesh.begin(0);
2317 cell != mesh.end(0);
2320 for (
const unsigned int i : cell->face_indices())
2322 const typename MeshType::face_iterator face = cell->face(i);
2323 if (face->at_boundary() && face->boundary_id() == b_id1)
2325 const std::pair<typename MeshType::cell_iterator, unsigned int>
2326 pair1 = std::make_pair(cell, i);
2327 pairs1.insert(pair1);
2330 if (face->at_boundary() && face->boundary_id() == b_id2)
2332 const std::pair<typename MeshType::cell_iterator, unsigned int>
2333 pair2 = std::make_pair(cell, i);
2334 pairs2.insert(pair2);
2345 if (!(((pairs1.size() > 0) &&
2348 *
>(&pairs1.begin()->first->get_triangulation()) !=
nullptr)) ||
2349 ((pairs2.size() > 0) &&
2352 *
>(&pairs2.begin()->first->get_triangulation()) !=
nullptr))))
2353 Assert(pairs1.size() == pairs2.size(),
2354 ExcMessage(
"Unmatched faces on periodic boundaries"));
2357 (pairs1.size() > 0 ||
2360 &mesh.begin()->get_triangulation()) !=
nullptr)),
2361 ExcMessage(
"No new periodic face pairs have been found. "
2362 "Are you sure that you've selected the correct boundary "
2363 "id's and that the coarsest level mesh is colorized?"));
2367 pairs1, pairs2, direction, matched_pairs, offset, matrix, abs_tol);
2381 template <
int spacedim>
2385 const unsigned int direction,
2388 const double abs_tol = 1e-10)
2396 if (matrix.m() == spacedim)
2397 for (
unsigned int i = 0; i < spacedim; ++i)
2398 for (
unsigned int j = 0; j < spacedim; ++j)
2399 distance[i] += matrix(i, j) * point1[j];
2403 distance += offset - point2;
2405 for (
unsigned int i = 0; i < spacedim; ++i)
2411 if (
std::abs(distance[i]) > abs_tol)
2420 template <
typename FaceIterator>
2421 std::optional<types::geometric_orientation>
2423 const FaceIterator &face1,
2424 const FaceIterator &face2,
2425 const unsigned int direction,
2428 const double abs_tol)
2430 Assert(matrix.m() == matrix.n(),
2431 ExcMessage(
"The supplied matrix must be a square matrix"));
2432 Assert(face1->reference_cell() == face2->reference_cell(),
2434 "The faces to be matched must have the same reference cell."));
2439 std::vector<unsigned int> face1_vertices(face1->n_vertices(),
2443 std::set<unsigned int> face2_vertices_set;
2444 for (
unsigned int i = 0; i < face1->n_vertices(); ++i)
2445 face2_vertices_set.insert(i);
2447 for (
unsigned int i = 0; i < face1->n_vertices(); ++i)
2449 for (
auto it = face2_vertices_set.begin();
2450 it != face2_vertices_set.end();
2460 face1_vertices[i] = *it;
2461 face2_vertices[i] = i;
2462 face2_vertices_set.erase(it);
2468 if (face2_vertices_set.empty())
2471 Assert(face1_vertices.end() ==
2472 std::find(face1_vertices.begin(),
2473 face1_vertices.begin() + face1->n_vertices(),
2476 Assert(face2_vertices.end() ==
2477 std::find(face2_vertices.begin(),
2478 face2_vertices.begin() + face1->n_vertices(),
2482 const auto reference_cell = face1->reference_cell();
2485 return std::make_optional(reference_cell.get_combined_orientation(
2487 face2_vertices.cbegin() + face2->n_vertices()),
2489 face1_vertices.cbegin() + face1->n_vertices())));
2492 return std::nullopt;
2497#include "grid/grid_tools_dof_handlers.inst"
* x_component_mask set(0, true)
* * const_iterator()=default
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
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
constexpr bool running_in_debug_mode()
#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 unsigned int invalid_unsigned_int
constexpr types::geometric_orientation default_geometric_orientation
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