16 #include <deal.II/base/mpi.h> 17 #include <deal.II/base/mpi.templates.h> 18 #include <deal.II/base/quadrature_lib.h> 19 #include <deal.II/base/thread_management.h> 21 #include <deal.II/distributed/shared_tria.h> 22 #include <deal.II/distributed/tria.h> 24 #include <deal.II/dofs/dof_accessor.h> 25 #include <deal.II/dofs/dof_handler.h> 26 #include <deal.II/dofs/dof_tools.h> 28 #include <deal.II/fe/fe_nothing.h> 29 #include <deal.II/fe/fe_q.h> 30 #include <deal.II/fe/fe_values.h> 31 #include <deal.II/fe/mapping_q.h> 32 #include <deal.II/fe/mapping_q1.h> 33 #include <deal.II/fe/mapping_q_generic.h> 35 #include <deal.II/grid/filtered_iterator.h> 36 #include <deal.II/grid/grid_reordering.h> 37 #include <deal.II/grid/grid_tools.h> 38 #include <deal.II/grid/grid_tools_cache.h> 39 #include <deal.II/grid/manifold.h> 40 #include <deal.II/grid/tria.h> 41 #include <deal.II/grid/tria_accessor.h> 42 #include <deal.II/grid/tria_iterator.h> 44 #include <deal.II/lac/dynamic_sparsity_pattern.h> 45 #include <deal.II/lac/filtered_matrix.h> 46 #include <deal.II/lac/precondition.h> 47 #include <deal.II/lac/solver_cg.h> 48 #include <deal.II/lac/sparse_matrix.h> 49 #include <deal.II/lac/sparsity_pattern.h> 50 #include <deal.II/lac/sparsity_tools.h> 51 #include <deal.II/lac/vector.h> 52 #include <deal.II/lac/vector_memory.h> 54 #include <deal.II/numerics/matrix_tools.h> 56 #include <boost/random/mersenne_twister.hpp> 57 #include <boost/random/uniform_real_distribution.hpp> 66 #include <unordered_map> 68 DEAL_II_NAMESPACE_OPEN
73 template <
int dim,
int spacedim>
83 #if defined(DEAL_II_WITH_P4EST) && defined(DEBUG) 97 const std::vector<Point<spacedim>> &vertices = tria.
get_vertices();
98 std::vector<bool> boundary_vertices(vertices.size(),
false);
104 for (; cell != endc; ++cell)
105 for (
unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
107 if (cell->face(face)->at_boundary())
108 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face;
110 boundary_vertices[cell->face(face)->vertex_index(i)] =
true;
114 double max_distance_sqr = 0;
115 std::vector<bool>::const_iterator pi = boundary_vertices.begin();
116 const unsigned int N = boundary_vertices.size();
117 for (
unsigned int i = 0; i < N; ++i, ++pi)
119 std::vector<bool>::const_iterator pj = pi + 1;
120 for (
unsigned int j = i + 1; j < N; ++j, ++pj)
121 if ((*pi ==
true) && (*pj ==
true) &&
122 ((vertices[i] - vertices[j]).norm_square() > max_distance_sqr))
123 max_distance_sqr = (vertices[i] - vertices[j]).norm_square();
126 return std::sqrt(max_distance_sqr);
131 template <
int dim,
int spacedim>
137 unsigned int mapping_degree = 1;
140 mapping_degree = p->get_degree();
141 else if (
const auto *p =
143 mapping_degree = p->get_degree();
146 const QGauss<dim> quadrature_formula(mapping_degree + 1);
147 const unsigned int n_q_points = quadrature_formula.
size();
159 cell = triangulation.begin_active(),
160 endc = triangulation.end();
162 double local_volume = 0;
165 for (; cell != endc; ++cell)
166 if (cell->is_locally_owned())
169 for (
unsigned int q = 0; q < n_q_points; ++q)
170 local_volume += fe_values.
JxW(q);
173 double global_volume = 0;
175 #ifdef DEAL_II_WITH_MPI 183 global_volume = local_volume;
185 return global_volume;
193 const std::vector<Point<1>> &all_vertices,
196 return all_vertices[vertex_indices[1]][0] -
197 all_vertices[vertex_indices[0]][0];
205 const std::vector<Point<3>> &all_vertices,
214 const double x[8] = {all_vertices[vertex_indices[0]](0),
215 all_vertices[vertex_indices[1]](0),
216 all_vertices[vertex_indices[2]](0),
217 all_vertices[vertex_indices[3]](0),
218 all_vertices[vertex_indices[4]](0),
219 all_vertices[vertex_indices[5]](0),
220 all_vertices[vertex_indices[6]](0),
221 all_vertices[vertex_indices[7]](0)};
222 const double y[8] = {all_vertices[vertex_indices[0]](1),
223 all_vertices[vertex_indices[1]](1),
224 all_vertices[vertex_indices[2]](1),
225 all_vertices[vertex_indices[3]](1),
226 all_vertices[vertex_indices[4]](1),
227 all_vertices[vertex_indices[5]](1),
228 all_vertices[vertex_indices[6]](1),
229 all_vertices[vertex_indices[7]](1)};
230 const double z[8] = {all_vertices[vertex_indices[0]](2),
231 all_vertices[vertex_indices[1]](2),
232 all_vertices[vertex_indices[2]](2),
233 all_vertices[vertex_indices[3]](2),
234 all_vertices[vertex_indices[4]](2),
235 all_vertices[vertex_indices[5]](2),
236 all_vertices[vertex_indices[6]](2),
237 all_vertices[vertex_indices[7]](2)};
276 const double t3 = y[3] * x[2];
277 const double t5 = z[1] * x[5];
278 const double t9 = z[3] * x[2];
279 const double t11 = x[1] * y[0];
280 const double t14 = x[4] * y[0];
281 const double t18 = x[5] * y[7];
282 const double t20 = y[1] * x[3];
283 const double t22 = y[5] * x[4];
284 const double t26 = z[7] * x[6];
285 const double t28 = x[0] * y[4];
287 z[3] * x[1] * y[2] + t3 * z[1] - t5 * y[7] + y[7] * x[4] * z[6] +
288 t9 * y[6] - t11 * z[4] - t5 * y[3] - t14 * z[2] + z[1] * x[4] * y[0] -
289 t18 * z[3] + t20 * z[0] - t22 * z[0] - y[0] * x[5] * z[4] - t26 * y[3] +
290 t28 * z[2] - t9 * y[1] - y[1] * x[4] * z[0] - t11 * z[5];
291 const double t37 = y[1] * x[0];
292 const double t44 = x[1] * y[5];
293 const double t46 = z[1] * x[0];
294 const double t49 = x[0] * y[2];
295 const double t52 = y[5] * x[7];
296 const double t54 = x[3] * y[7];
297 const double t56 = x[2] * z[0];
298 const double t58 = x[3] * y[2];
299 const double t64 = -x[6] * y[4] * z[2] - t37 * z[2] + t18 * z[6] -
300 x[3] * y[6] * z[2] + t11 * z[2] + t5 * y[0] +
301 t44 * z[4] - t46 * y[4] - t20 * z[7] - t49 * z[6] -
302 t22 * z[1] + t52 * z[3] - t54 * z[2] - t56 * y[4] -
303 t58 * z[0] + y[1] * x[2] * z[0] + t9 * y[7] + t37 * z[4];
304 const double t66 = x[1] * y[7];
305 const double t68 = y[0] * x[6];
306 const double t70 = x[7] * y[6];
307 const double t73 = z[5] * x[4];
308 const double t76 = x[6] * y[7];
309 const double t90 = x[4] * z[0];
310 const double t92 = x[1] * y[3];
311 const double t95 = -t66 * z[3] - t68 * z[2] - t70 * z[2] + t26 * y[5] -
312 t73 * y[6] - t14 * z[6] + t76 * z[2] - t3 * z[6] +
313 x[6] * y[2] * z[4] - z[3] * x[6] * y[2] + t26 * y[4] -
314 t44 * z[3] - x[1] * y[2] * z[0] + x[5] * y[6] * z[4] +
315 t54 * z[5] + t90 * y[2] - t92 * z[2] + t46 * y[2];
316 const double t102 = x[2] * y[0];
317 const double t107 = y[3] * x[7];
318 const double t114 = x[0] * y[6];
320 y[0] * x[3] * z[2] - z[7] * x[5] * y[6] - x[2] * y[6] * z[4] +
321 t102 * z[6] - t52 * z[6] + x[2] * y[4] * z[6] - t107 * z[5] - t54 * z[6] +
322 t58 * z[6] - x[7] * y[4] * z[6] + t37 * z[5] - t114 * z[4] + t102 * z[4] -
323 z[1] * x[2] * y[0] + t28 * z[6] - y[5] * x[6] * z[4] -
324 z[5] * x[1] * y[4] - t73 * y[7];
325 const double t129 = z[0] * x[6];
326 const double t133 = y[1] * x[7];
327 const double t145 = y[1] * x[5];
328 const double t156 = t90 * y[6] - t129 * y[4] + z[7] * x[2] * y[6] -
329 t133 * z[5] + x[5] * y[3] * z[7] - t26 * y[2] -
330 t70 * z[3] + t46 * y[3] + z[5] * x[7] * y[4] +
331 z[7] * x[3] * y[6] - t49 * z[4] + t145 * z[7] -
332 x[2] * y[7] * z[6] + t70 * z[5] + t66 * z[5] -
333 z[7] * x[4] * y[6] + t18 * z[4] + x[1] * y[4] * z[0];
334 const double t160 = x[5] * y[4];
335 const double t165 = z[1] * x[7];
336 const double t178 = z[1] * x[3];
338 t107 * z[6] + t22 * z[7] + t76 * z[3] + t160 * z[1] - x[4] * y[2] * z[6] +
339 t70 * z[4] + t165 * y[5] + x[7] * y[2] * z[6] - t76 * z[5] - t76 * z[4] +
340 t133 * z[3] - t58 * z[1] + y[5] * x[0] * z[4] + t114 * z[2] - t3 * z[7] +
341 t20 * z[2] + t178 * y[7] + t129 * y[2];
342 const double t207 = t92 * z[7] + t22 * z[6] + z[3] * x[0] * y[2] -
343 x[0] * y[3] * z[2] - z[3] * x[7] * y[2] - t165 * y[3] -
344 t9 * y[0] + t58 * z[7] + y[3] * x[6] * z[2] +
345 t107 * z[2] + t73 * y[0] - x[3] * y[5] * z[7] +
346 t3 * z[0] - t56 * y[6] - z[5] * x[0] * y[4] +
347 t73 * y[1] - t160 * z[6] + t160 * z[0];
348 const double t228 = -t44 * z[7] + z[5] * x[6] * y[4] - t52 * z[4] -
349 t145 * z[4] + t68 * z[4] + t92 * z[5] - t92 * z[0] +
350 t11 * z[3] + t44 * z[0] + t178 * y[5] - t46 * y[5] -
351 t178 * y[0] - t145 * z[0] - t20 * z[5] - t37 * z[3] -
352 t160 * z[7] + t145 * z[3] + x[4] * y[6] * z[2];
354 return (t34 + t64 + t95 + t125 + t156 + t181 + t207 + t228) / 12.;
362 const std::vector<Point<2>> &all_vertices,
401 const double x[4] = {all_vertices[vertex_indices[0]](0),
402 all_vertices[vertex_indices[1]](0),
403 all_vertices[vertex_indices[2]](0),
404 all_vertices[vertex_indices[3]](0)};
406 const double y[4] = {all_vertices[vertex_indices[0]](1),
407 all_vertices[vertex_indices[1]](1),
408 all_vertices[vertex_indices[2]](1),
409 all_vertices[vertex_indices[3]](1)};
411 return (-x[1] * y[0] + x[1] * y[3] + y[0] * x[2] + x[0] * y[1] -
412 x[0] * y[2] - y[1] * x[3] - x[2] * y[3] + x[3] * y[2]) /
418 template <
int dim,
int spacedim>
424 const auto predicate = [](
const iterator &) {
return true; };
427 tria, std::function<
bool(
const iterator &)>(predicate));
462 template <
int structdim>
463 struct CellDataComparator
470 if (std::lexicographical_compare(std::begin(a.
vertices),
472 std::begin(
b.vertices),
473 std::end(
b.vertices)))
479 if (std::equal(std::begin(a.
vertices),
481 std::begin(
b.vertices)))
486 "Two CellData objects with equal vertices must " 487 "have the same material/boundary ids and manifold " 498 template <
int dim,
int spacedim>
500 tuple<std::vector<Point<spacedim>>, std::vector<CellData<dim>>,
SubCellData>
504 ExcMessage(
"The input triangulation must be non-empty."));
506 std::vector<Point<spacedim>> vertices;
507 std::vector<CellData<dim>> cells;
510 unsigned int max_level_0_vertex_n = 0;
512 for (
unsigned int cell_vertex_n = 0;
513 cell_vertex_n < GeometryInfo<dim>::vertices_per_cell;
515 max_level_0_vertex_n =
516 std::max(cell->vertex_index(cell_vertex_n), max_level_0_vertex_n);
517 vertices.resize(max_level_0_vertex_n + 1);
519 std::set<CellData<1>, CellDataComparator<1>> line_data;
524 for (
unsigned int cell_vertex_n = 0;
525 cell_vertex_n < GeometryInfo<dim>::vertices_per_cell;
528 Assert(cell->vertex_index(cell_vertex_n) < vertices.size(),
530 vertices[cell->vertex_index(cell_vertex_n)] =
531 cell->vertex(cell_vertex_n);
533 cell->vertex_index(cell_vertex_n);
537 cells.push_back(cell_data);
542 for (
unsigned int face_n = 0;
543 face_n < GeometryInfo<dim>::faces_per_cell;
546 const auto face = cell->face(face_n);
548 for (
unsigned int vertex_n = 0;
549 vertex_n < GeometryInfo<dim>::vertices_per_face;
552 face->vertex_index(vertex_n);
553 face_cell_data.boundary_id = face->boundary_id();
554 face_cell_data.manifold_id = face->manifold_id();
556 face_data.insert(face_cell_data);
562 for (
unsigned int line_n = 0;
563 line_n < GeometryInfo<dim>::lines_per_cell;
566 const auto line = cell->line(line_n);
568 for (
unsigned int vertex_n = 0;
569 vertex_n < GeometryInfo<2>::vertices_per_face;
572 line->vertex_index(vertex_n);
576 line_data.insert(line_cell_data);
583 std::vector<bool> used_vertices(vertices.size());
585 for (
unsigned int cell_vertex_n = 0;
586 cell_vertex_n < GeometryInfo<dim>::vertices_per_cell;
588 used_vertices[cell_data.vertices[cell_vertex_n]] =
true;
589 Assert(std::find(used_vertices.begin(), used_vertices.end(),
false) ==
591 ExcMessage(
"The level zero vertices should form a contiguous " 597 append_face_data(face_cell_data, subcell_data);
599 for (
const CellData<1> &face_line_data : line_data)
601 return std::tuple<std::vector<Point<spacedim>>,
602 std::vector<CellData<dim>>,
605 std::move(subcell_data));
610 template <
int dim,
int spacedim>
619 "Invalid SubCellData supplied according to ::check_consistency(). " 620 "This is caused by data containing objects for the wrong dimension."));
623 std::vector<bool> vertex_used(vertices.size(),
false);
624 for (
unsigned int c = 0; c < cells.size(); ++c)
625 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
627 Assert(cells[c].vertices[v] < vertices.size(),
628 ExcMessage(
"Invalid vertex index encountered! cells[" +
632 " is invalid, because only " +
634 " vertices were supplied."));
635 vertex_used[cells[c].vertices[v]] =
true;
642 std::vector<unsigned int> new_vertex_numbers(vertices.size(),
644 unsigned int next_free_number = 0;
645 for (
unsigned int i = 0; i < vertices.size(); ++i)
646 if (vertex_used[i] ==
true)
648 new_vertex_numbers[i] = next_free_number;
653 for (
unsigned int c = 0; c < cells.size(); ++c)
654 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
655 cells[c].vertices[v] = new_vertex_numbers[cells[c].vertices[v]];
660 for (
unsigned int v = 0; v < GeometryInfo<1>::vertices_per_cell; ++v)
663 new_vertex_numbers.size(),
665 "Invalid vertex index in subcelldata.boundary_lines. " 666 "subcelldata.boundary_lines[" +
671 " is invalid, because only " +
673 " vertices were supplied."));
680 for (
unsigned int v = 0; v < GeometryInfo<2>::vertices_per_cell; ++v)
683 new_vertex_numbers.size(),
685 "Invalid vertex index in subcelldata.boundary_quads. " 686 "subcelldata.boundary_quads[" +
691 " is invalid, because only " +
693 " vertices were supplied."));
701 std::vector<Point<spacedim>> tmp;
702 tmp.reserve(std::count(vertex_used.begin(), vertex_used.end(),
true));
703 for (
unsigned int v = 0; v < vertices.size(); ++v)
704 if (vertex_used[v] ==
true)
705 tmp.push_back(vertices[v]);
711 template <
int dim,
int spacedim>
716 std::vector<unsigned int> & considered_vertices,
722 std::vector<unsigned int> new_vertex_numbers(vertices.size());
723 for (
unsigned int i = 0; i < vertices.size(); ++i)
724 new_vertex_numbers[i] = i;
728 if (considered_vertices.size() == 0)
729 considered_vertices = new_vertex_numbers;
737 for (
unsigned int i = 0; i < considered_vertices.size(); ++i)
740 if (new_vertex_numbers[considered_vertices[i]] !=
741 considered_vertices[i])
752 for (
unsigned int j = i + 1; j < considered_vertices.size(); ++j)
755 for (
unsigned int d = 0; d < spacedim; ++d)
756 equal &= (std::abs(vertices[considered_vertices[j]](d) -
757 vertices[considered_vertices[i]](d)) < tol);
760 new_vertex_numbers[considered_vertices[j]] =
761 considered_vertices[i];
770 for (
auto &cell : cells)
771 for (
auto &vertex_index : cell.vertices)
772 vertex_index = new_vertex_numbers[vertex_index];
774 for (
auto &vertex_index : quad.vertices)
775 vertex_index = new_vertex_numbers[vertex_index];
777 for (
auto &vertex_index : line.vertices)
778 vertex_index = new_vertex_numbers[vertex_index];
788 template <
int spacedim>
812 explicit Rotate2d(
const double angle)
818 return {std::cos(angle) * p(0) - std::sin(angle) * p(1),
819 std::sin(angle) * p(0) + std::cos(angle) * p(1)};
830 Rotate3d(
const double angle,
const unsigned int axis)
840 std::cos(angle) * p(1) - std::sin(angle) * p(2),
841 std::sin(angle) * p(1) + std::cos(angle) * p(2)};
843 return {std::cos(angle) * p(0) + std::sin(angle) * p(2),
845 -std::sin(angle) * p(0) + std::cos(angle) * p(2)};
847 return {std::cos(angle) * p(0) - std::sin(angle) * p(1),
848 std::sin(angle) * p(0) + std::cos(angle) * p(1),
854 const unsigned int axis;
857 template <
int spacedim>
861 explicit Scale(
const double factor)
876 template <
int dim,
int spacedim>
881 transform(Shift<spacedim>(shift_vector), triangulation);
889 transform(Rotate2d(angle), triangulation);
895 const unsigned int axis,
900 transform(Rotate3d(angle, axis), triangulation);
903 template <
int dim,
int spacedim>
909 transform(Scale<spacedim>(scaling_factor), triangulation);
922 const std::map<types::global_dof_index, double> &fixed_dofs,
925 const unsigned int n_dofs = S.
n();
937 SF.add_constraints(fixed_dofs);
938 SF.apply_constraints(f,
true);
939 solver.solve(SF, u, f, PF);
963 const bool solve_for_absolute_positions)
970 dof_handler.distribute_dofs(q1);
988 std::map<types::global_dof_index, double> fixed_dofs[dim];
989 typename std::map<unsigned int, Point<dim>>::const_iterator map_end =
994 endc = dof_handler.end();
995 for (; cell != endc; ++cell)
999 for (
unsigned int vertex_no = 0;
1000 vertex_no < GeometryInfo<dim>::vertices_per_cell;
1003 const unsigned int vertex_index = cell->vertex_index(vertex_no);
1004 const Point<dim> & vertex_point = cell->vertex(vertex_no);
1006 const typename std::map<unsigned int, Point<dim>>::const_iterator
1007 map_iter = new_points.find(vertex_index);
1009 if (map_iter != map_end)
1010 for (
unsigned int i = 0; i < dim; ++i)
1011 fixed_dofs[i].insert(std::pair<types::global_dof_index, double>(
1012 cell->vertex_dof_index(vertex_no, 0),
1013 (solve_for_absolute_positions ?
1014 map_iter->second(i) :
1015 map_iter->second(i) - vertex_point[i])));
1021 for (
unsigned int i = 0; i < dim; ++i)
1022 us[i].reinit(dof_handler.n_dofs());
1026 for (
unsigned int i = 0; i < dim; ++i)
1032 std::vector<bool> vertex_touched(triangulation.n_vertices(),
false);
1033 for (cell = dof_handler.begin_active(); cell != endc; ++cell)
1034 for (
unsigned int vertex_no = 0;
1035 vertex_no < GeometryInfo<dim>::vertices_per_cell;
1037 if (vertex_touched[cell->vertex_index(vertex_no)] ==
false)
1042 cell->vertex_dof_index(vertex_no, 0);
1043 for (
unsigned int i = 0; i < dim; ++i)
1044 if (solve_for_absolute_positions)
1045 v(i) = us[i](dof_index);
1047 v(i) += us[i](dof_index);
1049 vertex_touched[cell->vertex_index(vertex_no)] =
true;
1053 template <
int dim,
int spacedim>
1054 std::map<unsigned int, Point<spacedim>>
1057 std::map<unsigned int, Point<spacedim>> vertex_map;
1061 for (; cell != endc; ++cell)
1063 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
1067 if (face->at_boundary())
1069 for (
unsigned j = 0; j < GeometryInfo<dim>::vertices_per_face;
1073 const unsigned int vertex_index = face->vertex_index(j);
1074 vertex_map[vertex_index] = vertex;
1086 template <
int dim,
int spacedim>
1090 const bool keep_boundary)
1107 double almost_infinite_length = 0;
1109 triangulation.begin(0);
1110 cell != triangulation.end(0);
1112 almost_infinite_length += cell->diameter();
1114 std::vector<double> minimal_length(triangulation.n_vertices(),
1115 almost_infinite_length);
1118 std::vector<bool> at_boundary(keep_boundary ? triangulation.n_vertices() :
1123 const bool is_parallel_shared =
1125 &triangulation) !=
nullptr);
1127 triangulation.begin_active();
1128 cell != triangulation.end();
1130 if (is_parallel_shared || cell->is_locally_owned())
1134 for (
unsigned int i = 0; i < GeometryInfo<dim>::lines_per_cell;
1138 line = cell->line(i);
1140 if (keep_boundary && line->at_boundary())
1142 at_boundary[line->vertex_index(0)] =
true;
1143 at_boundary[line->vertex_index(1)] =
true;
1146 minimal_length[line->vertex_index(0)] =
1147 std::min(line->diameter(),
1148 minimal_length[line->vertex_index(0)]);
1149 minimal_length[line->vertex_index(1)] =
1150 std::min(line->diameter(),
1151 minimal_length[line->vertex_index(1)]);
1157 for (
unsigned int vertex = 0; vertex < 2; ++vertex)
1158 if (cell->at_boundary(vertex) ==
true)
1159 at_boundary[cell->vertex_index(vertex)] =
true;
1161 minimal_length[cell->vertex_index(0)] =
1162 std::min(cell->diameter(),
1163 minimal_length[cell->vertex_index(0)]);
1164 minimal_length[cell->vertex_index(1)] =
1165 std::min(cell->diameter(),
1166 minimal_length[cell->vertex_index(1)]);
1175 boost::random::mt19937 rng;
1176 boost::random::uniform_real_distribution<> uniform_distribution(-1, 1);
1181 *distributed_triangulation =
1185 const std::vector<bool> locally_owned_vertices =
1187 std::vector<bool> vertex_moved(triangulation.n_vertices(),
false);
1191 triangulation.begin_active();
1192 cell != triangulation.end();
1194 if (cell->is_locally_owned())
1196 for (
unsigned int vertex_no = 0;
1197 vertex_no < GeometryInfo<dim>::vertices_per_cell;
1200 const unsigned global_vertex_no =
1201 cell->vertex_index(vertex_no);
1206 if ((keep_boundary && at_boundary[global_vertex_no]) ||
1207 vertex_moved[global_vertex_no] ||
1208 !locally_owned_vertices[global_vertex_no])
1213 for (
unsigned int d = 0; d < spacedim; ++d)
1214 shift_vector(d) = uniform_distribution(rng);
1216 shift_vector *= factor * minimal_length[global_vertex_no] /
1217 std::sqrt(shift_vector.
square());
1220 cell->vertex(vertex_no) += shift_vector;
1221 vertex_moved[global_vertex_no] =
true;
1225 #ifdef DEAL_II_WITH_P4EST 1226 distributed_triangulation->communicate_locally_moved_vertices(
1227 locally_owned_vertices);
1229 (void)distributed_triangulation;
1240 const unsigned int n_vertices = triangulation.n_vertices();
1241 std::vector<Point<spacedim>> new_vertex_locations(n_vertices);
1242 const std::vector<Point<spacedim>> &old_vertex_locations =
1243 triangulation.get_vertices();
1245 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
1249 if (keep_boundary && at_boundary[vertex])
1250 new_vertex_locations[vertex] = old_vertex_locations[vertex];
1255 for (
unsigned int d = 0; d < spacedim; ++d)
1256 shift_vector(d) = uniform_distribution(rng);
1258 shift_vector *= factor * minimal_length[vertex] /
1259 std::sqrt(shift_vector.
square());
1262 new_vertex_locations[vertex] =
1263 old_vertex_locations[vertex] + shift_vector;
1269 triangulation.begin_active();
1270 cell != triangulation.end();
1272 for (
unsigned int vertex_no = 0;
1273 vertex_no < GeometryInfo<dim>::vertices_per_cell;
1275 cell->vertex(vertex_no) =
1276 new_vertex_locations[cell->vertex_index(vertex_no)];
1290 cell = triangulation.begin_active(),
1291 endc = triangulation.end();
1292 for (; cell != endc; ++cell)
1293 if (!cell->is_artificial())
1294 for (
unsigned int face = 0;
1295 face < GeometryInfo<dim>::faces_per_cell;
1297 if (cell->face(face)->has_children() &&
1298 !cell->face(face)->at_boundary())
1302 cell->face(face)->child(0)->vertex(1) =
1303 (cell->face(face)->vertex(0) +
1304 cell->face(face)->vertex(1)) /
1308 cell->face(face)->child(0)->vertex(1) =
1309 .5 * (cell->face(face)->vertex(0) +
1310 cell->face(face)->vertex(1));
1311 cell->face(face)->child(0)->vertex(2) =
1312 .5 * (cell->face(face)->vertex(0) +
1313 cell->face(face)->vertex(2));
1314 cell->face(face)->child(1)->vertex(3) =
1315 .5 * (cell->face(face)->vertex(1) +
1316 cell->face(face)->vertex(3));
1317 cell->face(face)->child(2)->vertex(3) =
1318 .5 * (cell->face(face)->vertex(2) +
1319 cell->face(face)->vertex(3));
1322 cell->face(face)->child(0)->vertex(3) =
1323 .25 * (cell->face(face)->vertex(0) +
1324 cell->face(face)->vertex(1) +
1325 cell->face(face)->vertex(2) +
1326 cell->face(face)->vertex(3));
1334 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1338 const std::vector<bool> & marked_vertices)
1344 const std::vector<Point<spacedim>> &vertices = tria.
get_vertices();
1347 marked_vertices.size() == 0,
1349 marked_vertices.size()));
1356 marked_vertices.size() == 0 ||
1357 std::equal(marked_vertices.begin(),
1358 marked_vertices.end(),
1360 [](
bool p,
bool q) {
return !p || q; }),
1362 "marked_vertices should be a subset of used vertices in the triangulation " 1363 "but marked_vertices contains one or more vertices that are not used vertices!"));
1367 const std::vector<bool> &vertices_to_use = (marked_vertices.size() == 0) ?
1373 std::vector<bool>::const_iterator first =
1374 std::find(vertices_to_use.begin(), vertices_to_use.end(),
true);
1379 unsigned int best_vertex = std::distance(vertices_to_use.begin(), first);
1380 double best_dist = (p - vertices[best_vertex]).norm_square();
1384 for (
unsigned int j = best_vertex + 1; j < vertices.size(); j++)
1385 if (vertices_to_use[j])
1387 const double dist = (p - vertices[j]).norm_square();
1388 if (dist < best_dist)
1400 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1403 const MeshType<dim, spacedim> &mesh,
1405 const std::vector<bool> & marked_vertices)
1418 marked_vertices.size() == 0,
1420 marked_vertices.size()));
1428 marked_vertices.size() == 0 ||
1429 std::equal(marked_vertices.begin(),
1430 marked_vertices.end(),
1432 [](
bool p,
bool q) {
return !p || q; }),
1434 "marked_vertices should be a subset of used vertices in the triangulation " 1435 "but marked_vertices contains one or more vertices that are not used vertices!"));
1438 if (marked_vertices.size() != 0)
1439 for (
auto it = vertices.begin(); it != vertices.end();)
1441 if (marked_vertices[it->first] ==
false)
1443 it = vertices.erase(it);
1456 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1458 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
1461 typename ::internal::
1462 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
1465 const unsigned int vertex)
1470 Assert(vertex < mesh.get_triangulation().n_vertices(),
1471 ExcIndexRange(0, mesh.get_triangulation().n_vertices(), vertex));
1472 Assert(mesh.get_triangulation().get_used_vertices()[vertex],
1479 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
1517 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; v++)
1518 if (cell->vertex_index(v) == vertex)
1523 adjacent_cells.insert(cell);
1530 for (
unsigned int vface = 0; vface < dim; vface++)
1532 const unsigned int face =
1535 if (!cell->at_boundary(face) &&
1536 cell->neighbor(face)->active())
1548 adjacent_cells.insert(cell->neighbor(face));
1559 for (
unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++e)
1560 if (cell->line(e)->has_children())
1564 if (cell->line(e)->child(0)->vertex_index(1) == vertex)
1566 adjacent_cells.insert(cell);
1588 typename ::internal::
1589 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>(
1590 adjacent_cells.begin(), adjacent_cells.end());
1595 template <
int dim,
int spacedim>
1596 std::vector<std::vector<Tensor<1, spacedim>>>
1603 const std::vector<Point<spacedim>> &vertices = mesh.
get_vertices();
1604 const unsigned int n_vertices = vertex_to_cells.size();
1609 std::vector<std::vector<Tensor<1, spacedim>>> vertex_to_cell_centers(
1611 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
1614 const unsigned int n_neighbor_cells = vertex_to_cells[vertex].size();
1615 vertex_to_cell_centers[vertex].resize(n_neighbor_cells);
1617 typename std::set<typename Triangulation<dim, spacedim>::
1618 active_cell_iterator>::iterator it =
1619 vertex_to_cells[vertex].begin();
1620 for (
unsigned int cell = 0; cell < n_neighbor_cells; ++cell, ++it)
1622 vertex_to_cell_centers[vertex][cell] =
1623 (*it)->center() - vertices[vertex];
1624 vertex_to_cell_centers[vertex][cell] /=
1625 vertex_to_cell_centers[vertex][cell].
norm();
1628 return vertex_to_cell_centers;
1634 template <
int spacedim>
1636 compare_point_association(
1637 const unsigned int a,
1638 const unsigned int b,
1642 const double scalar_product_a = center_directions[a] * point_direction;
1643 const double scalar_product_b = center_directions[b] * point_direction;
1648 return (scalar_product_a > scalar_product_b);
1652 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1654 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim>>
1656 std::pair<typename ::internal::
1657 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1662 const MeshType<dim, spacedim> &mesh,
1665 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator>>
1668 const typename MeshType<dim, spacedim>::active_cell_iterator &cell_hint,
1669 const std::vector<bool> & marked_vertices,
1670 const RTree<std::pair<
Point<spacedim>,
unsigned int>> &used_vertices_rtree)
1672 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1677 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1679 cell_and_position_approx;
1681 bool found_cell =
false;
1682 bool approx_cell =
false;
1684 unsigned int closest_vertex_index = 0;
1686 auto current_cell = cell_hint;
1688 while (found_cell ==
false)
1694 const unsigned int closest_vertex =
1695 find_closest_vertex_of_cell<dim, spacedim>(current_cell, p);
1696 vertex_to_point = p - current_cell->vertex(closest_vertex);
1697 closest_vertex_index = current_cell->vertex_index(closest_vertex);
1701 if (!used_vertices_rtree.empty())
1704 using ValueType = std::pair<Point<spacedim>,
unsigned int>;
1705 std::function<bool(const ValueType &)> marked;
1706 if (marked_vertices.size() == mesh.n_vertices())
1707 marked = [&marked_vertices](
const ValueType &value) ->
bool {
1708 return marked_vertices[value.second];
1711 marked = [](
const ValueType &) ->
bool {
return true; };
1713 std::vector<std::pair<Point<spacedim>,
unsigned int>> res;
1714 used_vertices_rtree.query(
1715 boost::geometry::index::nearest(p, 1) &&
1716 boost::geometry::index::satisfies(marked),
1717 std::back_inserter(res));
1721 closest_vertex_index = res[0].second;
1725 closest_vertex_index =
1728 vertex_to_point = p - mesh.get_vertices()[closest_vertex_index];
1731 const double vertex_point_norm = vertex_to_point.
norm();
1732 if (vertex_point_norm > 0)
1733 vertex_to_point /= vertex_point_norm;
1735 const unsigned int n_neighbor_cells =
1736 vertex_to_cells[closest_vertex_index].size();
1739 std::vector<unsigned int> neighbor_permutation(n_neighbor_cells);
1741 for (
unsigned int i = 0; i < n_neighbor_cells; ++i)
1742 neighbor_permutation[i] = i;
1744 auto comp = [&](
const unsigned int a,
const unsigned int b) ->
bool {
1745 return compare_point_association<spacedim>(
1749 vertex_to_cell_centers[closest_vertex_index]);
1752 std::sort(neighbor_permutation.begin(),
1753 neighbor_permutation.end(),
1759 double best_distance = 1e-10;
1763 for (
unsigned int i = 0; i < n_neighbor_cells; ++i)
1767 auto cell = vertex_to_cells[closest_vertex_index].
begin();
1768 std::advance(cell, neighbor_permutation[i]);
1773 cell_and_position.first = *cell;
1774 cell_and_position.second = p_unit;
1776 approx_cell =
false;
1784 if (dist < best_distance)
1786 best_distance = dist;
1787 cell_and_position_approx.first = *cell;
1788 cell_and_position_approx.second = p_unit;
1796 if (found_cell ==
true)
1797 return cell_and_position;
1798 else if (approx_cell ==
true)
1799 return cell_and_position_approx;
1813 ExcPointNotFound<spacedim>(p));
1815 current_cell =
typename MeshType<dim, spacedim>::active_cell_iterator();
1817 return cell_and_position;
1822 template <
int dim,
int spacedim>
1829 unsigned int closest_vertex = 0;
1831 for (
unsigned int v = 1; v < GeometryInfo<dim>::vertices_per_cell; ++v)
1833 const double vertex_distance =
1835 if (vertex_distance < minimum_distance)
1838 minimum_distance = vertex_distance;
1841 return closest_vertex;
1848 namespace BoundingBoxPredicate
1850 template <
class MeshType>
1851 std::tuple<BoundingBox<MeshType::space_dimension>,
bool>
1852 compute_cell_predicate_bounding_box(
1853 const typename MeshType::cell_iterator &parent_cell,
1854 const std::function<
1855 bool(
const typename MeshType::active_cell_iterator &)> &predicate)
1857 bool has_predicate =
1859 std::vector<typename MeshType::active_cell_iterator> active_cells;
1860 if (parent_cell->active())
1861 active_cells = {parent_cell};
1865 active_cells = get_active_child_cells<MeshType>(parent_cell);
1867 const unsigned int spacedim = MeshType::space_dimension;
1871 while (i < active_cells.size() && !predicate(active_cells[i]))
1875 if (active_cells.size() == 0 || i == active_cells.size())
1878 return std::make_tuple(bbox, has_predicate);
1885 for (; i < active_cells.size(); ++i)
1886 if (predicate(active_cells[i]))
1887 for (
unsigned int v = 0;
1888 v < GeometryInfo<spacedim>::vertices_per_cell;
1890 for (
unsigned int d = 0;
d < spacedim; ++
d)
1892 minp[
d] = std::min(minp[d], active_cells[i]->vertex(v)[d]);
1893 maxp[
d] = std::max(maxp[d], active_cells[i]->vertex(v)[d]);
1896 has_predicate =
true;
1898 return std::make_tuple(bbox, has_predicate);
1905 template <
class MeshType>
1906 std::vector<BoundingBox<MeshType::space_dimension>>
1908 const MeshType &mesh,
1909 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1911 const unsigned int refinement_level,
1912 const bool allow_merge,
1913 const unsigned int max_boxes)
1920 refinement_level <= mesh.n_levels(),
1922 "Error: refinement level is higher then total levels in the triangulation!"));
1924 const unsigned int spacedim = MeshType::space_dimension;
1925 std::vector<BoundingBox<spacedim>> bounding_boxes;
1929 for (
unsigned int i = 0; i < refinement_level; ++i)
1930 for (
const typename MeshType::cell_iterator &cell :
1933 bool has_predicate =
false;
1935 std::tie(bbox, has_predicate) =
1936 internal::BoundingBoxPredicate::compute_cell_predicate_bounding_box<
1937 MeshType>(cell, predicate);
1939 bounding_boxes.push_back(bbox);
1943 for (
const typename MeshType::cell_iterator &cell :
1946 bool has_predicate =
false;
1948 std::tie(bbox, has_predicate) =
1949 internal::BoundingBoxPredicate::compute_cell_predicate_bounding_box<
1950 MeshType>(cell, predicate);
1952 bounding_boxes.push_back(bbox);
1957 return bounding_boxes;
1963 std::vector<unsigned int> merged_boxes_idx;
1964 bool found_neighbors =
true;
1969 while (found_neighbors)
1971 found_neighbors =
false;
1972 for (
unsigned int i = 0; i < bounding_boxes.size() - 1; ++i)
1974 if (std::find(merged_boxes_idx.begin(),
1975 merged_boxes_idx.end(),
1976 i) == merged_boxes_idx.end())
1977 for (
unsigned int j = i + 1; j < bounding_boxes.size(); ++j)
1978 if (std::find(merged_boxes_idx.begin(),
1979 merged_boxes_idx.end(),
1980 j) == merged_boxes_idx.end() &&
1981 bounding_boxes[i].get_neighbor_type(
1982 bounding_boxes[j]) ==
1983 NeighborType::mergeable_neighbors)
1985 bounding_boxes[i].merge_with(bounding_boxes[j]);
1986 merged_boxes_idx.push_back(j);
1987 found_neighbors =
true;
1993 std::vector<BoundingBox<spacedim>> merged_b_boxes;
1994 for (
unsigned int i = 0; i < bounding_boxes.size(); ++i)
1995 if (std::find(merged_boxes_idx.begin(), merged_boxes_idx.end(), i) ==
1996 merged_boxes_idx.end())
1997 merged_b_boxes.push_back(bounding_boxes[i]);
2002 if ((merged_b_boxes.size() > max_boxes) && (spacedim > 1))
2004 std::vector<double> volumes;
2005 for (
unsigned int i = 0; i < merged_b_boxes.size(); ++i)
2006 volumes.push_back(merged_b_boxes[i].volume());
2008 while (merged_b_boxes.size() > max_boxes)
2010 unsigned int min_idx =
2011 std::min_element(volumes.begin(), volumes.end()) -
2013 volumes.erase(volumes.begin() + min_idx);
2015 bool not_removed =
true;
2016 for (
unsigned int i = 0;
2017 i < merged_b_boxes.size() && not_removed;
2022 if (i != min_idx && (merged_b_boxes[i].get_neighbor_type(
2023 merged_b_boxes[min_idx]) ==
2024 NeighborType::attached_neighbors ||
2025 merged_b_boxes[i].get_neighbor_type(
2026 merged_b_boxes[min_idx]) ==
2027 NeighborType::mergeable_neighbors))
2029 merged_b_boxes[i].merge_with(merged_b_boxes[min_idx]);
2030 merged_b_boxes.erase(merged_b_boxes.begin() + min_idx);
2031 not_removed =
false;
2034 ExcMessage(
"Error: couldn't merge bounding boxes!"));
2037 Assert(merged_b_boxes.size() <= max_boxes,
2039 "Error: couldn't reach target number of bounding boxes!"));
2040 return merged_b_boxes;
2046 template <
int spacedim>
2048 std::tuple<std::vector<std::vector<unsigned int>>,
2049 std::map<unsigned int, unsigned int>,
2050 std::map<unsigned int, std::vector<unsigned int>>>
2058 unsigned int n_procs = global_bboxes.size();
2059 std::vector<std::vector<unsigned int>> point_owners(n_procs);
2060 std::map<unsigned int, unsigned int> map_owners_found;
2061 std::map<unsigned int, std::vector<unsigned int>> map_owners_guessed;
2063 unsigned int n_points = points.size();
2064 for (
unsigned int pt = 0; pt < n_points; ++pt)
2067 std::vector<unsigned int> owners_found;
2069 for (
unsigned int rk = 0; rk < n_procs; ++rk)
2072 if (bbox.point_inside(points[pt]))
2074 point_owners[rk].emplace_back(pt);
2075 owners_found.emplace_back(rk);
2079 Assert(owners_found.size() > 0,
2080 ExcMessage(
"No owners found for the point " +
2081 std::to_string(pt)));
2082 if (owners_found.size() == 1)
2083 map_owners_found[pt] = owners_found[0];
2086 map_owners_guessed[pt] = owners_found;
2089 return std::make_tuple(std::move(point_owners),
2090 std::move(map_owners_found),
2091 std::move(map_owners_guessed));
2094 template <
int spacedim>
2096 std::tuple<std::map<unsigned int, std::vector<unsigned int>>,
2097 std::map<unsigned int, unsigned int>,
2098 std::map<unsigned int, std::vector<unsigned int>>>
2106 std::map<unsigned int, std::vector<unsigned int>> point_owners;
2107 std::map<unsigned int, unsigned int> map_owners_found;
2108 std::map<unsigned int, std::vector<unsigned int>> map_owners_guessed;
2109 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>> search_result;
2111 unsigned int n_points = points.size();
2112 for (
unsigned int pt_n = 0; pt_n < n_points; ++pt_n)
2114 search_result.clear();
2117 covering_rtree.query(boost::geometry::index::intersects(points[pt_n]),
2118 std::back_inserter(search_result));
2121 std::set<unsigned int> owners_found;
2123 for (
const auto &rank_bbox : search_result)
2127 const bool pt_inserted = owners_found.insert(pt_n).second;
2129 point_owners[rank_bbox.second].emplace_back(pt_n);
2131 Assert(owners_found.size() > 0,
2132 ExcMessage(
"No owners found for the point " +
2133 std::to_string(pt_n)));
2134 if (owners_found.size() == 1)
2135 map_owners_found[pt_n] = *owners_found.begin();
2138 std::copy(owners_found.begin(),
2140 std::back_inserter(map_owners_guessed[pt_n]));
2143 return std::make_tuple(std::move(point_owners),
2144 std::move(map_owners_found),
2145 std::move(map_owners_guessed));
2149 template <
int dim,
int spacedim>
2151 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>>
2155 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>>
2158 cell = triangulation.begin_active(),
2159 endc = triangulation.end();
2160 for (; cell != endc; ++cell)
2161 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
2165 cell = triangulation.begin_active();
2166 for (; cell != endc; ++cell)
2168 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
2170 if ((cell->at_boundary(i) ==
false) &&
2171 (cell->neighbor(i)->active()))
2174 adjacent_cell = cell->neighbor(i);
2175 for (
unsigned int j = 0;
2176 j < GeometryInfo<dim>::vertices_per_face;
2186 for (
unsigned int i = 0; i < GeometryInfo<dim>::lines_per_cell; ++i)
2187 if (cell->line(i)->has_children())
2201 template <
int dim,
int spacedim>
2202 std::map<unsigned int, types::global_vertex_index>
2206 std::map<unsigned int, types::global_vertex_index>
2207 local_to_global_vertex_index;
2209 #ifndef DEAL_II_WITH_MPI 2214 (void)triangulation;
2216 ExcMessage(
"This function does not make any sense " 2217 "for parallel::distributed::Triangulation " 2218 "objects if you do not have MPI enabled."));
2222 using active_cell_iterator =
2224 const std::vector<std::set<active_cell_iterator>> vertex_to_cell =
2229 unsigned int max_cellid_size = 0;
2230 std::set<std::pair<types::subdomain_id, types::global_vertex_index>>
2232 std::map<types::subdomain_id, std::set<unsigned int>> vertices_to_recv;
2238 active_cell_iterator cell = triangulation.begin_active(),
2239 endc = triangulation.end();
2240 std::set<active_cell_iterator> missing_vert_cells;
2241 std::set<unsigned int> used_vertex_index;
2242 for (; cell != endc; ++cell)
2244 if (cell->is_locally_owned())
2246 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell;
2250 typename std::set<active_cell_iterator>::iterator
2251 adjacent_cell = vertex_to_cell[cell->vertex_index(i)].begin(),
2252 end_adj_cell = vertex_to_cell[cell->vertex_index(i)].end();
2253 for (; adjacent_cell != end_adj_cell; ++adjacent_cell)
2254 lowest_subdomain_id =
2255 std::min(lowest_subdomain_id,
2256 (*adjacent_cell)->subdomain_id());
2259 if (lowest_subdomain_id == cell->subdomain_id())
2263 if (used_vertex_index.find(cell->vertex_index(i)) ==
2264 used_vertex_index.end())
2267 local_to_global_vertex_index[cell->vertex_index(i)] =
2273 vertex_to_cell[cell->vertex_index(i)].begin();
2274 for (; adjacent_cell != end_adj_cell; ++adjacent_cell)
2275 if ((*adjacent_cell)->subdomain_id() !=
2276 cell->subdomain_id())
2280 tmp((*adjacent_cell)->subdomain_id(),
2281 cell->vertex_index(i));
2282 if (vertices_added.find(tmp) ==
2283 vertices_added.end())
2285 vertices_to_send[(*adjacent_cell)
2288 cell->vertex_index(i),
2289 cell->id().to_string());
2290 if (cell->id().to_string().size() >
2293 cell->id().to_string().size();
2294 vertices_added.insert(tmp);
2297 used_vertex_index.insert(cell->vertex_index(i));
2304 vertices_to_recv[lowest_subdomain_id].insert(
2305 cell->vertex_index(i));
2306 missing_vert_cells.insert(cell);
2313 if (cell->is_ghost())
2315 for (
unsigned int i = 0; i < GeometryInfo<dim>::faces_per_cell; ++i)
2317 if (cell->at_boundary(i) ==
false)
2319 if (cell->neighbor(i)->active())
2322 spacedim>::active_cell_iterator
2323 adjacent_cell = cell->neighbor(i);
2324 if ((adjacent_cell->is_locally_owned()))
2327 adjacent_cell->subdomain_id();
2328 if (cell->subdomain_id() < adj_subdomain_id)
2329 for (
unsigned int j = 0;
2330 j < GeometryInfo<dim>::vertices_per_face;
2333 vertices_to_recv[cell->subdomain_id()].insert(
2334 cell->face(i)->vertex_index(j));
2335 missing_vert_cells.insert(cell);
2350 const unsigned int n_cpu =
2352 std::vector<types::global_vertex_index> indices(n_cpu);
2353 int ierr = MPI_Allgather(&next_index,
2355 DEAL_II_VERTEX_INDEX_MPI_TYPE,
2358 DEAL_II_VERTEX_INDEX_MPI_TYPE,
2359 triangulation.get_communicator());
2361 Assert(indices.begin() + triangulation.locally_owned_subdomain() <
2365 std::accumulate(indices.begin(),
2366 indices.begin() + triangulation.locally_owned_subdomain(),
2369 std::map<unsigned int, types::global_vertex_index>::iterator
2370 global_index_it = local_to_global_vertex_index.begin(),
2371 global_index_end = local_to_global_vertex_index.end();
2372 for (; global_index_it != global_index_end; ++global_index_it)
2373 global_index_it->second +=
shift;
2380 std::vector<std::vector<types::global_vertex_index>> vertices_send_buffers(
2381 vertices_to_send.size());
2382 std::vector<MPI_Request> first_requests(vertices_to_send.size());
2386 std::string>>>::iterator
2387 vert_to_send_it = vertices_to_send.begin(),
2388 vert_to_send_end = vertices_to_send.end();
2389 for (
unsigned int i = 0; vert_to_send_it != vert_to_send_end;
2390 ++vert_to_send_it, ++i)
2392 int destination = vert_to_send_it->first;
2393 const unsigned int n_vertices = vert_to_send_it->second.size();
2394 const int buffer_size = 2 * n_vertices;
2395 vertices_send_buffers[i].resize(buffer_size);
2398 for (
unsigned int j = 0; j < n_vertices; ++j)
2400 vertices_send_buffers[i][2 * j] =
2401 std::get<0>(vert_to_send_it->second[j]);
2402 vertices_send_buffers[i][2 * j + 1] =
2403 local_to_global_vertex_index[std::get<1>(
2404 vert_to_send_it->second[j])];
2408 ierr = MPI_Isend(vertices_send_buffers[i].data(),
2410 DEAL_II_VERTEX_INDEX_MPI_TYPE,
2413 triangulation.get_communicator(),
2414 &first_requests[i]);
2419 std::vector<std::vector<types::global_vertex_index>> vertices_recv_buffers(
2420 vertices_to_recv.size());
2421 typename std::map<types::subdomain_id, std::set<unsigned int>>::iterator
2422 vert_to_recv_it = vertices_to_recv.begin(),
2423 vert_to_recv_end = vertices_to_recv.end();
2424 for (
unsigned int i = 0; vert_to_recv_it != vert_to_recv_end;
2425 ++vert_to_recv_it, ++i)
2427 int source = vert_to_recv_it->first;
2428 const unsigned int n_vertices = vert_to_recv_it->second.size();
2429 const int buffer_size = 2 * n_vertices;
2430 vertices_recv_buffers[i].resize(buffer_size);
2433 ierr = MPI_Recv(vertices_recv_buffers[i].data(),
2435 DEAL_II_VERTEX_INDEX_MPI_TYPE,
2438 triangulation.get_communicator(),
2445 std::vector<std::vector<char>> cellids_send_buffers(
2446 vertices_to_send.size());
2447 std::vector<MPI_Request> second_requests(vertices_to_send.size());
2448 vert_to_send_it = vertices_to_send.begin();
2449 for (
unsigned int i = 0; vert_to_send_it != vert_to_send_end;
2450 ++vert_to_send_it, ++i)
2452 int destination = vert_to_send_it->first;
2453 const unsigned int n_vertices = vert_to_send_it->second.size();
2454 const int buffer_size = max_cellid_size * n_vertices;
2455 cellids_send_buffers[i].resize(buffer_size);
2458 unsigned int pos = 0;
2459 for (
unsigned int j = 0; j < n_vertices; ++j)
2461 std::string cell_id = std::get<2>(vert_to_send_it->second[j]);
2462 for (
unsigned int k = 0; k < max_cellid_size; ++k, ++pos)
2464 if (k < cell_id.size())
2465 cellids_send_buffers[i][pos] = cell_id[k];
2469 cellids_send_buffers[i][pos] =
'-';
2474 ierr = MPI_Isend(cellids_send_buffers[i].data(),
2479 triangulation.get_communicator(),
2480 &second_requests[i]);
2485 std::vector<std::vector<char>> cellids_recv_buffers(
2486 vertices_to_recv.size());
2487 vert_to_recv_it = vertices_to_recv.begin();
2488 for (
unsigned int i = 0; vert_to_recv_it != vert_to_recv_end;
2489 ++vert_to_recv_it, ++i)
2491 int source = vert_to_recv_it->first;
2492 const unsigned int n_vertices = vert_to_recv_it->second.size();
2493 const int buffer_size = max_cellid_size * n_vertices;
2494 cellids_recv_buffers[i].resize(buffer_size);
2497 ierr = MPI_Recv(cellids_recv_buffers[i].data(),
2502 triangulation.get_communicator(),
2509 vert_to_recv_it = vertices_to_recv.begin();
2510 for (
unsigned int i = 0; vert_to_recv_it != vert_to_recv_end;
2511 ++i, ++vert_to_recv_it)
2513 for (
unsigned int j = 0; j < vert_to_recv_it->second.size(); ++j)
2515 const unsigned int local_pos_recv = vertices_recv_buffers[i][2 * j];
2517 vertices_recv_buffers[i][2 * j + 1];
2518 const std::string cellid_recv(
2519 &cellids_recv_buffers[i][max_cellid_size * j],
2520 &cellids_recv_buffers[i][max_cellid_size * j] + max_cellid_size);
2522 typename std::set<active_cell_iterator>::iterator
2523 cell_set_it = missing_vert_cells.begin(),
2524 end_cell_set = missing_vert_cells.end();
2525 for (; (found ==
false) && (cell_set_it != end_cell_set);
2528 typename std::set<active_cell_iterator>::iterator
2530 vertex_to_cell[(*cell_set_it)->vertex_index(i)].begin(),
2532 vertex_to_cell[(*cell_set_it)->vertex_index(i)].end();
2533 for (; candidate_cell != end_cell; ++candidate_cell)
2535 std::string current_cellid =
2536 (*candidate_cell)->id().to_string();
2537 current_cellid.resize(max_cellid_size,
'-');
2538 if (current_cellid.compare(cellid_recv) == 0)
2540 local_to_global_vertex_index
2541 [(*candidate_cell)->vertex_index(local_pos_recv)] =
2553 return local_to_global_vertex_index;
2558 template <
int dim,
int spacedim>
2564 cell_connectivity.
reinit(triangulation.n_active_cells(),
2565 triangulation.n_active_cells());
2572 std::map<std::pair<unsigned int, unsigned int>,
unsigned int> indexmap;
2573 for (
const auto &cell : triangulation.active_cell_iterators())
2574 indexmap[std::pair<unsigned int, unsigned int>(cell->level(),
2576 cell->active_cell_index();
2585 for (
const auto &cell : triangulation.active_cell_iterators())
2587 const unsigned int index = cell->active_cell_index();
2588 cell_connectivity.
add(index, index);
2589 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
2590 if ((cell->at_boundary(f) ==
false) &&
2591 (cell->neighbor(f)->has_children() ==
false))
2593 const unsigned int other_index =
2595 .find(std::pair<unsigned int, unsigned int>(
2596 cell->neighbor(f)->level(), cell->neighbor(f)->index()))
2598 cell_connectivity.
add(index, other_index);
2599 cell_connectivity.
add(other_index, index);
2606 template <
int dim,
int spacedim>
2612 std::vector<std::vector<unsigned int>> vertex_to_cell(
2613 triangulation.n_vertices());
2615 triangulation.begin_active();
2616 cell != triangulation.end();
2619 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
2620 vertex_to_cell[cell->vertex_index(v)].push_back(
2621 cell->active_cell_index());
2624 cell_connectivity.
reinit(triangulation.n_active_cells(),
2625 triangulation.n_active_cells());
2627 triangulation.begin_active();
2628 cell != triangulation.end();
2631 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
2632 for (
unsigned int n = 0;
2633 n < vertex_to_cell[cell->vertex_index(v)].size();
2635 cell_connectivity.
add(cell->active_cell_index(),
2636 vertex_to_cell[cell->vertex_index(v)][n]);
2641 template <
int dim,
int spacedim>
2645 const unsigned int level,
2648 std::vector<std::vector<unsigned int>> vertex_to_cell(
2649 triangulation.n_vertices());
2651 triangulation.begin(level);
2652 cell != triangulation.end(level);
2655 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
2656 vertex_to_cell[cell->vertex_index(v)].push_back(cell->index());
2659 cell_connectivity.
reinit(triangulation.n_cells(level),
2660 triangulation.n_cells(level));
2662 triangulation.begin(level);
2663 cell != triangulation.end(level);
2666 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
2667 for (
unsigned int n = 0;
2668 n < vertex_to_cell[cell->vertex_index(v)].size();
2670 cell_connectivity.
add(cell->index(),
2671 vertex_to_cell[cell->vertex_index(v)][n]);
2677 template <
int dim,
int spacedim>
2684 &triangulation) ==
nullptr),
2685 ExcMessage(
"Objects of type parallel::distributed::Triangulation " 2686 "are already partitioned implicitly and can not be " 2687 "partitioned again explicitly."));
2689 std::vector<unsigned int> cell_weights;
2692 if (!triangulation.signals.cell_weight.empty())
2694 cell_weights.resize(triangulation.n_active_cells(), 0U);
2699 for (
const auto &cell : triangulation.active_cell_iterators())
2700 if (cell->is_locally_owned())
2701 cell_weights[cell->active_cell_index()] =
2702 triangulation.signals.cell_weight(
2711 if (
const auto shared_tria =
2715 shared_tria->get_communicator(),
2728 template <
int dim,
int spacedim>
2731 const std::vector<unsigned int> &cell_weights,
2736 &triangulation) ==
nullptr),
2737 ExcMessage(
"Objects of type parallel::distributed::Triangulation " 2738 "are already partitioned implicitly and can not be " 2739 "partitioned again explicitly."));
2743 if (n_partitions == 1)
2745 for (
const auto &cell : triangulation.active_cell_iterators())
2746 cell->set_subdomain_id(0);
2760 sp_cell_connectivity.
copy_from(cell_connectivity);
2763 sp_cell_connectivity,
2770 template <
int dim,
int spacedim>
2778 &triangulation) ==
nullptr),
2779 ExcMessage(
"Objects of type parallel::distributed::Triangulation " 2780 "are already partitioned implicitly and can not be " 2781 "partitioned again explicitly."));
2783 std::vector<unsigned int> cell_weights;
2786 if (!triangulation.signals.cell_weight.empty())
2788 cell_weights.resize(triangulation.n_active_cells(), 0U);
2793 for (
const auto &cell : triangulation.active_cell_iterators())
2794 if (cell->is_locally_owned())
2795 cell_weights[cell->active_cell_index()] =
2796 triangulation.signals.cell_weight(
2805 if (
const auto shared_tria =
2809 shared_tria->get_communicator(),
2816 cell_connection_graph,
2823 template <
int dim,
int spacedim>
2826 const std::vector<unsigned int> &cell_weights,
2832 &triangulation) ==
nullptr),
2833 ExcMessage(
"Objects of type parallel::distributed::Triangulation " 2834 "are already partitioned implicitly and can not be " 2835 "partitioned again explicitly."));
2837 Assert(cell_connection_graph.
n_rows() == triangulation.n_active_cells(),
2838 ExcMessage(
"Connectivity graph has wrong size"));
2839 Assert(cell_connection_graph.
n_cols() == triangulation.n_active_cells(),
2840 ExcMessage(
"Connectivity graph has wrong size"));
2843 triangulation.signals.pre_partition();
2846 if (n_partitions == 1)
2848 for (
const auto &cell : triangulation.active_cell_iterators())
2849 cell->set_subdomain_id(0);
2857 std::vector<unsigned int> partition_indices(triangulation.n_active_cells());
2865 for (
const auto &cell : triangulation.active_cell_iterators())
2866 cell->set_subdomain_id(partition_indices[cell->active_cell_index()]);
2877 set_subdomain_id_in_zorder_recursively(IT cell,
2878 unsigned int & current_proc_idx,
2879 unsigned int & current_cell_idx,
2880 const unsigned int n_active_cells,
2881 const unsigned int n_partitions)
2885 while (current_cell_idx >=
2886 std::floor(static_cast<uint_least64_t>(n_active_cells) *
2887 (current_proc_idx + 1) / n_partitions))
2889 cell->set_subdomain_id(current_proc_idx);
2894 for (
unsigned int n = 0; n < cell->n_children(); ++n)
2895 set_subdomain_id_in_zorder_recursively(cell->child(n),
2904 template <
int dim,
int spacedim>
2910 &triangulation) ==
nullptr),
2911 ExcMessage(
"Objects of type parallel::distributed::Triangulation " 2912 "are already partitioned implicitly and can not be " 2913 "partitioned again explicitly."));
2917 triangulation.signals.pre_partition();
2920 if (n_partitions == 1)
2922 for (
const auto &cell : triangulation.active_cell_iterators())
2923 cell->set_subdomain_id(0);
2929 std::vector<types::global_dof_index> coarse_cell_to_p4est_tree_permutation;
2930 std::vector<types::global_dof_index> p4est_tree_to_coarse_cell_permutation;
2936 coarse_cell_to_p4est_tree_permutation.resize(triangulation.n_cells(0));
2938 coarse_cell_to_p4est_tree_permutation);
2940 p4est_tree_to_coarse_cell_permutation =
2943 unsigned int current_proc_idx = 0;
2944 unsigned int current_cell_idx = 0;
2945 const unsigned int n_active_cells = triangulation.n_active_cells();
2949 for (
unsigned int idx = 0; idx < triangulation.n_cells(0); ++idx)
2951 const unsigned int coarse_cell_idx =
2952 p4est_tree_to_coarse_cell_permutation[idx];
2954 &triangulation, 0, coarse_cell_idx);
2956 set_subdomain_id_in_zorder_recursively(coarse_cell,
2972 cell = triangulation.begin(),
2973 endc = triangulation.end();
2974 for (; cell != endc; ++cell)
2978 bool all_children_active =
true;
2979 std::map<unsigned int, unsigned int> map_cpu_n_cells;
2980 for (
unsigned int n = 0; n < cell->n_children(); ++n)
2981 if (!cell->child(n)->active())
2983 all_children_active =
false;
2987 ++map_cpu_n_cells[cell->child(n)->subdomain_id()];
2989 if (!all_children_active)
2992 unsigned int new_owner = cell->child(0)->subdomain_id();
2993 for (std::map<unsigned int, unsigned int>::iterator it =
2994 map_cpu_n_cells.begin();
2995 it != map_cpu_n_cells.end();
2997 if (it->second > map_cpu_n_cells[new_owner])
2998 new_owner = it->first;
3000 for (
unsigned int n = 0; n < cell->n_children(); ++n)
3001 cell->child(n)->set_subdomain_id(new_owner);
3007 template <
int dim,
int spacedim>
3011 unsigned int n_levels = triangulation.n_levels();
3012 for (
int lvl = n_levels - 1; lvl >= 0; --lvl)
3015 cell = triangulation.begin(lvl),
3016 endc = triangulation.end(lvl);
3017 for (; cell != endc; ++cell)
3019 if (!cell->has_children())
3020 cell->set_level_subdomain_id(cell->subdomain_id());
3023 Assert(cell->child(0)->level_subdomain_id() !=
3026 cell->set_level_subdomain_id(
3027 cell->child(0)->level_subdomain_id());
3034 template <
int dim,
int spacedim>
3037 std::vector<types::subdomain_id> & subdomain)
3039 Assert(subdomain.size() == triangulation.n_active_cells(),
3041 triangulation.n_active_cells()));
3043 triangulation.begin_active();
3044 cell != triangulation.end();
3046 subdomain[cell->active_cell_index()] = cell->subdomain_id();
3051 template <
int dim,
int spacedim>
3057 unsigned int count = 0;
3059 triangulation.begin_active();
3060 cell != triangulation.end();
3062 if (cell->subdomain_id() == subdomain)
3070 template <
int dim,
int spacedim>
3075 std::vector<bool> locally_owned_vertices =
3076 triangulation.get_used_vertices();
3085 for (
const auto &cell : triangulation.active_cell_iterators())
3086 if (cell->is_artificial() ||
3087 (cell->is_ghost() &&
3088 (cell->subdomain_id() < tr->locally_owned_subdomain())))
3089 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
3091 locally_owned_vertices[cell->vertex_index(v)] =
false;
3093 return locally_owned_vertices;
3100 template <
int dim,
int spacedim>
3109 return (vertices[1] - vertices[0]).norm();
3111 return std::max((vertices[3] - vertices[0]).norm(),
3112 (vertices[2] - vertices[1]).norm());
3114 return std::max(std::max((vertices[7] - vertices[0]).norm(),
3115 (vertices[6] - vertices[1]).norm()),
3116 std::max((vertices[2] - vertices[5]).norm(),
3117 (vertices[3] - vertices[4]).norm()));
3126 template <
int dim,
int spacedim>
3131 double min_diameter = std::numeric_limits<double>::max();
3132 for (
const auto &cell : triangulation.active_cell_iterators())
3133 if (!cell->is_artificial())
3135 std::min(min_diameter, diameter<dim, spacedim>(cell, mapping));
3137 double global_min_diameter = 0;
3139 #ifdef DEAL_II_WITH_MPI 3143 global_min_diameter =
3147 global_min_diameter = min_diameter;
3149 return global_min_diameter;
3154 template <
int dim,
int spacedim>
3159 double max_diameter = 0.;
3160 for (
const auto &cell : triangulation.active_cell_iterators())
3161 if (!cell->is_artificial())
3162 max_diameter = std::max(max_diameter,
diameter(cell, mapping));
3164 double global_max_diameter = 0;
3166 #ifdef DEAL_II_WITH_MPI 3170 global_max_diameter =
3174 global_max_diameter = max_diameter;
3176 return global_max_diameter;
3183 namespace FixUpDistortedChildCells
3206 template <
typename Iterator,
int spacedim>
3208 objective_function(
const Iterator &
object,
3211 const unsigned int structdim =
3212 Iterator::AccessorType::structure_dimension;
3213 Assert(spacedim == Iterator::AccessorType::dimension,
3219 Assert(object->refinement_case() ==
3227 Tensor<spacedim - structdim, spacedim>
3230 for (
unsigned int i = 0; i < GeometryInfo<structdim>::vertices_per_cell;
3232 parent_vertices[i] = object->vertex(i);
3235 parent_vertices, parent_alternating_forms);
3237 const Tensor<spacedim - structdim, spacedim>
3238 average_parent_alternating_form =
3239 std::accumulate(parent_alternating_forms,
3240 parent_alternating_forms +
3254 Tensor<spacedim - structdim, spacedim> child_alternating_forms
3258 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3259 for (
unsigned int i = 0;
3260 i < GeometryInfo<structdim>::vertices_per_cell;
3262 child_vertices[c][i] = object->child(c)->vertex(i);
3270 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3272 1] = object_mid_point;
3274 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3276 child_vertices[c], child_alternating_forms[c]);
3288 double objective = 0;
3289 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3290 for (
unsigned int i = 0;
3291 i < GeometryInfo<structdim>::vertices_per_cell;
3294 (child_alternating_forms[c][i] -
3295 average_parent_alternating_form / std::pow(2., 1. * structdim))
3307 template <
typename Iterator>
3309 get_face_midpoint(
const Iterator &
object,
3310 const unsigned int f,
3311 std::integral_constant<int, 1>)
3313 return object->vertex(f);
3323 template <
typename Iterator>
3325 get_face_midpoint(
const Iterator &
object,
3326 const unsigned int f,
3327 std::integral_constant<int, 2>)
3329 return object->line(f)->center();
3339 template <
typename Iterator>
3341 get_face_midpoint(
const Iterator &
object,
3342 const unsigned int f,
3343 std::integral_constant<int, 3>)
3345 return object->face(f)->center();
3372 template <
typename Iterator>
3374 minimal_diameter(
const Iterator &
object)
3376 const unsigned int structdim =
3377 Iterator::AccessorType::structure_dimension;
3379 double diameter =
object->diameter();
3380 for (
unsigned int f = 0; f < GeometryInfo<structdim>::faces_per_cell;
3382 for (
unsigned int e = f + 1;
3383 e < GeometryInfo<structdim>::faces_per_cell;
3387 get_face_midpoint(
object,
3389 std::integral_constant<int, structdim>())
3390 .distance(get_face_midpoint(
3391 object, e, std::integral_constant<int, structdim>())));
3402 template <
typename Iterator>
3404 fix_up_object(
const Iterator &
object)
3406 const unsigned int structdim =
3407 Iterator::AccessorType::structure_dimension;
3408 const unsigned int spacedim = Iterator::AccessorType::space_dimension;
3415 Assert(object->refinement_case() ==
3425 unsigned int iteration = 0;
3426 const double diameter = minimal_diameter(
object);
3429 double current_value = objective_function(
object, object_mid_point);
3430 double initial_delta = 0;
3437 const double step_length =
diameter / 4 / (iteration + 1);
3442 for (
unsigned int d = 0;
d < spacedim; ++
d)
3444 const double eps = step_length / 10;
3450 (objective_function(
3458 if (gradient.
norm() == 0)
3467 std::min(2 * current_value / (gradient * gradient),
3468 step_length / gradient.norm()) *
3473 const double previous_value = current_value;
3474 current_value = objective_function(
object, object_mid_point);
3477 initial_delta = (previous_value - current_value);
3480 if ((iteration >= 1) &&
3481 ((previous_value - current_value < 0) ||
3482 (std::fabs(previous_value - current_value) <
3483 0.001 * initial_delta)))
3488 while (iteration < 20);
3504 double old_min_product, new_min_product;
3508 for (
unsigned int i = 0; i < GeometryInfo<structdim>::vertices_per_cell;
3510 parent_vertices[i] = object->vertex(i);
3512 Tensor<spacedim - structdim, spacedim>
3515 parent_vertices, parent_alternating_forms);
3521 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3522 for (
unsigned int i = 0;
3523 i < GeometryInfo<structdim>::vertices_per_cell;
3525 child_vertices[c][i] = object->child(c)->vertex(i);
3527 Tensor<spacedim - structdim, spacedim> child_alternating_forms
3531 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3533 child_vertices[c], child_alternating_forms[c]);
3536 child_alternating_forms[0][0] * parent_alternating_forms[0];
3537 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3538 for (
unsigned int i = 0;
3539 i < GeometryInfo<structdim>::vertices_per_cell;
3541 for (
unsigned int j = 0;
3542 j < GeometryInfo<structdim>::vertices_per_cell;
3544 old_min_product = std::min<double>(old_min_product,
3545 child_alternating_forms[c][i] *
3546 parent_alternating_forms[j]);
3554 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3556 1] = object_mid_point;
3558 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3560 child_vertices[c], child_alternating_forms[c]);
3563 child_alternating_forms[0][0] * parent_alternating_forms[0];
3564 for (
unsigned int c = 0; c <
object->n_children(); ++c)
3565 for (
unsigned int i = 0;
3566 i < GeometryInfo<structdim>::vertices_per_cell;
3568 for (
unsigned int j = 0;
3569 j < GeometryInfo<structdim>::vertices_per_cell;
3571 new_min_product = std::min<double>(new_min_product,
3572 child_alternating_forms[c][i] *
3573 parent_alternating_forms[j]);
3581 if (new_min_product >= old_min_product)
3582 object->child(0)->vertex(
3589 return (std::max(new_min_product, old_min_product) > 0);
3595 fix_up_faces(const ::Triangulation<1, 1>::cell_iterator &,
3596 std::integral_constant<int, 1>,
3597 std::integral_constant<int, 1>)
3605 template <
int dim,
int spacedim>
3608 const typename ::Triangulation<dim, spacedim>::cell_iterator
3610 std::integral_constant<int, dim>,
3611 std::integral_constant<int, spacedim>)
3621 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
3624 Assert(cell->face(f)->refinement_case() ==
3628 bool subface_is_more_refined =
false;
3629 for (
unsigned int g = 0;
3630 g < GeometryInfo<dim>::max_children_per_face;
3632 if (cell->face(f)->child(g)->has_children())
3634 subface_is_more_refined =
true;
3638 if (subface_is_more_refined ==
true)
3642 fix_up_object(cell->face(f));
3649 template <
int dim,
int spacedim>
3659 for (
typename std::list<
3670 "This function is only valid for a list of cells that " 3671 "have children (i.e., no cell in the list may be active)."));
3673 internal::FixUpDistortedChildCells ::fix_up_faces(
3675 std::integral_constant<int, dim>(),
3676 std::integral_constant<int, spacedim>());
3679 if (!internal::FixUpDistortedChildCells::fix_up_object(cell))
3683 return unfixable_subset;
3688 template <
int dim,
int spacedim>
3691 const bool reset_boundary_ids)
3694 std::vector<types::manifold_id> dst_manifold_ids(src_boundary_ids.size());
3695 auto m_it = dst_manifold_ids.begin();
3696 for (
const auto b : src_boundary_ids)
3701 const std::vector<types::boundary_id> reset_boundary_id =
3702 reset_boundary_ids ?
3703 std::vector<types::boundary_id>(src_boundary_ids.size(), 0) :
3713 template <
int dim,
int spacedim>
3716 const std::vector<types::boundary_id> &src_boundary_ids,
3717 const std::vector<types::manifold_id> &dst_manifold_ids,
3719 const std::vector<types::boundary_id> &reset_boundary_ids_)
3722 const auto reset_boundary_ids =
3723 reset_boundary_ids_.size() ? reset_boundary_ids_ : src_boundary_ids;
3735 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
3736 if (cell->face(f)->at_boundary())
3737 for (
unsigned int e = 0; e < GeometryInfo<dim>::lines_per_face; ++e)
3739 const auto bid = cell->face(f)->line(e)->boundary_id();
3740 const unsigned int ind = std::find(src_boundary_ids.begin(),
3741 src_boundary_ids.end(),
3743 src_boundary_ids.begin();
3744 if (ind < src_boundary_ids.size())
3745 cell->face(f)->line(e)->set_manifold_id(
3746 dst_manifold_ids[ind]);
3754 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
3755 if (cell->face(f)->at_boundary())
3757 const auto bid = cell->face(f)->boundary_id();
3758 const unsigned int ind =
3759 std::find(src_boundary_ids.begin(), src_boundary_ids.end(), bid) -
3760 src_boundary_ids.begin();
3762 if (ind < src_boundary_ids.size())
3765 cell->face(f)->set_manifold_id(dst_manifold_ids[ind]);
3767 cell->face(f)->set_boundary_id(reset_boundary_ids[ind]);
3771 for (
unsigned int e = 0; e < GeometryInfo<dim>::lines_per_face;
3774 const auto bid = cell->face(f)->line(e)->boundary_id();
3775 const unsigned int ind = std::find(src_boundary_ids.begin(),
3776 src_boundary_ids.end(),
3778 src_boundary_ids.begin();
3779 if (ind < src_boundary_ids.size())
3780 cell->face(f)->line(e)->set_boundary_id(
3781 reset_boundary_ids[ind]);
3787 template <
int dim,
int spacedim>
3790 const bool compute_face_ids)
3796 for (; cell != endc; ++cell)
3798 cell->set_manifold_id(cell->material_id());
3799 if (compute_face_ids ==
true)
3801 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
3803 if (cell->at_boundary(f) ==
false)
3804 cell->face(f)->set_manifold_id(
3805 std::min(cell->material_id(),
3806 cell->neighbor(f)->material_id()));
3808 cell->face(f)->set_manifold_id(cell->material_id());
3815 template <
int dim,
int spacedim>
3820 const std::set<types::manifold_id> &)> &disambiguation_function,
3821 bool overwrite_only_flat_manifold_ids)
3826 const unsigned int n_subobjects =
3830 std::vector<std::set<types::manifold_id>> manifold_ids(n_subobjects + 1);
3831 std::vector<unsigned int> backup;
3835 unsigned next_index = 1;
3839 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3841 if (cell->line(l)->user_index() == 0)
3844 manifold_ids[next_index].insert(cell->manifold_id());
3845 cell->line(l)->set_user_index(next_index++);
3848 manifold_ids[cell->line(l)->user_index()].insert(
3849 cell->manifold_id());
3852 for (
unsigned int l = 0; l < GeometryInfo<dim>::quads_per_cell; ++l)
3854 if (cell->quad(l)->user_index() == 0)
3857 manifold_ids[next_index].insert(cell->manifold_id());
3858 cell->quad(l)->set_user_index(next_index++);
3861 manifold_ids[cell->quad(l)->user_index()].insert(
3862 cell->manifold_id());
3868 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++l)
3870 const auto id = cell->line(l)->user_index();
3874 if (cell->line(l)->manifold_id() ==
3876 overwrite_only_flat_manifold_ids ==
false)
3877 cell->line(l)->set_manifold_id(
3878 disambiguation_function(manifold_ids[
id]));
3879 cell->line(l)->set_user_index(0);
3883 for (
unsigned int l = 0; l < GeometryInfo<dim>::quads_per_cell; ++l)
3885 const auto id = cell->quad(l)->user_index();
3889 if (cell->quad(l)->manifold_id() ==
3891 overwrite_only_flat_manifold_ids ==
false)
3892 cell->quad(l)->set_manifold_id(
3893 disambiguation_function(manifold_ids[
id]));
3894 cell->quad(l)->set_user_index(0);
3903 template <
int dim,
int spacedim>
3904 std::pair<unsigned int, double>
3908 double max_ratio = 1;
3909 unsigned int index = 0;
3911 for (
unsigned int i = 0; i < dim; ++i)
3912 for (
unsigned int j = i + 1; j < dim; ++j)
3914 unsigned int ax = i % dim;
3915 unsigned int next_ax = j % dim;
3918 cell->extent_in_direction(ax) / cell->extent_in_direction(next_ax);
3920 if (ratio > max_ratio)
3925 else if (1.0 / ratio > max_ratio)
3927 max_ratio = 1.0 / ratio;
3931 return std::make_pair(index, max_ratio);
3935 template <
int dim,
int spacedim>
3938 const bool isotropic,
3939 const unsigned int max_iterations)
3941 unsigned int iter = 0;
3942 bool continue_refinement =
true;
3948 while (continue_refinement && (iter < max_iterations))
3952 continue_refinement =
false;
3955 for (
unsigned int j = 0; j < GeometryInfo<dim>::faces_per_cell; j++)
3956 if (cell->at_boundary(j) ==
false &&
3957 cell->neighbor(j)->has_children())
3961 cell->set_refine_flag();
3962 continue_refinement =
true;
3965 continue_refinement |= cell->flag_for_face_refinement(j);
3972 template <
int dim,
int spacedim>
3975 const double max_ratio,
3976 const unsigned int max_iterations)
3978 unsigned int iter = 0;
3979 bool continue_refinement =
true;
3985 while (continue_refinement && (iter < max_iterations))
3988 continue_refinement =
false;
3991 std::pair<unsigned int, double> info =
3992 GridTools::get_longest_direction<dim, spacedim>(cell);
3993 if (info.second > max_ratio)
3995 cell->set_refine_flag(
3997 continue_refinement =
true;
4005 template <
int dim,
int spacedim>
4008 const double limit_angle_fraction)
4016 "have hanging nodes."));
4019 bool has_cells_with_more_than_dim_faces_on_boundary =
true;
4020 bool has_cells_with_dim_faces_on_boundary =
false;
4022 unsigned int refinement_cycles = 0;
4024 while (has_cells_with_more_than_dim_faces_on_boundary)
4026 has_cells_with_more_than_dim_faces_on_boundary =
false;
4030 unsigned int boundary_face_counter = 0;
4031 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
4032 if (cell->face(f)->at_boundary())
4033 boundary_face_counter++;
4034 if (boundary_face_counter > dim)
4036 has_cells_with_more_than_dim_faces_on_boundary =
true;
4039 else if (boundary_face_counter == dim)
4040 has_cells_with_dim_faces_on_boundary =
true;
4042 if (has_cells_with_more_than_dim_faces_on_boundary)
4045 refinement_cycles++;
4049 if (has_cells_with_dim_faces_on_boundary)
4052 refinement_cycles++;
4056 while (refinement_cycles > 0)
4059 cell->set_coarsen_flag();
4061 refinement_cycles--;
4067 std::vector<Point<spacedim>> vertices = tria.
get_vertices();
4069 std::vector<bool> faces_to_remove(tria.
n_raw_faces(),
false);
4071 std::vector<CellData<dim>> cells_to_add;
4075 const unsigned int v0 = 0, v1 = 1, v2 = (dim > 1 ? 2 : 0),
4076 v3 = (dim > 1 ? 3 : 0);
4080 double angle_fraction = 0;
4086 p0[spacedim > 1 ? 1 : 0] = 1;
4090 if (cell->face(v0)->at_boundary() && cell->face(v3)->at_boundary())
4092 p0 = cell->vertex(v0) - cell->vertex(v2);
4093 p1 = cell->vertex(v3) - cell->vertex(v2);
4094 vertex_at_corner = v2;
4096 else if (cell->face(v3)->at_boundary() &&
4097 cell->face(v1)->at_boundary())
4099 p0 = cell->vertex(v2) - cell->vertex(v3);
4100 p1 = cell->vertex(v1) - cell->vertex(v3);
4101 vertex_at_corner = v3;
4103 else if (cell->face(1)->at_boundary() &&
4104 cell->face(2)->at_boundary())
4106 p0 = cell->vertex(v0) - cell->vertex(v1);
4107 p1 = cell->vertex(v3) - cell->vertex(v1);
4108 vertex_at_corner = v1;
4110 else if (cell->face(2)->at_boundary() &&
4111 cell->face(0)->at_boundary())
4113 p0 = cell->vertex(v2) - cell->vertex(v0);
4114 p1 = cell->vertex(v1) - cell->vertex(v0);
4115 vertex_at_corner = v0;
4119 angle_fraction = std::acos(p0 * p1) /
numbers::PI;
4126 if (angle_fraction > limit_angle_fraction)
4128 auto flags_removal = [&](
unsigned int f1,
4131 unsigned int n2) ->
void {
4132 cells_to_remove[cell->active_cell_index()] =
true;
4133 cells_to_remove[cell->neighbor(n1)->active_cell_index()] =
true;
4134 cells_to_remove[cell->neighbor(n2)->active_cell_index()] =
true;
4136 faces_to_remove[cell->face(f1)->index()] =
true;
4137 faces_to_remove[cell->face(f2)->index()] =
true;
4139 faces_to_remove[cell->neighbor(n1)->face(f1)->index()] =
true;
4140 faces_to_remove[cell->neighbor(n2)->face(f2)->index()] =
true;
4143 auto cell_creation = [&](
const unsigned int vv0,
4144 const unsigned int vv1,
4145 const unsigned int f0,
4146 const unsigned int f1,
4148 const unsigned int n0,
4149 const unsigned int v0n0,
4150 const unsigned int v1n0,
4152 const unsigned int n1,
4153 const unsigned int v0n1,
4154 const unsigned int v1n1) {
4158 c1.
vertices[v0] = cell->vertex_index(vv0);
4159 c1.
vertices[v1] = cell->vertex_index(vv1);
4160 c1.
vertices[v2] = cell->neighbor(n0)->vertex_index(v0n0);
4161 c1.
vertices[v3] = cell->neighbor(n0)->vertex_index(v1n0);
4166 c2.
vertices[v0] = cell->vertex_index(vv0);
4167 c2.
vertices[v1] = cell->neighbor(n1)->vertex_index(v0n1);
4168 c2.
vertices[v2] = cell->vertex_index(vv1);
4169 c2.
vertices[v3] = cell->neighbor(n1)->vertex_index(v1n1);
4174 l1.
vertices[0] = cell->vertex_index(vv0);
4175 l1.
vertices[1] = cell->neighbor(n0)->vertex_index(v0n0);
4181 l2.
vertices[0] = cell->vertex_index(vv0);
4182 l2.
vertices[1] = cell->neighbor(n1)->vertex_index(v0n1);
4188 cells_to_add.push_back(c1);
4189 cells_to_add.push_back(c2);
4194 switch (vertex_at_corner)
4197 flags_removal(0, 2, 3, 1);
4198 cell_creation(0, 3, 0, 2, 3, 2, 3, 1, 1, 3);
4201 flags_removal(1, 2, 3, 0);
4202 cell_creation(1, 2, 2, 1, 0, 0, 2, 3, 3, 2);
4205 flags_removal(3, 0, 1, 2);
4206 cell_creation(2, 1, 3, 0, 1, 3, 1, 2, 0, 1);
4209 flags_removal(3, 1, 0, 2);
4210 cell_creation(3, 0, 1, 3, 2, 1, 0, 0, 2, 0);
4223 if (cells_to_add.size() == 0)
4225 while (refinement_cycles > 0)
4228 cell->set_coarsen_flag();
4230 refinement_cycles--;
4238 if (cells_to_remove[cell->active_cell_index()] ==
false)
4241 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
4243 c.
vertices[v] = cell->vertex_index(v);
4246 cells_to_add.push_back(c);
4254 for (; face != endf; ++face)
4255 if ((face->at_boundary() ||
4257 faces_to_remove[face->index()] ==
false)
4259 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_face; ++l)
4264 for (
unsigned int v = 0;
4265 v < GeometryInfo<1>::vertices_per_cell;
4267 line.
vertices[v] = face->vertex_index(v);
4273 for (
unsigned int v = 0;
4274 v < GeometryInfo<1>::vertices_per_cell;
4276 line.
vertices[v] = face->line(l)->vertex_index(v);
4285 for (
unsigned int v = 0; v < GeometryInfo<2>::vertices_per_cell;
4287 quad.
vertices[v] = face->vertex_index(v);
4295 subcelldata_to_add);
4300 std::map<types::manifold_id, std::unique_ptr<Manifold<dim, spacedim>>>
4303 for (
const auto manifold_id : manifold_ids)
4305 manifolds[manifold_id] = tria.
get_manifold(manifold_id).clone();
4312 for (
const auto manifold_id : manifold_ids)
4314 tria.
set_manifold(manifold_id, *manifolds[manifold_id]);
4319 template <
int dim,
int spacedim>
4322 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
4323 std::vector<std::vector<Point<dim>>>,
4324 std::vector<std::vector<unsigned int>>>
4336 auto &cells = std::get<0>(cqmp);
4337 auto &qpoints = std::get<1>(cqmp);
4338 auto &maps = std::get<2>(cqmp);
4339 auto &missing_points = std::get<3>(cqmp);
4343 ExcPointNotFound<spacedim>(points[missing_points[0]]));
4345 (void)missing_points;
4347 return std::make_tuple(std::move(cells),
4354 template <
int dim,
int spacedim>
4357 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
4358 std::vector<std::vector<Point<dim>>>,
4359 std::vector<std::vector<unsigned int>>,
4360 std::vector<unsigned int>>
4371 const unsigned int np = points.size();
4373 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>
4375 std::vector<std::vector<Point<dim>>> qpoints_out;
4376 std::vector<std::vector<unsigned int>> maps_out;
4377 std::vector<unsigned int> missing_points_out;
4381 return std::make_tuple(std::move(cells_out),
4382 std::move(qpoints_out),
4383 std::move(maps_out),
4384 std::move(missing_points_out));
4390 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
4395 unsigned int points_checked = 0;
4407 catch (
const GridTools::ExcPointNotFound<dim> &)
4409 missing_points_out.emplace_back(0);
4418 std::pair<BoundingBox<spacedim>,
4423 int cell_candidate_idx = -1;
4427 bool use_try =
false;
4429 while (!found && points_checked < np)
4432 b_tree.query(boost::geometry::index::intersects(points[points_checked]),
4433 std::back_inserter(box_cell));
4436 cell_candidate_idx = -1;
4437 for (
unsigned int i = 0; i < box_cell.size(); ++i)
4440 if (!box_cell[i].second->is_artificial())
4441 cell_candidate_idx = i;
4445 if (cell_candidate_idx != -1 &&
4446 (!box_cell[i].second->is_locally_owned() ||
4447 box_cell[i].second->at_boundary()))
4451 if (cell_candidate_idx != -1)
4456 if (cell_candidate_idx != -1)
4464 points[points_checked],
4465 box_cell[cell_candidate_idx].second);
4468 catch (
const GridTools::ExcPointNotFound<dim> &)
4470 missing_points_out.emplace_back(points_checked);
4477 points[points_checked],
4478 box_cell[cell_candidate_idx].second);
4487 cache, points[points_checked]);
4492 cell_candidate_idx = box_cell.size();
4494 std::make_pair(my_pair.first->bounding_box(), my_pair.first));
4496 catch (
const GridTools::ExcPointNotFound<dim> &)
4498 missing_points_out.emplace_back(points_checked);
4509 cells_out.emplace_back(my_pair.first);
4510 qpoints_out.emplace_back(1, my_pair.second);
4511 maps_out.emplace_back(1, points_checked - 1);
4515 if (np == qpoints_out.size())
4516 return std::make_tuple(std::move(cells_out),
4517 std::move(qpoints_out),
4518 std::move(maps_out),
4519 std::move(missing_points_out));
4522 for (
unsigned int p = points_checked; p < np; ++p)
4525 if (cell_candidate_idx != -1)
4526 if (!box_cell[cell_candidate_idx].first.point_inside(points[p]))
4528 cell_candidate_idx = -1;
4531 if (cell_candidate_idx == -1)
4535 b_tree.query(boost::geometry::index::intersects(points[p]),
4536 std::back_inserter(box_cell));
4539 cell_candidate_idx = -1;
4540 for (
unsigned int i = 0; i < box_cell.size(); ++i)
4543 if (!box_cell[i].second->is_artificial())
4544 cell_candidate_idx = i;
4548 if (cell_candidate_idx != -1 &&
4549 (!box_cell[i].second->is_locally_owned() ||
4550 box_cell[i].second->at_boundary()))
4554 if (cell_candidate_idx != -1)
4559 if (cell_candidate_idx == -1)
4570 cell_candidate_idx = box_cell.size();
4572 std::make_pair(my_pair.first->bounding_box(), my_pair.first));
4574 catch (
const GridTools::ExcPointNotFound<dim> &)
4576 missing_points_out.emplace_back(p);
4588 cache, points[p], box_cell[cell_candidate_idx].second);
4590 catch (
const GridTools::ExcPointNotFound<dim> &)
4592 missing_points_out.push_back(p);
4599 cache, points[p], box_cell[cell_candidate_idx].second);
4604 if (my_pair.first != box_cell[cell_candidate_idx].second)
4606 for (
unsigned int i = 0; i < box_cell.size(); ++i)
4608 if (my_pair.first == box_cell[i].second)
4610 cell_candidate_idx = i;
4615 if (my_pair.first != box_cell[cell_candidate_idx].second)
4619 cell_candidate_idx = box_cell.size();
4621 std::make_pair(my_pair.first->bounding_box(),
4630 if (my_pair.first == cells_out.back())
4633 qpoints_out.back().emplace_back(my_pair.second);
4634 maps_out.back().emplace_back(p);
4639 typename std::vector<typename Triangulation<dim, spacedim>::
4640 active_cell_iterator>::iterator cells_it =
4641 std::find(cells_out.begin(), cells_out.end() - 1, my_pair.first);
4643 if (cells_it == cells_out.end() - 1)
4646 cells_out.emplace_back(my_pair.first);
4647 qpoints_out.emplace_back(1, my_pair.second);
4648 maps_out.emplace_back(1, p);
4654 unsigned int current_cell = cells_it - cells_out.begin();
4655 qpoints_out[current_cell].emplace_back(my_pair.second);
4656 maps_out[current_cell].emplace_back(p);
4662 Assert(cells_out.size() == maps_out.size(),
4665 Assert(cells_out.size() == qpoints_out.size(),
4669 unsigned int c = cells_out.size();
4670 unsigned int qps = 0;
4676 for (
unsigned int n = 0; n < c; ++n)
4678 Assert(qpoints_out[n].size() == maps_out[n].size(),
4680 qps += qpoints_out[n].size();
4683 Assert(qps + missing_points_out.size() == np,
4687 return std::make_tuple(std::move(cells_out),
4688 std::move(qpoints_out),
4689 std::move(maps_out),
4690 std::move(missing_points_out));
4698 namespace distributed_cptloc
4701 template <
int dim,
int spacedim>
4710 return k->active_cell_index();
4718 template <
int dim,
int spacedim>
4721 std::pair<std::vector<Point<dim>>, std::vector<unsigned int>>,
4722 cell_hash<dim, spacedim>>
4723 compute_point_locations_unmap(
4728 const unsigned int np = points.size();
4732 std::pair<std::vector<Point<dim>>, std::vector<unsigned int>>,
4733 cell_hash<dim, spacedim>>
4738 return cell_qpoint_map;
4743 auto last_cell = cell_qpoint_map.emplace(
4744 std::make_pair(my_pair.first,
4745 std::make_pair(std::vector<
Point<dim>>{my_pair.second},
4746 std::vector<unsigned int>{0})));
4749 return cell_qpoint_map;
4752 double cell_diameter = my_pair.first->diameter() *
4753 (0.5 + std::numeric_limits<double>::epsilon());
4756 for (
unsigned int p = 1; p < np; ++p)
4760 if (cell_center.
distance(points[p]) < cell_diameter)
4762 cache, points[p], last_cell.first->first);
4767 if (last_cell.first->first == my_pair.first)
4769 last_cell.first->second.first.emplace_back(my_pair.second);
4770 last_cell.first->second.second.emplace_back(p);
4775 last_cell = cell_qpoint_map.emplace(std::make_pair(
4777 std::make_pair(std::vector<
Point<dim>>{my_pair.second},
4778 std::vector<unsigned int>{p})));
4780 if (last_cell.second ==
false)
4783 last_cell.first->second.first.emplace_back(my_pair.second);
4784 last_cell.first->second.second.emplace_back(p);
4789 cell_center = my_pair.first->center();
4791 my_pair.first->diameter() *
4792 (0.5 + std::numeric_limits<double>::epsilon());
4798 unsigned int qps = 0;
4803 for (
const auto &m : cell_qpoint_map)
4805 Assert(m.second.second.size() == m.second.first.size(),
4807 m.second.first.size()));
4808 qps += m.second.second.size();
4812 return cell_qpoint_map;
4825 template <
int dim,
int spacedim>
4827 merge_cptloc_outputs(
4831 std::vector<unsigned int>,
4833 std::vector<unsigned int>>,
4834 cell_hash<dim, spacedim>> &output_unmap,
4838 const std::vector<std::vector<
Point<dim>>> & in_qpoints,
4839 const std::vector<std::vector<unsigned int>> & in_maps,
4841 const unsigned int in_rank)
4844 for (
unsigned int c = 0; c < in_cells.size(); ++c)
4847 auto current_c = output_unmap.emplace(
4848 std::make_pair(in_cells[c],
4849 std::make_tuple(in_qpoints[c],
4852 std::vector<unsigned int>(
4853 in_points[c].size(), in_rank))));
4855 if (current_c.second ==
false)
4859 auto &cell_qpts = std::get<0>(current_c.first->second);
4860 auto &cell_maps = std::get<1>(current_c.first->second);
4861 auto &cell_pts = std::get<2>(current_c.first->second);
4862 auto &cell_ranks = std::get<3>(current_c.first->second);
4863 cell_qpts.insert(cell_qpts.end(),
4864 in_qpoints[c].begin(),
4865 in_qpoints[c].end());
4866 cell_maps.insert(cell_maps.end(),
4869 cell_pts.insert(cell_pts.end(),
4870 in_points[c].begin(),
4871 in_points[c].end());
4872 std::vector<unsigned int> ranks_tmp(in_points[c].size(),
4874 cell_ranks.insert(cell_ranks.end(),
4892 template <
int dim,
int spacedim>
4894 compute_and_classify_points(
4897 const std::vector<unsigned int> & local_points_idx,
4901 std::vector<unsigned int>,
4903 std::vector<unsigned int>>,
4904 cell_hash<dim, spacedim>> &output_unmap,
4905 std::map<
unsigned int,
4906 std::tuple<std::vector<CellId>,
4908 std::vector<std::vector<unsigned int>>,
4911 std::vector<unsigned int> &classified_pts)
4913 auto cpt_loc_pts = compute_point_locations_unmap(cache, local_points);
4917 for (
const auto &cell_tuples : cpt_loc_pts)
4919 auto &cell_loc = cell_tuples.first;
4920 auto &q_loc = std::get<0>(cell_tuples.second);
4921 auto &indices_loc = std::get<1>(cell_tuples.second);
4922 if (cell_loc->is_locally_owned())
4925 std::vector<Point<spacedim>> cell_points(indices_loc.size());
4926 std::vector<unsigned int> cell_points_idx(indices_loc.size());
4927 for (
unsigned int i = 0; i < indices_loc.size(); ++i)
4930 cell_points[i] = local_points[indices_loc[i]];
4935 cell_points_idx[i] = local_points_idx[indices_loc[i]];
4936 classified_pts.emplace_back(
4937 local_points_idx[indices_loc[i]]);
4939 output_unmap.emplace(
4940 std::make_pair(cell_loc,
4941 std::make_tuple(q_loc,
4944 std::vector<unsigned int>(
4946 cell_loc->subdomain_id()))));
4948 else if (cell_loc->is_ghost())
4952 std::vector<Point<spacedim>> cell_points(indices_loc.size());
4953 std::vector<unsigned int> cell_points_idx(indices_loc.size());
4954 for (
unsigned int i = 0; i < indices_loc.size(); ++i)
4956 cell_points[i] = local_points[indices_loc[i]];
4957 cell_points_idx[i] = local_points_idx[indices_loc[i]];
4958 classified_pts.emplace_back(
4959 local_points_idx[indices_loc[i]]);
4965 auto &map_tuple_owner = ghost_loc_pts[cell_loc->subdomain_id()];
4967 std::get<0>(map_tuple_owner).emplace_back(cell_loc->id());
4968 std::get<1>(map_tuple_owner).emplace_back(q_loc);
4969 std::get<2>(map_tuple_owner).emplace_back(cell_points_idx);
4970 std::get<3>(map_tuple_owner).emplace_back(cell_points);
4983 template <
int dim,
int spacedim>
4985 compute_and_merge_from_map(
4987 const std::map<
unsigned int,
4989 std::vector<unsigned int>>> &map_pts,
4993 std::vector<unsigned int>,
4995 std::vector<unsigned int>>,
4996 cell_hash<dim, spacedim>> &output_unmap,
4997 const bool check_owned)
4999 bool no_check = !check_owned;
5003 for (
const auto &rank_and_points : map_pts)
5006 const auto &received_process = rank_and_points.first;
5007 const auto &received_points = rank_and_points.second.first;
5008 const auto &received_map = rank_and_points.second.second;
5015 std::vector<std::vector<Point<dim>>> in_qpoints;
5016 std::vector<std::vector<unsigned int>> in_maps;
5017 std::vector<std::vector<Point<spacedim>>> in_points;
5020 compute_point_locations_unmap(cache,
5021 rank_and_points.second.first);
5022 for (
const auto &map_c_pt_idx : cpt_loc_pts)
5025 const auto &proc_cell = map_c_pt_idx.first;
5026 const auto &proc_qpoints = map_c_pt_idx.second.first;
5027 const auto &proc_maps = map_c_pt_idx.second.second;
5031 if (no_check || proc_cell->is_locally_owned())
5033 in_cell.emplace_back(proc_cell);
5034 in_qpoints.emplace_back(proc_qpoints);
5036 unsigned int loc_size = proc_qpoints.size();
5037 std::vector<unsigned int> cell_maps(loc_size);
5038 std::vector<Point<spacedim>> cell_points(loc_size);
5039 for (
unsigned int pt = 0; pt < loc_size; ++pt)
5041 cell_maps[pt] = received_map[proc_maps[pt]];
5042 cell_points[pt] = received_points[proc_maps[pt]];
5044 in_maps.emplace_back(cell_maps);
5045 in_points.emplace_back(cell_points);
5050 internal::distributed_cptloc::merge_cptloc_outputs(
5064 template <
int dim,
int spacedim>
5067 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
5068 std::vector<std::vector<Point<dim>>>,
5069 std::vector<std::vector<unsigned int>>,
5070 std::vector<std::vector<Point<spacedim>>>,
5071 std::vector<std::vector<unsigned int>>>
5080 #ifndef DEAL_II_WITH_MPI 5083 (void)global_bboxes;
5086 "GridTools::distributed_compute_point_locations() requires MPI."));
5088 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
5089 std::vector<std::vector<Point<dim>>>,
5090 std::vector<std::vector<unsigned int>>,
5091 std::vector<std::vector<Point<spacedim>>>,
5092 std::vector<std::vector<unsigned int>>>
5097 const auto &tria_mpi =
5105 "GridTools::distributed_compute_point_locations() requires a parallel triangulation."));
5106 auto mpi_communicator = tria_mpi->get_communicator();
5109 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
5110 std::vector<std::vector<Point<dim>>>,
5111 std::vector<std::vector<unsigned int>>,
5112 std::vector<std::vector<Point<spacedim>>>,
5113 std::vector<std::vector<unsigned int>>>
5119 std::tuple<std::vector<Point<dim>>,
5120 std::vector<unsigned int>,
5121 std::vector<Point<spacedim>>,
5122 std::vector<unsigned int>>,
5123 internal::distributed_cptloc::cell_hash<dim, spacedim>>
5131 std::tuple<std::vector<std::vector<unsigned int>>,
5132 std::map<unsigned int, unsigned int>,
5133 std::map<unsigned int, std::vector<unsigned int>>>
5139 const auto &guess_loc_idx = std::get<0>(guessed_points)[my_rank];
5140 const unsigned int n_local_guess = guess_loc_idx.size();
5142 std::vector<Point<spacedim>> guess_local_pts(n_local_guess);
5143 for (
unsigned int i = 0; i < n_local_guess; ++i)
5144 guess_local_pts[i] = local_points[guess_loc_idx[i]];
5147 std::map<
unsigned int,
5148 std::tuple<std::vector<CellId>,
5149 std::vector<std::vector<Point<dim>>>,
5150 std::vector<std::vector<unsigned int>>,
5151 std::vector<std::vector<Point<spacedim>>>>>
5155 std::vector<unsigned int> classified_pts;
5159 &internal::distributed_cptloc::compute_and_classify_points<dim, spacedim>,
5169 const auto &other_owned_idx = std::get<1>(guessed_points);
5170 std::map<
unsigned int,
5171 std::pair<std::vector<Point<spacedim>>, std::vector<unsigned int>>>
5174 for (
const auto &indices : other_owned_idx)
5175 if (indices.second != my_rank)
5178 auto ¤t_pts = other_owned_pts[indices.second];
5180 current_pts.first.emplace_back(local_points[indices.first]);
5181 current_pts.second.emplace_back(indices.first);
5185 auto owned_rank_pts =
5192 &internal::distributed_cptloc::compute_and_merge_from_map<dim, spacedim>,
5206 std::map<
unsigned int,
5207 std::pair<std::vector<Point<spacedim>>, std::vector<unsigned int>>>
5212 const std::map<unsigned int, std::vector<unsigned int>> &other_check_idx =
5213 std::get<2>(guessed_points);
5220 std::sort(classified_pts.begin(), classified_pts.end());
5222 for (
const auto &pt_to_guesses : other_check_idx)
5224 const auto &point_idx = pt_to_guesses.first;
5225 const auto &probable_owners_rks = pt_to_guesses.second;
5226 if (!std::binary_search(classified_pts.begin(),
5227 classified_pts.end(),
5231 for (
const unsigned int probable_owners_rk : probable_owners_rks)
5232 if (probable_owners_rk != my_rank)
5235 auto ¤t_pts = other_check_pts[probable_owners_rk];
5237 current_pts.first.emplace_back(local_points[point_idx]);
5239 current_pts.second.emplace_back(point_idx);
5247 owned_pts_tsk.
join();
5250 for (
const auto &rank_vals : cpt_ghost)
5253 const auto &cell_ids = std::get<0>(rank_vals.second);
5254 unsigned int n_cells = cell_ids.size();
5255 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>
5257 for (
unsigned int c = 0; c < n_cells; ++c)
5260 internal::distributed_cptloc::merge_cptloc_outputs(
5263 std::get<1>(rank_vals.second),
5264 std::get<2>(rank_vals.second),
5265 std::get<3>(rank_vals.second),
5271 internal::distributed_cptloc::compute_and_merge_from_map(cache,
5278 unsigned int size_output = temporary_unmap.size();
5279 auto &out_cells = std::get<0>(output_tuple);
5280 auto &out_qpoints = std::get<1>(output_tuple);
5281 auto &out_maps = std::get<2>(output_tuple);
5282 auto &out_points = std::get<3>(output_tuple);
5283 auto &out_ranks = std::get<4>(output_tuple);
5285 out_cells.resize(size_output);
5286 out_qpoints.resize(size_output);
5287 out_maps.resize(size_output);
5288 out_points.resize(size_output);
5289 out_ranks.resize(size_output);
5292 for (
const auto &rank_and_tuple : temporary_unmap)
5294 out_cells[c] = rank_and_tuple.first;
5295 out_qpoints[c] = std::get<0>(rank_and_tuple.second);
5296 out_maps[c] = std::get<1>(rank_and_tuple.second);
5297 out_points[c] = std::get<2>(rank_and_tuple.second);
5298 out_ranks[c] = std::get<3>(rank_and_tuple.second);
5302 return output_tuple;
5307 template <
int dim,
int spacedim>
5308 std::map<unsigned int, Point<spacedim>>
5312 std::map<unsigned int, Point<spacedim>> result;
5315 if (!cell->is_artificial())
5318 for (
unsigned int i = 0; i < vs.size(); ++i)
5319 result[cell->vertex_index(i)] = vs[i];
5326 template <
int spacedim>
5331 auto id_and_v = std::min_element(
5334 [&](
const std::pair<const unsigned int, Point<spacedim>> &p1,
5335 const std::pair<const unsigned int, Point<spacedim>> &p2) ->
bool {
5336 return p1.second.
distance(p) < p2.second.distance(p);
5338 return id_and_v->first;
5342 template <
int dim,
int spacedim>
5343 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
5350 const std::vector<bool> &marked_vertices)
5355 const auto &vertex_to_cell_centers =
5363 vertex_to_cell_centers,
5366 used_vertices_rtree);
5369 template <
int spacedim>
5370 std::vector<std::vector<BoundingBox<spacedim>>>
5371 exchange_local_bounding_boxes(
5373 MPI_Comm mpi_communicator)
5375 #ifndef DEAL_II_WITH_MPI 5377 (void)mpi_communicator;
5380 "GridTools::exchange_local_bounding_boxes() requires MPI."));
5384 unsigned int n_bboxes = local_bboxes.size();
5386 int n_local_data = 2 * spacedim * n_bboxes;
5388 std::vector<double> loc_data_array(n_local_data);
5389 for (
unsigned int i = 0; i < n_bboxes; ++i)
5390 for (
unsigned int d = 0;
d < spacedim; ++
d)
5393 loc_data_array[2 * i * spacedim +
d] =
5394 local_bboxes[i].get_boundary_points().first[
d];
5395 loc_data_array[2 * i * spacedim + spacedim +
d] =
5396 local_bboxes[i].get_boundary_points().second[
d];
5403 std::vector<int> size_all_data(n_procs);
5406 int ierr = MPI_Allgather(&n_local_data,
5409 size_all_data.data(),
5417 std::vector<int> rdispls(n_procs);
5419 for (
unsigned int i = 1; i < n_procs; ++i)
5420 rdispls[i] = rdispls[i - 1] + size_all_data[i - 1];
5424 std::vector<double> data_array(rdispls.back() + size_all_data.back());
5426 ierr = MPI_Allgatherv(loc_data_array.data(),
5430 size_all_data.data(),
5437 std::vector<std::vector<BoundingBox<spacedim>>> global_bboxes(n_procs);
5438 unsigned int begin_idx = 0;
5439 for (
unsigned int i = 0; i < n_procs; ++i)
5442 unsigned int n_bbox_i = size_all_data[i] / (spacedim * 2);
5443 global_bboxes[i].resize(n_bbox_i);
5444 for (
unsigned int bbox = 0; bbox < n_bbox_i; ++bbox)
5447 for (
unsigned int d = 0;
d < spacedim; ++
d)
5449 p1[
d] = data_array[begin_idx + 2 * bbox * spacedim +
d];
5451 data_array[begin_idx + 2 * bbox * spacedim + spacedim +
d];
5454 global_bboxes[i][bbox] = loc_bbox;
5457 begin_idx += size_all_data[i];
5459 return global_bboxes;
5460 #endif // DEAL_II_WITH_MPI 5465 template <
int spacedim>
5466 RTree<std::pair<BoundingBox<spacedim>,
unsigned int>>
5469 MPI_Comm mpi_communicator)
5471 #ifndef DEAL_II_WITH_MPI 5472 (void)mpi_communicator;
5474 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>> boxes_index(
5475 local_description.size());
5477 for (
unsigned int i = 0; i < local_description.size(); ++i)
5478 boxes_index[i] = std::make_pair(local_description[i], 0u);
5479 return pack_rtree(boxes_index);
5482 const std::vector<std::vector<BoundingBox<spacedim>>> global_bboxes =
5486 const unsigned int n_procs =
5490 std::vector<unsigned int> bboxes_position(n_procs);
5492 unsigned int tot_bboxes = 0;
5493 for (
const auto &process_bboxes : global_bboxes)
5494 tot_bboxes += process_bboxes.size();
5497 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>>
5499 flat_global_bboxes.reserve(tot_bboxes);
5500 unsigned int process_index = 0;
5501 for (
const auto &process_bboxes : global_bboxes)
5504 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>>
5505 boxes_and_indices(process_bboxes.size());
5508 for (
unsigned int i = 0; i < process_bboxes.size(); ++i)
5509 boxes_and_indices[i] =
5510 std::make_pair(process_bboxes[i], process_index);
5512 flat_global_bboxes.insert(flat_global_bboxes.end(),
5513 boxes_and_indices.begin(),
5514 boxes_and_indices.end());
5521 return RTree<std::pair<BoundingBox<spacedim>,
unsigned int>>(
5522 flat_global_bboxes.begin(), flat_global_bboxes.end());
5523 #endif // DEAL_II_WITH_MPI 5532 #include "grid_tools.inst" 5534 DEAL_II_NAMESPACE_CLOSE
void map_boundary_to_manifold_ids(const std::vector< types::boundary_id > &src_boundary_ids, const std::vector< types::manifold_id > &dst_manifold_ids, Triangulation< dim, spacedim > &tria, const std::vector< types::boundary_id > &reset_boundary_ids={})
std::vector< CellData< 1 > > boundary_lines
Transformed quadrature weights.
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcScalingFactorNotPositive(double arg1)
unsigned int n_active_cells() const
static void reorder_cells(std::vector< CellData< dim >> &original_cells, const bool use_new_style_ordering=false)
const types::manifold_id flat_manifold_id
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
void copy_boundary_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool reset_boundary_ids=false)
active_face_iterator begin_active_face() const
void create_laplace_matrix(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim > &q, SparseMatrix< double > &matrix, const Function< spacedim > *const a=nullptr, const AffineConstraints< double > &constraints=AffineConstraints< double >())
cell_iterator begin(const unsigned int level=0) const
typename IteratorSelector::line_iterator line_iterator
virtual bool has_hanging_nodes() const
unsigned int n_cells() const
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Task< RT > new_task(const std::function< RT()> &function)
void add(const size_type i, const size_type j)
IteratorRange< active_cell_iterator > active_cell_iterators() const
#define AssertIndexRange(index, range)
virtual std::array< Point< spacedim >, GeometryInfo< dim >::vertices_per_cell > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
active_cell_iterator begin_active(const unsigned int level=0) const
#define AssertThrow(cond, exc)
numbers::NumberTraits< Number >::real_type norm() const
types::boundary_id boundary_id
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)
unsigned int n_levels() const
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
static double distance_to_unit_cell(const Point< dim > &p)
cell_iterator end() const
active_cell_iterator begin_active(const unsigned int level=0) const
virtual void execute_coarsening_and_refinement()
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
bool check_consistency(const unsigned int dim) const
unsigned int subdomain_id
T sum(const T &t, const MPI_Comm &mpi_communicator)
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
#define Assert(cond, exc)
IteratorRange< active_cell_iterator > active_cell_iterators() const
void reinit(const size_type m, const size_type n, const IndexSet &rowset=IndexSet())
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
std::list< typename Triangulation< dim, spacedim >::cell_iterator > distorted_cells
unsigned int n_quads() const
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim - dim, spacedim >(&forms)[vertices_per_cell])
void save_user_indices(std::vector< unsigned int > &v) const
types::material_id material_id
const std::vector< Point< spacedim > > & get_vertices() const
void load_user_indices(const std::vector< unsigned int > &v)
unsigned int n_lines() const
void initialize(const MatrixType &A, const AdditionalData ¶meters=AdditionalData())
void copy_material_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool compute_face_ids=false)
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
std::vector< unsigned int > invert_permutation(const std::vector< unsigned int > &permutation)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access >> &cell)
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
unsigned int size() const
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
types::manifold_id manifold_id
unsigned int n_raw_faces() const
void swap(Vector< Number > &u, Vector< Number > &v)
unsigned int global_dof_index
const types::subdomain_id artificial_subdomain_id
__global__ void set(Number *val, const Number s, const size_type N)
#define AssertThrowMPI(error_code)
static constexpr double PI
double JxW(const unsigned int quadrature_point) const
const std::vector< bool > & get_used_vertices() const
T min(const T &t, const MPI_Comm &mpi_communicator)
std::vector< CellData< 2 > > boundary_quads
numbers::NumberTraits< Number >::real_type square() const
void refine_global(const unsigned int times=1)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
virtual bool preserves_vertex_locations() const =0
void assign_co_dimensional_manifold_indicators(Triangulation< dim, spacedim > &tria, const std::function< types::manifold_id(const std::set< types::manifold_id > &)> &disambiguation_function=[](const std::set< types::manifold_id > &manifold_ids) { if(manifold_ids.size()==1) return *manifold_ids.begin();else return numbers::flat_manifold_id;}, bool overwrite_only_flat_manifold_ids=true)
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcNotImplemented()
Iterator points to a valid object.
static ::ExceptionBase & ExcVertexNotUsed(unsigned int arg1)
face_iterator end_face() const
std::vector< T > all_gather(const MPI_Comm &comm, const T &object_to_send)
unsigned long long int global_vertex_index
IteratorState::IteratorStates state() const
void make_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
std::map< unsigned int, T > some_to_some(const MPI_Comm &comm, const std::map< unsigned int, T > &objects_to_send)
std::vector< types::manifold_id > get_manifold_ids() const
bool vertex_used(const unsigned int index) const
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
T max(const T &t, const MPI_Comm &mpi_communicator)
numbers::NumberTraits< Number >::real_type distance_square(const Point< dim, Number > &p) const
std::vector< types::boundary_id > get_boundary_ids() const
unsigned int vertices[GeometryInfo< structdim >::vertices_per_cell]
static ::ExceptionBase & ExcInternalError()
Triangulation< dim, spacedim > & get_triangulation()