16 #include <deal.II/base/point.h> 17 #include <deal.II/base/geometry_info.h> 18 #include <deal.II/base/tensor.h> 20 #include <deal.II/distributed/tria.h> 21 #include <deal.II/distributed/shared_tria.h> 23 #include <deal.II/dofs/dof_handler.h> 24 #include <deal.II/dofs/dof_accessor.h> 26 #include <deal.II/fe/mapping_q1.h> 27 #include <deal.II/fe/mapping_q_generic.h> 29 #include <deal.II/grid/filtered_iterator.h> 30 #include <deal.II/grid/grid_tools.h> 31 #include <deal.II/grid/tria.h> 32 #include <deal.II/grid/tria_accessor.h> 33 #include <deal.II/grid/tria_iterator.h> 35 #include <deal.II/hp/mapping_collection.h> 36 #include <deal.II/hp/dof_handler.h> 38 #include <deal.II/lac/full_matrix.h> 50 DEAL_II_NAMESPACE_OPEN
54 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
58 const std::vector<bool> &marked_vertices)
66 const std::vector< Point<spacedim> > &vertices = tria.
get_vertices();
68 Assert ( tria.
get_vertices().size() == marked_vertices.size() || marked_vertices.size() ==0,
78 Assert( marked_vertices.size()==0
80 std::equal( marked_vertices.begin(),
81 marked_vertices.end(),
87 ExcMessage(
"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>
132 const MeshType<dim,spacedim> &mesh,
134 const std::vector<bool> &marked_vertices)
148 Assert ( tria.
get_vertices().size() == marked_vertices.size() || marked_vertices.size() ==0,
158 Assert( marked_vertices.size()==0
160 std::equal( marked_vertices.begin(),
161 marked_vertices.end(),
167 ExcMessage(
"marked_vertices should be a subset of used vertices in the triangulation " 168 "but marked_vertices contains one or more vertices that are not used vertices!") );
171 if (marked_vertices.size())
172 for (
auto it = vertices.begin(); it != vertices.end(); )
174 if (marked_vertices[it->first] ==
false)
176 vertices.erase(it++);
189 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
191 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
193 std::vector<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type>
196 const unsigned int vertex)
201 Assert(vertex < mesh.get_triangulation().n_vertices(),
202 ExcIndexRange(0,mesh.get_triangulation().n_vertices(),vertex));
203 Assert(mesh.get_triangulation().get_used_vertices()[vertex],
209 std::set<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type> adjacent_cells;
211 typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type
212 cell = mesh.begin_active(),
248 for (; cell != endc; ++cell)
250 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; v++)
251 if (cell->vertex_index(v) == vertex)
256 adjacent_cells.insert(cell);
263 for (
unsigned int vface = 0; vface < dim; vface++)
265 const unsigned int face =
268 if (!cell->at_boundary(face)
270 cell->neighbor(face)->active())
282 adjacent_cells.insert (cell->neighbor(face));
293 for (
unsigned int e=0; e<GeometryInfo<dim>::lines_per_cell; ++
e)
294 if (cell->line(e)->has_children())
298 if (cell->line(e)->child(0)->vertex_index(1) == vertex)
300 adjacent_cells.insert(cell);
323 std::vector<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type>
324 (adjacent_cells.begin(), adjacent_cells.end());
331 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
332 void find_active_cell_around_point_internal
333 (
const MeshType<dim,spacedim> &mesh,
335 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator> &searched_cells,
336 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator> &adjacent_cells)
338 std::set<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type> &searched_cells,
339 std::set<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type> &adjacent_cells)
343 typedef typename MeshType<dim, spacedim>::active_cell_iterator cell_iterator;
345 typedef typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type cell_iterator;
349 searched_cells.insert(adjacent_cells.begin(), adjacent_cells.end());
353 std::set<cell_iterator> adjacent_cells_new;
355 typename std::set<cell_iterator>::const_iterator
356 cell = adjacent_cells.begin(),
357 endc = adjacent_cells.end();
358 for (; cell != endc; ++cell)
360 std::vector<cell_iterator> active_neighbors;
361 get_active_neighbors<MeshType<dim, spacedim> >(*cell, active_neighbors);
362 for (
unsigned int i=0; i<active_neighbors.size(); ++i)
363 if (searched_cells.find(active_neighbors[i]) == searched_cells.end())
364 adjacent_cells_new.insert(active_neighbors[i]);
366 adjacent_cells.clear();
367 adjacent_cells.insert(adjacent_cells_new.begin(), adjacent_cells_new.end());
368 if (adjacent_cells.size() == 0)
376 cell_iterator it = mesh.begin_active();
377 for ( ; it!=mesh.end(); ++it)
378 if (searched_cells.find(it) == searched_cells.end())
380 adjacent_cells.insert(it);
387 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
389 typename MeshType<dim, spacedim>::active_cell_iterator
391 typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type
395 const std::vector<bool> &marked_vertices)
398 find_active_cell_around_point<dim,MeshType,spacedim>
400 mesh, p, marked_vertices).first;
404 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
406 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim> >
408 std::pair<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type,
Point<dim> >
411 const MeshType<dim,spacedim> &mesh,
413 const std::vector<bool> &marked_vertices)
415 typedef typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type active_cell_iterator;
421 double best_distance = 1
e-10;
423 std::pair<active_cell_iterator, Point<dim> > best_cell;
427 std::vector<active_cell_iterator> adjacent_cells_tmp
436 std::set<active_cell_iterator> adjacent_cells (adjacent_cells_tmp.begin(),
437 adjacent_cells_tmp.end());
438 std::set<active_cell_iterator> searched_cells;
446 const unsigned int n_active_cells = mesh.get_triangulation().n_active_cells();
448 unsigned int cells_searched = 0;
449 while (!found && cells_searched < n_active_cells)
451 typename std::set<active_cell_iterator>::const_iterator
452 cell = adjacent_cells.begin(),
453 endc = adjacent_cells.end();
454 for (; cell != endc; ++cell)
468 if ((dist < best_distance)
470 ((dist == best_distance)
472 ((*cell)->level() > best_level)))
475 best_distance = dist;
476 best_level = (*cell)->level();
477 best_cell = std::make_pair(*cell, p_cell);
497 cells_searched += adjacent_cells.size();
502 if (marked_vertices.size() > 0)
503 cells_searched = n_active_cells;
512 if (!found && cells_searched < n_active_cells)
514 find_active_cell_around_point_internal<dim,MeshType,spacedim>
515 (mesh, searched_cells, adjacent_cells);
520 ExcPointNotFound<spacedim>(p));
527 template <
class MeshType>
528 std::vector<typename MeshType::active_cell_iterator>
530 (
const MeshType &mesh,
531 const std::function<
bool (
const typename MeshType::active_cell_iterator &)> &predicate)
533 std::vector<typename MeshType::active_cell_iterator> active_halo_layer;
534 std::vector<bool> locally_active_vertices_on_subdomain (mesh.get_triangulation().n_vertices(),
540 for (
typename MeshType::active_cell_iterator
541 cell = mesh.begin_active();
542 cell != mesh.end(); ++cell)
544 for (
unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
545 locally_active_vertices_on_subdomain[cell->vertex_index(v)] =
true;
550 for (
typename MeshType::active_cell_iterator
551 cell = mesh.begin_active();
552 cell != mesh.end(); ++cell)
553 if (!predicate(cell))
554 for (
unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
555 if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] ==
true)
557 active_halo_layer.push_back(cell);
561 return active_halo_layer;
566 template <
class MeshType>
567 std::vector<typename MeshType::cell_iterator>
569 (
const MeshType &mesh,
570 const std::function<
bool (
const typename MeshType::cell_iterator &)> &predicate,
571 const unsigned int level)
573 std::vector<typename MeshType::cell_iterator> level_halo_layer;
574 std::vector<bool> locally_active_vertices_on_level_subdomain (mesh.get_triangulation().n_vertices(),
580 for (
typename MeshType::cell_iterator
581 cell = mesh.begin(level);
582 cell != mesh.end(level); ++cell)
584 for (
unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
585 locally_active_vertices_on_level_subdomain[cell->vertex_index(v)] =
true;
590 for (
typename MeshType::cell_iterator
591 cell = mesh.begin(level);
592 cell != mesh.end(level); ++cell)
593 if (!predicate(cell))
594 for (
unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
595 if (locally_active_vertices_on_level_subdomain[cell->vertex_index(v)] ==
true)
597 level_halo_layer.push_back(cell);
601 return level_halo_layer;
607 template <
class MeshType>
609 contains_locally_owned_cells (
const std::vector<typename MeshType::active_cell_iterator> &cells)
611 for (
typename std::vector<typename MeshType::active_cell_iterator>::const_iterator
612 it = cells.begin(); it != cells.end(); ++it)
614 if ((*it)->is_locally_owned())
620 template <
class MeshType>
622 contains_artificial_cells (
const std::vector<typename MeshType::active_cell_iterator> &cells)
624 for (
typename std::vector<typename MeshType::active_cell_iterator>::const_iterator
625 it = cells.begin(); it != cells.end(); ++it)
627 if ((*it)->is_artificial())
637 template <
class MeshType>
638 std::vector<typename MeshType::active_cell_iterator>
641 std::function<bool (const typename MeshType::active_cell_iterator &)> predicate
644 const std::vector<typename MeshType::active_cell_iterator>
649 Assert(contains_locally_owned_cells<MeshType>(active_halo_layer) ==
false,
650 ExcMessage(
"Halo layer contains locally owned cells"));
651 Assert(contains_artificial_cells<MeshType>(active_halo_layer) ==
false,
652 ExcMessage(
"Halo layer contains artificial cells"));
654 return active_halo_layer;
659 template <
class MeshType>
660 std::vector<typename MeshType::active_cell_iterator>
662 (
const MeshType &mesh,
663 const std::function<
bool (
const typename MeshType::active_cell_iterator &)> &predicate,
664 const double layer_thickness)
666 std::vector<typename MeshType::active_cell_iterator> subdomain_boundary_cells, active_cell_layer_within_distance;
667 std::vector<bool> vertices_outside_subdomain ( mesh.get_triangulation().n_vertices(),
670 const unsigned int spacedim = MeshType::space_dimension;
672 unsigned int n_non_predicate_cells = 0;
680 for (
typename MeshType::active_cell_iterator
681 cell = mesh.begin_active();
682 cell != mesh.end(); ++cell)
683 if ( !predicate(cell))
685 for (
unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
686 vertices_outside_subdomain[cell->vertex_index(v)] =
true;
687 n_non_predicate_cells++;
694 if ( n_non_predicate_cells == 0 || n_non_predicate_cells == mesh.get_triangulation().n_active_cells() )
695 return std::vector<typename MeshType::active_cell_iterator>();
699 for (
typename MeshType::active_cell_iterator
700 cell = mesh.begin_active();
701 cell != mesh.end(); ++cell)
702 if ( predicate(cell))
703 for (
unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
704 if (vertices_outside_subdomain[cell->vertex_index(v)] ==
true)
706 subdomain_boundary_cells.push_back(cell);
716 const double &DOUBLE_EPSILON = 100.*std::numeric_limits<double>::epsilon();
719 for (
unsigned int d=0; d<spacedim; ++d)
721 bounding_box.first[d] -= (layer_thickness+DOUBLE_EPSILON);
722 bounding_box.second[d] += (layer_thickness+DOUBLE_EPSILON);
725 std::vector<Point<spacedim> > subdomain_boundary_cells_centers;
726 std::vector<double> subdomain_boundary_cells_radii;
727 subdomain_boundary_cells_centers.reserve (subdomain_boundary_cells.size());
728 subdomain_boundary_cells_radii.reserve (subdomain_boundary_cells.size());
730 for (
typename std::vector<typename MeshType::active_cell_iterator>::const_iterator
731 subdomain_boundary_cell_iterator = subdomain_boundary_cells.begin();
732 subdomain_boundary_cell_iterator != subdomain_boundary_cells.end(); ++subdomain_boundary_cell_iterator )
734 const std::pair<Point<spacedim>,
double> &
735 subdomain_boundary_cell_enclosing_ball = (*subdomain_boundary_cell_iterator)->enclosing_ball();
737 subdomain_boundary_cells_centers.push_back( subdomain_boundary_cell_enclosing_ball.first);
738 subdomain_boundary_cells_radii.push_back( subdomain_boundary_cell_enclosing_ball.second);
740 AssertThrow( subdomain_boundary_cells_radii.size() == subdomain_boundary_cells_centers.size(),
749 for (
typename MeshType::active_cell_iterator
750 cell = mesh.begin_active();
751 cell != mesh.end(); ++cell)
754 if ( predicate(cell))
757 const std::pair<Point<spacedim>,
double> &cell_enclosing_ball
758 = cell->enclosing_ball();
760 const Point<spacedim> &cell_enclosing_ball_center = cell_enclosing_ball.first;
761 const double &cell_enclosing_ball_radius = cell_enclosing_ball.second;
763 bool cell_inside =
true;
765 for (
unsigned int d = 0; d < spacedim; ++d)
766 cell_inside &= (cell_enclosing_ball_center[d] + cell_enclosing_ball_radius > bounding_box.first[d])
767 && (cell_enclosing_ball_center[d] - cell_enclosing_ball_radius < bounding_box.second[d]);
772 for (
unsigned int i =0; i< subdomain_boundary_cells_radii.size(); ++i)
773 if ( cell_enclosing_ball_center.
distance_square(subdomain_boundary_cells_centers[i])
774 < Utilities::fixed_power<2>( cell_enclosing_ball_radius +
775 subdomain_boundary_cells_radii[i] +
776 layer_thickness + DOUBLE_EPSILON ))
778 active_cell_layer_within_distance.push_back(cell);
783 return active_cell_layer_within_distance;
788 template <
class MeshType>
789 std::vector<typename MeshType::active_cell_iterator>
793 std::function<bool (const typename MeshType::active_cell_iterator &)> predicate (locally_owned_cell_predicate);
795 const std::vector<typename MeshType::active_cell_iterator>
800 Assert(contains_locally_owned_cells<MeshType>(ghost_cell_layer_within_distance) ==
false,
801 ExcMessage(
"Ghost cells within layer_thickness contains locally owned cells."));
802 Assert(contains_artificial_cells<MeshType>(ghost_cell_layer_within_distance) ==
false,
803 ExcMessage(
"Ghost cells within layer_thickness contains artificial cells." 804 "The function compute_ghost_cell_layer_within_distance " 805 "is probably called while using parallel::distributed::Triangulation. " 806 "In such case please refer to the description of this function."));
808 return ghost_cell_layer_within_distance;
813 template <
class MeshType>
816 (
const MeshType &mesh,
817 const std::function<
bool (
const typename MeshType::active_cell_iterator &)> &predicate )
819 std::vector<bool> locally_active_vertices_on_subdomain (mesh.get_triangulation().n_vertices(),
822 const unsigned int spacedim = MeshType::space_dimension;
829 for (
typename MeshType::active_cell_iterator
830 cell = mesh.begin_active();
831 cell != mesh.end(); ++cell)
832 if ( predicate(cell))
834 minp = cell->center();
835 maxp = cell->center();
841 for (
typename MeshType::active_cell_iterator
842 cell = mesh.begin_active();
843 cell != mesh.end(); ++cell)
845 for (
unsigned int v=0; v<GeometryInfo<MeshType::dimension>::vertices_per_cell; ++v)
846 if (locally_active_vertices_on_subdomain[cell->vertex_index(v)] ==
false)
848 locally_active_vertices_on_subdomain[cell->vertex_index(v)] =
true;
849 for (
unsigned int d=0; d<spacedim; ++d)
851 minp[d] = std::min( minp[d], cell->vertex(v)[d]);
852 maxp[d] = std::max( maxp[d], cell->vertex(v)[d]);
856 return std::make_pair( minp, maxp );
861 template <
typename MeshType>
862 std::list<std::pair<
typename MeshType::cell_iterator,
863 typename MeshType::cell_iterator> >
865 const MeshType &mesh_2)
868 ExcMessage (
"The two meshes must be represent triangulations that " 869 "have the same coarse meshes"));
887 std::list<std::pair<
typename MeshType::cell_iterator,
888 typename MeshType::cell_iterator> >
894 typename MeshType::cell_iterator
895 cell_1 = mesh_1.begin(0),
896 cell_2 = mesh_2.begin(0);
897 for (; cell_1 != mesh_1.end(0); ++cell_1, ++cell_2)
898 cell_list.emplace_back (cell_1, cell_2);
902 typename CellList::iterator cell_pair = cell_list.begin();
903 while (cell_pair != cell_list.end())
909 if (cell_pair->first->has_children()
911 cell_pair->second->has_children())
913 Assert(cell_pair->first->refinement_case()==
915 for (
unsigned int c=0; c<cell_pair->first->n_children(); ++c)
916 cell_list.emplace_back (cell_pair->first->child(c),
917 cell_pair->second->child(c));
926 const typename CellList::iterator previous_cell_pair = cell_pair;
929 cell_list.erase (previous_cell_pair);
941 for (cell_pair = cell_list.begin(); cell_pair != cell_list.end(); ++cell_pair)
942 Assert (cell_pair->first->active()
944 cell_pair->second->active()
946 (cell_pair->first->refinement_case()
947 != cell_pair->second->refinement_case()),
955 template <
int dim,
int spacedim>
969 cell_1 = mesh_1.
begin(0),
970 cell_2 = mesh_2.
begin(0),
971 endc = mesh_1.
end(0);
972 for (; cell_1!=endc; ++cell_1, ++cell_2)
973 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
974 if (cell_1->vertex(v) != cell_2->vertex(v))
986 template <
typename MeshType>
989 const MeshType &mesh_2)
992 mesh_2.get_triangulation());
997 template <
int dim,
int spacedim>
998 std::pair<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator,
Point<dim> >
1005 ExcMessage (
"Mapping collection needs to have either size 1 " 1006 "or size equal to the number of elements in " 1007 "the FECollection."));
1011 std::pair<cell_iterator, Point<dim> > best_cell;
1015 if (mapping.
size() == 1)
1025 double best_distance = 1e-10;
1026 int best_level = -1;
1033 std::vector<cell_iterator> adjacent_cells_tmp =
1041 std::set<cell_iterator> adjacent_cells(adjacent_cells_tmp.begin(), adjacent_cells_tmp.end());
1042 std::set<cell_iterator> searched_cells;
1052 unsigned int cells_searched = 0;
1053 while (!found && cells_searched < n_cells)
1055 typename std::set<cell_iterator>::const_iterator
1056 cell = adjacent_cells.begin(),
1057 endc = adjacent_cells.end();
1058 for (; cell != endc; ++cell)
1062 const Point<dim> p_cell = mapping[(*cell)->active_fe_index()].transform_real_to_unit_cell(*cell, p);
1073 if (dist < best_distance ||
1074 (dist == best_distance && (*cell)->level() > best_level))
1077 best_distance = dist;
1078 best_level = (*cell)->level();
1079 best_cell = std::make_pair(*cell, p_cell);
1098 cells_searched += adjacent_cells.size();
1104 if (!found && cells_searched < n_cells)
1106 find_active_cell_around_point_internal<dim,hp::DoFHandler,spacedim>
1107 (mesh, searched_cells, adjacent_cells);
1114 ExcPointNotFound<spacedim>(p));
1120 template <
class MeshType>
1121 std::vector<typename MeshType::active_cell_iterator>
1124 Assert (cell->is_locally_owned(),
1125 ExcMessage (
"This function only makes sense if the cell for " 1126 "which you are asking for a patch, is locally " 1129 std::vector<typename MeshType::active_cell_iterator> patch;
1130 patch.push_back (cell);
1131 for (
unsigned int face_number=0; face_number<GeometryInfo<MeshType::dimension>::faces_per_cell; ++face_number)
1132 if (cell->face(face_number)->at_boundary()==
false)
1134 if (cell->neighbor(face_number)->has_children() ==
false)
1135 patch.push_back (cell->neighbor(face_number));
1140 if (MeshType::dimension > 1)
1142 for (
unsigned int subface=0; subface<cell->face(face_number)->n_children(); ++subface)
1143 patch.push_back (cell->neighbor_child_on_subface (face_number, subface));
1149 typename MeshType::cell_iterator neighbor
1150 = cell->neighbor (face_number);
1151 while (neighbor->has_children())
1152 neighbor = neighbor->child(1-face_number);
1155 patch.push_back (neighbor);
1163 template <
class Container>
1164 std::vector<typename Container::cell_iterator>
1166 const std::vector<typename Container::active_cell_iterator> &patch)
1168 Assert (patch.size() > 0,
ExcMessage(
"Vector containing patch cells should not be an empty vector!"));
1171 int min_level = patch[0]->level();
1173 for (
unsigned int i=0; i<patch.size(); ++i)
1174 min_level = std::min (min_level, patch[i]->level() );
1175 std::set<typename Container::cell_iterator> uniform_cells;
1176 typename std::vector<typename Container::active_cell_iterator>::const_iterator patch_cell;
1178 for (patch_cell=patch.begin(); patch_cell!=patch.end () ; ++patch_cell)
1182 if ((*patch_cell)->level() == min_level)
1183 uniform_cells.insert (*patch_cell);
1189 typename Container::cell_iterator parent = *patch_cell;
1191 while (parent->level() > min_level)
1192 parent = parent-> parent();
1193 uniform_cells.insert (parent);
1197 return std::vector<typename Container::cell_iterator> (uniform_cells.begin(),
1198 uniform_cells.end());
1203 template <
class Container>
1207 typename Container::active_cell_iterator> &patch_to_global_tria_map)
1210 const std::vector<typename Container::cell_iterator> uniform_cells =
1211 get_cells_at_coarsest_common_level <Container> (patch);
1213 local_triangulation.
clear();
1214 std::vector<Point<Container::space_dimension> > vertices;
1215 const unsigned int n_uniform_cells=uniform_cells.size();
1216 std::vector<CellData<Container::dimension> > cells(n_uniform_cells);
1219 typename std::vector<typename Container::cell_iterator>::const_iterator uniform_cell;
1220 for (uniform_cell=uniform_cells.begin(); uniform_cell!=uniform_cells.end(); ++uniform_cell)
1222 for (
unsigned int v=0; v<GeometryInfo<Container::dimension>::vertices_per_cell; ++v)
1225 bool repeat_vertex=
false;
1227 for (
unsigned int m=0; m<i; ++m)
1229 if (position == vertices[m])
1232 cells[k].vertices[v]=m;
1236 if (repeat_vertex==
false)
1238 vertices.push_back(position);
1239 cells[k].vertices[v]=i;
1249 unsigned int index=0;
1251 std::map<typename Triangulation<Container::dimension,Container::space_dimension>::cell_iterator,
1252 typename Container::cell_iterator> patch_to_global_tria_map_tmp;
1254 coarse_cell != local_triangulation.
end(); ++coarse_cell, ++index)
1256 patch_to_global_tria_map_tmp.insert (std::make_pair(coarse_cell, uniform_cells[index]));
1259 Assert(coarse_cell->center().distance( uniform_cells[index]->center())<=1e-15*coarse_cell->diameter(),
1262 bool refinement_necessary;
1267 refinement_necessary =
false;
1270 active_tria_cell != local_triangulation.
end(); ++active_tria_cell)
1272 if (patch_to_global_tria_map_tmp[active_tria_cell]->has_children())
1274 active_tria_cell -> set_refine_flag();
1275 refinement_necessary =
true;
1277 else for (
unsigned int i=0; i<patch.size(); ++i)
1282 if (patch_to_global_tria_map_tmp[active_tria_cell]==patch[i])
1286 for (
unsigned int v=0; v<GeometryInfo<Container::dimension>::vertices_per_cell; ++v)
1287 active_tria_cell->vertex(v) = patch[i]->vertex(v);
1289 Assert(active_tria_cell->center().distance(patch_to_global_tria_map_tmp[active_tria_cell]->center())
1292 active_tria_cell->set_user_flag();
1298 if (refinement_necessary)
1303 cell = local_triangulation.
begin();
1304 cell != local_triangulation.
end(); ++cell)
1307 if (patch_to_global_tria_map_tmp.find(cell)!=patch_to_global_tria_map_tmp.end())
1309 if (cell-> has_children())
1315 for (
unsigned int c=0; c<cell->n_children(); ++c)
1317 if (patch_to_global_tria_map_tmp.find(cell->child(c)) ==
1318 patch_to_global_tria_map_tmp.end())
1320 patch_to_global_tria_map_tmp.insert (std::make_pair(cell->child(c),
1321 patch_to_global_tria_map_tmp[cell]->child(c)));
1343 patch_to_global_tria_map_tmp.erase(cell);
1350 while (refinement_necessary);
1356 cell = local_triangulation.
begin();
1357 cell != local_triangulation.
end(); ++cell)
1359 if (cell->user_flag_set() )
1361 Assert(patch_to_global_tria_map_tmp.find(cell) != patch_to_global_tria_map_tmp.end(),
1364 Assert(cell->center().distance( patch_to_global_tria_map_tmp[cell]->center())<=1e-15*cell->diameter(),
1370 typename std::map<typename Triangulation<Container::dimension,Container::space_dimension>::cell_iterator,
1371 typename Container::cell_iterator>::iterator map_tmp_it =
1372 patch_to_global_tria_map_tmp.begin(),map_tmp_end = patch_to_global_tria_map_tmp.end();
1375 for (; map_tmp_it!=map_tmp_end; ++map_tmp_it)
1376 patch_to_global_tria_map[map_tmp_it->first] = map_tmp_it->second;
1382 template <
class DoFHandlerType>
1383 std::map< types::global_dof_index,std::vector<typename DoFHandlerType::active_cell_iterator> >
1397 std::map< types::global_dof_index,std::set<typename DoFHandlerType::active_cell_iterator> > dof_to_set_of_cells_map;
1399 std::vector<types::global_dof_index> local_dof_indices;
1400 std::vector<types::global_dof_index> local_face_dof_indices;
1401 std::vector<types::global_dof_index> local_line_dof_indices;
1405 std::vector<bool> user_flags;
1410 std::map<typename DoFHandlerType::active_line_iterator, typename DoFHandlerType::line_iterator > lines_to_parent_lines_map;
1411 if (DoFHandlerType::dimension == 3)
1415 dof_handler.get_triangulation().save_user_flags(user_flags);
1419 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
1420 endc = dof_handler.end();
1421 for (; cell!=endc; ++cell)
1427 if (cell->is_artificial() ==
false)
1429 for (
unsigned int l=0; l<GeometryInfo<DoFHandlerType::dimension>::lines_per_cell; ++l)
1430 if (cell->line(l)->has_children())
1431 for (
unsigned int c=0; c<cell->line(l)->n_children(); ++c)
1433 lines_to_parent_lines_map[cell->line(l)->child(c)] = cell->line(l);
1436 cell->line(l)->child(c)->set_user_flag();
1449 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
1450 endc = dof_handler.end();
1451 for (; cell!=endc; ++cell)
1456 if (cell->is_artificial() ==
false)
1458 const unsigned int n_dofs_per_cell = cell->get_fe().dofs_per_cell;
1459 local_dof_indices.resize(n_dofs_per_cell);
1463 cell->get_dof_indices(local_dof_indices);
1464 for (
unsigned int i=0; i< n_dofs_per_cell; ++i )
1465 dof_to_set_of_cells_map[local_dof_indices[i]].insert(cell);
1475 for (
unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
1477 if (cell->face(f)->has_children())
1479 for (
unsigned int c=0; c<cell->face(f)->n_children(); ++c)
1495 const unsigned int n_dofs_per_face = cell->get_fe().dofs_per_face;
1496 local_face_dof_indices.resize(n_dofs_per_face);
1498 cell->face(f)->child(c)->get_dof_indices(local_face_dof_indices);
1499 for (
unsigned int i=0; i< n_dofs_per_face; ++i )
1500 dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(cell);
1503 else if ((cell->face(f)->at_boundary() ==
false) && (cell->neighbor_is_coarser(f)))
1521 std::pair<unsigned int, unsigned int> neighbor_face_no_subface_no = cell->neighbor_of_coarser_neighbor(f);
1522 unsigned int face_no = neighbor_face_no_subface_no.first;
1523 unsigned int subface = neighbor_face_no_subface_no.second;
1525 const unsigned int n_dofs_per_face = cell->get_fe().dofs_per_face;
1526 local_face_dof_indices.resize(n_dofs_per_face);
1528 cell->neighbor(f)->face(face_no)->get_dof_indices(local_face_dof_indices);
1529 for (
unsigned int i=0; i< n_dofs_per_face; ++i )
1530 dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(cell);
1534 for (
unsigned int c=0; c<cell->neighbor(f)->face(face_no)->n_children(); ++c)
1538 const unsigned int n_dofs_per_face = cell->get_fe().dofs_per_face;
1539 local_face_dof_indices.resize(n_dofs_per_face);
1542 cell->neighbor(f)->face(face_no)->child(c)->get_dof_indices(local_face_dof_indices);
1543 for (
unsigned int i=0; i<n_dofs_per_face; ++i )
1544 dof_to_set_of_cells_map[local_face_dof_indices[i]].insert(cell);
1558 if (DoFHandlerType::dimension == 3)
1560 for (
unsigned int l=0; l<GeometryInfo<DoFHandlerType::dimension>::lines_per_cell; ++l)
1562 if (cell->line(l)->has_children())
1564 for (
unsigned int c=0; c<cell->line(l)->n_children(); ++c)
1570 const unsigned int n_dofs_per_line = 2*cell->get_fe().dofs_per_vertex
1571 + cell->get_fe().dofs_per_line;
1572 local_line_dof_indices.resize(n_dofs_per_line);
1574 cell->line(l)->child(c)->get_dof_indices(local_line_dof_indices);
1575 for (
unsigned int i=0; i<n_dofs_per_line; ++i )
1576 dof_to_set_of_cells_map[local_line_dof_indices[i]].insert(cell);
1583 else if (cell->line(l)->user_flag_set() ==
true)
1585 typename DoFHandlerType::line_iterator parent_line = lines_to_parent_lines_map[cell->line(l)];
1590 const unsigned int n_dofs_per_line = 2*cell->get_fe().dofs_per_vertex
1591 + cell->get_fe().dofs_per_line;
1592 local_line_dof_indices.resize(n_dofs_per_line);
1594 parent_line->get_dof_indices(local_line_dof_indices);
1595 for (
unsigned int i=0; i<n_dofs_per_line; ++i )
1596 dof_to_set_of_cells_map[local_line_dof_indices[i]].insert(cell);
1598 for (
unsigned int c=0; c<parent_line->n_children(); ++c)
1602 const unsigned int n_dofs_per_line = 2*cell->get_fe().dofs_per_vertex
1603 + cell->get_fe().dofs_per_line;
1604 local_line_dof_indices.resize(n_dofs_per_line);
1606 parent_line->child(c)->get_dof_indices(local_line_dof_indices);
1607 for (
unsigned int i=0; i<n_dofs_per_line; ++i )
1608 dof_to_set_of_cells_map[local_line_dof_indices[i]].insert(cell);
1619 if (DoFHandlerType::dimension == 3)
1629 std::map< types::global_dof_index, std::vector<typename DoFHandlerType::active_cell_iterator> > dof_to_cell_patches;
1631 typename std::map<types::global_dof_index, std::set< typename DoFHandlerType::active_cell_iterator> >::iterator
1632 it = dof_to_set_of_cells_map.begin(),
1633 it_end = dof_to_set_of_cells_map.end();
1634 for ( ; it!=it_end; ++it)
1635 dof_to_cell_patches[it->first].assign( it->second.begin(), it->second.end() );
1637 return dof_to_cell_patches;
1643 template <
typename CellIterator>
1645 match_periodic_face_pairs
1646 (std::set<std::pair<CellIterator, unsigned int> > &pairs1,
1647 std::set<std::pair<
typename identity<CellIterator>::type,
unsigned int> > &pairs2,
1648 const int direction,
1649 std::vector<PeriodicFacePair<CellIterator> > &matched_pairs,
1650 const ::Tensor<1,CellIterator::AccessorType::space_dimension> &offset,
1653 static const int space_dim = CellIterator::AccessorType::space_dimension;
1655 Assert (0<=direction && direction<space_dim,
1658 Assert (pairs1.size() == pairs2.size(),
1659 ExcMessage (
"Unmatched faces on periodic boundaries"));
1661 unsigned int n_matches = 0;
1664 std::bitset<3> orientation;
1665 typedef typename std::set
1666 <std::pair<CellIterator, unsigned int> >::const_iterator PairIterator;
1667 for (PairIterator it1 = pairs1.begin(); it1 != pairs1.end(); ++it1)
1669 for (PairIterator it2 = pairs2.begin(); it2 != pairs2.end(); ++it2)
1671 const CellIterator cell1 = it1->first;
1672 const CellIterator cell2 = it2->first;
1673 const unsigned int face_idx1 = it1->second;
1674 const unsigned int face_idx2 = it2->second;
1676 cell1->face(face_idx1),
1677 cell2->face(face_idx2),
1684 const PeriodicFacePair<CellIterator> matched_face =
1687 {face_idx1, face_idx2},
1691 matched_pairs.push_back(matched_face);
1700 AssertThrow (n_matches == pairs1.size() && pairs2.size() == 0,
1701 ExcMessage (
"Unmatched faces on periodic boundaries"));
1706 template <
typename MeshType>
1709 (
const MeshType &mesh,
1711 const int direction,
1712 std::vector<PeriodicFacePair<typename MeshType::cell_iterator> > &matched_pairs,
1716 static const int dim = MeshType::dimension;
1717 static const int space_dim = MeshType::space_dimension;
1720 Assert (0<=direction && direction<space_dim,
1729 std::set<std::pair<typename MeshType::cell_iterator, unsigned int> > pairs1;
1730 std::set<std::pair<typename MeshType::cell_iterator, unsigned int> > pairs2;
1732 for (
typename MeshType::cell_iterator cell = mesh.begin(0);
1733 cell != mesh.end(0); ++cell)
1735 const typename MeshType::face_iterator face_1 = cell->face(2*direction);
1736 const typename MeshType::face_iterator face_2 = cell->face(2*direction+1);
1738 if (face_1->at_boundary() && face_1->boundary_id() == b_id)
1740 const std::pair<typename MeshType::cell_iterator, unsigned int> pair1
1741 = std::make_pair(cell, 2*direction);
1742 pairs1.insert(pair1);
1745 if (face_2->at_boundary() && face_2->boundary_id() == b_id)
1747 const std::pair<typename MeshType::cell_iterator, unsigned int> pair2
1748 = std::make_pair(cell, 2*direction+1);
1749 pairs2.insert(pair2);
1753 Assert (pairs1.size() == pairs2.size(),
1754 ExcMessage (
"Unmatched faces on periodic boundaries"));
1756 Assert (pairs1.size() > 0,
1757 ExcMessage(
"No new periodic face pairs have been found. " 1758 "Are you sure that you've selected the correct boundary " 1759 "id's and that the coarsest level mesh is colorized?"));
1762 const unsigned int size_old = matched_pairs.size();
1766 match_periodic_face_pairs(pairs1, pairs2, direction, matched_pairs, offset,
1771 const unsigned int size_new = matched_pairs.size();
1772 for (
unsigned int i = size_old; i < size_new; ++i)
1774 Assert(matched_pairs[i].orientation == 1,
1775 ExcMessage(
"Found a face match with non standard orientation. " 1776 "This function is only suitable for meshes with cells " 1777 "in default orientation"));
1784 template <
typename MeshType>
1787 (
const MeshType &mesh,
1790 const int direction,
1795 static const int dim = MeshType::dimension;
1796 static const int space_dim = MeshType::space_dimension;
1799 Assert (0<=direction && direction<space_dim,
1805 std::set<std::pair<typename MeshType::cell_iterator, unsigned int> > pairs1;
1806 std::set<std::pair<typename MeshType::cell_iterator, unsigned int> > pairs2;
1808 for (
typename MeshType::cell_iterator cell = mesh.begin(0);
1809 cell != mesh.end(0); ++cell)
1811 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
1813 const typename MeshType::face_iterator face = cell->face(i);
1814 if (face->at_boundary() && face->boundary_id() == b_id1)
1816 const std::pair<typename MeshType::cell_iterator, unsigned int> pair1
1817 = std::make_pair(cell, i);
1818 pairs1.insert(pair1);
1821 if (face->at_boundary() && face->boundary_id() == b_id2)
1823 const std::pair<typename MeshType::cell_iterator, unsigned int> pair2
1824 = std::make_pair(cell, i);
1825 pairs2.insert(pair2);
1830 Assert (pairs1.size() == pairs2.size(),
1831 ExcMessage (
"Unmatched faces on periodic boundaries"));
1833 Assert (pairs1.size() > 0,
1834 ExcMessage(
"No new periodic face pairs have been found. " 1835 "Are you sure that you've selected the correct boundary " 1836 "id's and that the coarsest level mesh is colorized?"));
1839 match_periodic_face_pairs(pairs1, pairs2, direction, matched_pairs, offset,
1854 template <
int spacedim>
1857 const int direction,
1861 Assert (0<=direction && direction<spacedim,
1868 if (matrix.m() == spacedim)
1869 for (
int i = 0; i < spacedim; ++i)
1870 for (
int j = 0; j < spacedim; ++j)
1871 distance(i) += matrix(i,j) * point1(j);
1875 distance += offset - point2;
1877 for (
int i = 0; i < spacedim; ++i)
1883 if (fabs(distance(i)) > 1.e-10)
1901 template <
int dim>
struct OrientationLookupTable {};
1903 template <>
struct OrientationLookupTable<1>
1905 typedef std::array<unsigned int, GeometryInfo<1>::vertices_per_face> MATCH_T;
1906 static inline std::bitset<3> lookup (
const MATCH_T &)
1913 template <>
struct OrientationLookupTable<2>
1915 typedef std::array<unsigned int, GeometryInfo<2>::vertices_per_face> MATCH_T;
1916 static inline std::bitset<3> lookup (
const MATCH_T &matching)
1923 static const MATCH_T m_tff = {{ 0, 1 }};
1924 if (matching == m_tff)
return 1;
1925 static const MATCH_T m_ttf = {{ 1, 0 }};
1926 if (matching == m_ttf)
return 3;
1934 template <>
struct OrientationLookupTable<3>
1936 typedef std::array<unsigned int, GeometryInfo<3>::vertices_per_face> MATCH_T;
1937 static inline std::bitset<3> lookup (
const MATCH_T &matching)
1944 static const MATCH_T m_tff = {{ 0, 1, 2, 3 }};
1945 if (matching == m_tff)
return 1;
1946 static const MATCH_T m_tft = {{ 1, 3, 0, 2 }};
1947 if (matching == m_tft)
return 5;
1948 static const MATCH_T m_ttf = {{ 3, 2, 1, 0 }};
1949 if (matching == m_ttf)
return 3;
1950 static const MATCH_T m_ttt = {{ 2, 0, 3, 1 }};
1951 if (matching == m_ttt)
return 7;
1952 static const MATCH_T m_fff = {{ 0, 2, 1, 3 }};
1953 if (matching == m_fff)
return 0;
1954 static const MATCH_T m_fft = {{ 2, 3, 0, 1 }};
1955 if (matching == m_fft)
return 4;
1956 static const MATCH_T m_ftf = {{ 3, 1, 2, 0 }};
1957 if (matching == m_ftf)
return 2;
1958 static const MATCH_T m_ftt = {{ 1, 0, 3, 2 }};
1959 if (matching == m_ftt)
return 6;
1969 template <
typename FaceIterator>
1972 const FaceIterator &face1,
1973 const FaceIterator &face2,
1974 const int direction,
1978 Assert(matrix.m() == matrix.n(),
1979 ExcMessage(
"The supplied matrix must be a square matrix"));
1981 static const int dim = FaceIterator::AccessorType::dimension;
1986 array<unsigned int, GeometryInfo<dim>::vertices_per_face> matching;
1988 std::set<unsigned int> face2_vertices;
1989 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face; ++i)
1990 face2_vertices.insert(i);
1992 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face; ++i)
1994 for (std::set<unsigned int>::iterator it = face2_vertices.begin();
1995 it != face2_vertices.end();
1999 direction, offset, matrix))
2002 face2_vertices.erase(it);
2009 if (face2_vertices.empty())
2010 orientation = OrientationLookupTable<dim>::lookup(matching);
2012 return face2_vertices.empty();
2017 template <
typename FaceIterator>
2020 const FaceIterator &face2,
2021 const int direction,
2026 std::bitset<3> dummy;
2035 #include "grid_tools_dof_handlers.inst" 2038 DEAL_II_NAMESPACE_CLOSE
unsigned int n_active_cells() const
Contents is actually a matrix.
unsigned int n_cells() const
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
active_cell_iterator begin_active(const unsigned int level=0) const
#define AssertThrow(cond, exc)
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const =0
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
cell_iterator begin(const unsigned int level=0) const
ActiveSelector::active_cell_iterator active_cell_iterator
static double distance_to_unit_cell(const Point< dim > &p)
cell_iterator end() const
virtual void execute_coarsening_and_refinement()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
const std::vector< Point< spacedim > > & get_vertices() const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const Triangulation< dim, spacedim > & get_triangulation() const
const std::vector< bool > & get_used_vertices() const
virtual bool preserves_vertex_locations() const =0
static ::ExceptionBase & ExcNotImplemented()
Iterator points to a valid object.
static ::ExceptionBase & ExcVertexNotUsed(unsigned int arg1)
unsigned int size() const
numbers::NumberTraits< Number >::real_type distance_square(const Point< dim, Number > &p) const
static ::ExceptionBase & ExcInternalError()
Triangulation< dim, spacedim > & get_triangulation()