18#include <deal.II/base/mpi.templates.h>
23#ifdef DEAL_II_WITH_CGAL
68#include <boost/random/mersenne_twister.hpp>
69#include <boost/random/uniform_real_distribution.hpp>
79#include <unordered_map>
86 template <
int dim,
int spacedim>
96#if defined(DEAL_II_WITH_P4EST) && defined(DEBUG)
111 std::vector<bool> boundary_vertices(
vertices.size(),
false);
117 for (; cell != endc; ++cell)
118 for (
const unsigned int face : cell->face_indices())
119 if (cell->face(face)->at_boundary())
120 for (
unsigned int i = 0; i < cell->face(face)->n_vertices(); ++i)
121 boundary_vertices[cell->face(face)->vertex_index(i)] =
true;
125 double max_distance_sqr = 0;
126 std::vector<bool>::const_iterator pi = boundary_vertices.begin();
127 const unsigned int N = boundary_vertices.size();
128 for (
unsigned int i = 0; i < N; ++i, ++pi)
130 std::vector<bool>::const_iterator pj = pi + 1;
131 for (
unsigned int j = i + 1; j < N; ++j, ++pj)
132 if ((*pi ==
true) && (*pj ==
true) &&
142 template <
int dim,
int spacedim>
151 reference_cell.template get_default_linear_mapping<dim, spacedim>());
156 template <
int dim,
int spacedim>
162 unsigned int mapping_degree = 1;
164 mapping_degree = p->get_degree();
165 else if (
const auto *p =
167 mapping_degree = p->get_degree();
174 reference_cell.template get_gauss_type_quadrature<dim>(mapping_degree +
176 const unsigned int n_q_points = quadrature_formula.
size();
187 double local_volume = 0;
190 for (
const auto &cell :
triangulation.active_cell_iterators())
191 if (cell->is_locally_owned())
194 for (
unsigned int q = 0; q < n_q_points; ++q)
195 local_volume += fe_values.
JxW(q);
198 double global_volume = 0;
200#ifdef DEAL_II_WITH_MPI
208 global_volume = local_volume;
210 return global_volume;
232 struct TransformR2UAffine
247 [1] = {{-1.000000}, {1.000000}};
251 {1.000000, 0.000000};
262 [2] = {{-0.500000, -0.500000},
263 {0.500000, -0.500000},
264 {-0.500000, 0.500000},
265 {0.500000, 0.500000}};
275 {0.750000, 0.250000, 0.250000, -0.250000};
281 {-0.250000, -0.250000, -0.250000},
282 {0.250000, -0.250000, -0.250000},
283 {-0.250000, 0.250000, -0.250000},
284 {0.250000, 0.250000, -0.250000},
285 {-0.250000, -0.250000, 0.250000},
286 {0.250000, -0.250000, 0.250000},
287 {-0.250000, 0.250000, 0.250000},
288 {0.250000, 0.250000, 0.250000}
307 template <
int dim,
int spacedim>
316 for (
unsigned int d = 0; d < spacedim; ++d)
317 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
318 for (
unsigned int e = 0; e < dim; ++e)
319 A[d][e] +=
vertices[v][d] * TransformR2UAffine<dim>::KA[v][e];
323 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell; ++v)
324 b +=
vertices[v] * TransformR2UAffine<dim>::Kb[v];
326 return std::make_pair(A, b);
343 for (
const auto &cell :
triangulation.active_cell_iterators())
345 if (cell->is_locally_owned())
347 double aspect_ratio_cell = 0.0;
352 for (
unsigned int q = 0; q < quadrature.
size(); ++q)
363 aspect_ratio_cell = std::numeric_limits<double>::infinity();
368 for (
unsigned int i = 0; i < dim; ++i)
369 for (
unsigned int j = 0; j < dim; ++j)
370 J(i, j) = jacobian[i][j];
376 double const ar = max_sv / min_sv;
383 aspect_ratio_cell =
std::max(aspect_ratio_cell, ar);
388 aspect_ratio_vector(cell->active_cell_index()) = aspect_ratio_cell;
392 return aspect_ratio_vector;
413 template <
int dim,
int spacedim>
419 const auto predicate = [](
const iterator &) {
return true; };
422 tria, std::function<
bool(
const iterator &)>(predicate));
448 template <
int structdim>
456 if (std::lexicographical_compare(std::begin(a.
vertices),
458 std::begin(b.vertices),
459 std::end(b.vertices)))
465 if (std::equal(std::begin(a.
vertices),
467 std::begin(b.vertices)))
472 "Two CellData objects with equal vertices must "
473 "have the same material/boundary ids and manifold "
498 template <
class FaceIteratorType>
502 CellData<dim - 1> face_cell_data(face->n_vertices());
503 for (
unsigned int vertex_n = 0; vertex_n < face->n_vertices();
505 face_cell_data.vertices[vertex_n] = face->vertex_index(vertex_n);
506 face_cell_data.boundary_id = face->boundary_id();
507 face_cell_data.manifold_id = face->manifold_id();
509 face_data.insert(std::move(face_cell_data));
537 template <
class FaceIteratorType>
552 template <
int dim,
int spacedim>
554 tuple<std::vector<Point<spacedim>>, std::vector<CellData<dim>>,
SubCellData>
558 ExcMessage(
"The input triangulation must be non-empty."));
560 std::vector<Point<spacedim>>
vertices;
561 std::vector<CellData<dim>> cells;
563 unsigned int max_level_0_vertex_n = 0;
565 for (
const unsigned int cell_vertex_n : cell->vertex_indices())
566 max_level_0_vertex_n =
567 std::max(cell->vertex_index(cell_vertex_n), max_level_0_vertex_n);
568 vertices.resize(max_level_0_vertex_n + 1);
578 for (
const unsigned int cell_vertex_n : cell->vertex_indices())
582 vertices[cell->vertex_index(cell_vertex_n)] =
583 cell->vertex(cell_vertex_n);
585 cell->vertex_index(cell_vertex_n);
589 cells.push_back(cell_data);
594 for (
const unsigned int face_n : cell->face_indices())
597 const auto face = cell->face(face_n);
606 for (
unsigned int line_n = 0; line_n < cell->n_lines(); ++line_n)
608 const auto line = cell->line(line_n);
614 for (
const unsigned int vertex_n : line->vertex_indices())
616 line->vertex_index(vertex_n);
619 line_data.insert(std::move(line_cell_data));
628 std::vector<bool> used_vertices(
vertices.size());
630 for (
const auto v : cell_data.vertices)
631 used_vertices[v] =
true;
632 Assert(std::find(used_vertices.begin(), used_vertices.end(),
false) ==
634 ExcMessage(
"The level zero vertices should form a contiguous "
642 for (
const CellData<1> &face_line_data : line_data)
645 return std::tuple<std::vector<Point<spacedim>>,
646 std::vector<CellData<dim>>,
649 std::move(subcell_data));
654 template <
int dim,
int spacedim>
663 "Invalid SubCellData supplied according to ::check_consistency(). "
664 "This is caused by data containing objects for the wrong dimension."));
667 std::vector<bool> vertex_used(
vertices.size(),
false);
668 for (
unsigned int c = 0; c < cells.size(); ++c)
669 for (
unsigned int v = 0; v < cells[c].vertices.size(); ++v)
672 ExcMessage(
"Invalid vertex index encountered! cells[" +
676 " is invalid, because only " +
678 " vertices were supplied."));
679 vertex_used[cells[c].vertices[v]] =
true;
686 std::vector<unsigned int> new_vertex_numbers(
vertices.size(),
688 unsigned int next_free_number = 0;
689 for (
unsigned int i = 0; i <
vertices.size(); ++i)
690 if (vertex_used[i] ==
true)
692 new_vertex_numbers[i] = next_free_number;
697 for (
unsigned int c = 0; c < cells.size(); ++c)
698 for (
auto &v : cells[c].vertices)
699 v = new_vertex_numbers[v];
704 for (
unsigned int v = 0;
709 new_vertex_numbers.size(),
711 "Invalid vertex index in subcelldata.boundary_lines. "
712 "subcelldata.boundary_lines[" +
717 " is invalid, because only " +
719 " vertices were supplied."));
726 for (
unsigned int v = 0;
731 new_vertex_numbers.size(),
733 "Invalid vertex index in subcelldata.boundary_quads. "
734 "subcelldata.boundary_quads[" +
739 " is invalid, because only " +
741 " vertices were supplied."));
749 std::vector<Point<spacedim>> tmp;
750 tmp.reserve(std::count(vertex_used.begin(), vertex_used.end(),
true));
751 for (
unsigned int v = 0; v <
vertices.size(); ++v)
752 if (vertex_used[v] ==
true)
759 template <
int dim,
int spacedim>
764 std::vector<unsigned int> & considered_vertices,
771 std::vector<unsigned int> new_vertex_numbers(
vertices.size());
772 std::iota(new_vertex_numbers.begin(), new_vertex_numbers.end(), 0);
775 if (considered_vertices.size() == 0)
776 considered_vertices = new_vertex_numbers;
791 unsigned int longest_coordinate_direction = 0;
792 double longest_coordinate_length = bbox.
side_length(0);
793 for (
unsigned int d = 1; d < spacedim; ++d)
795 const double coordinate_length = bbox.
side_length(d);
796 if (longest_coordinate_length < coordinate_length)
798 longest_coordinate_length = coordinate_length;
799 longest_coordinate_direction = d;
805 std::vector<std::pair<unsigned int, Point<spacedim>>> sorted_vertices;
806 sorted_vertices.reserve(
vertices.size());
807 for (
const unsigned int vertex_n : considered_vertices)
810 sorted_vertices.emplace_back(vertex_n,
vertices[vertex_n]);
812 std::sort(sorted_vertices.begin(),
813 sorted_vertices.end(),
816 return a.second[longest_coordinate_direction] <
817 b.second[longest_coordinate_direction];
822 for (
unsigned int d = 0; d < spacedim; ++d)
830 auto range_start = sorted_vertices.begin();
831 while (range_start != sorted_vertices.end())
833 auto range_end = range_start + 1;
834 while (range_end != sorted_vertices.end() &&
835 std::abs(range_end->second[longest_coordinate_direction] -
836 range_start->second[longest_coordinate_direction]) <
842 std::sort(range_start,
846 return a.first < b.first;
855 for (
auto reference = range_start; reference != range_end; ++reference)
858 for (
auto it = reference + 1; it != range_end; ++it)
860 if (within_tolerance(reference->second, it->second))
862 new_vertex_numbers[it->first] = reference->first;
868 range_start = range_end;
875 for (
auto &cell : cells)
876 for (
auto &vertex_index : cell.vertices)
877 vertex_index = new_vertex_numbers[vertex_index];
879 for (
auto &vertex_index : quad.vertices)
880 vertex_index = new_vertex_numbers[vertex_index];
882 for (
auto &vertex_index : line.vertices)
883 vertex_index = new_vertex_numbers[vertex_index];
903 for (
unsigned int i = 0; i <
vertices.size(); ++i)
904 map_point_to_local_vertex_index[
vertices[i]] = i;
907 if (map_point_to_local_vertex_index.size() ==
vertices.size())
911 vertices.resize(map_point_to_local_vertex_index.size());
914 for (
const auto &p : map_point_to_local_vertex_index)
921 template <
int dim,
int spacedim>
932 if (dim == 2 && spacedim == 3)
935 std::size_t n_negative_cells = 0;
936 std::size_t cell_no = 0;
937 for (
auto &cell : cells)
945 const auto reference_cell =
948 if (reference_cell.is_hyper_cube())
953 std::swap(cell.vertices[1], cell.vertices[2]);
958 std::swap(cell.vertices[0], cell.vertices[2]);
959 std::swap(cell.vertices[1], cell.vertices[3]);
960 std::swap(cell.vertices[4], cell.vertices[6]);
961 std::swap(cell.vertices[5], cell.vertices[7]);
964 else if (reference_cell.is_simplex())
969 std::swap(cell.vertices[cell.vertices.size() - 2],
970 cell.vertices[cell.vertices.size() - 1]);
975 std::swap(cell.vertices[0], cell.vertices[3]);
976 std::swap(cell.vertices[1], cell.vertices[4]);
977 std::swap(cell.vertices[2], cell.vertices[5]);
983 std::swap(cell.vertices[2], cell.vertices[3]);
997 return n_negative_cells;
1001 template <
int dim,
int spacedim>
1007 const std::size_t n_negative_cells =
1016 AssertThrow(n_negative_cells == 0 || n_negative_cells == cells.size(),
1019 "This function assumes that either all cells have positive "
1020 "volume, or that all cells have been specified in an "
1021 "inverted vertex order so that their volume is negative. "
1022 "(In the latter case, this class automatically inverts "
1023 "every cell.) However, the mesh you have specified "
1024 "appears to have both cells with positive and cells with "
1025 "negative volume. You need to check your mesh which "
1026 "cells these are and how they got there.\n"
1027 "As a hint, of the total ") +
1028 std::to_string(cells.size()) +
" cells in the mesh, " +
1029 std::to_string(n_negative_cells) +
1030 " appear to have a negative volume."));
1048 CheapEdge(
const unsigned int v0,
const unsigned int v1)
1060 return ((v0 <
e.v0) || ((v0 ==
e.v0) && (v1 <
e.v1)));
1083 std::set<CheapEdge> edges;
1085 for (
typename std::vector<
CellData<dim>>::const_iterator c =
1095 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1097 const CheapEdge reverse_edge(
1100 if (edges.find(reverse_edge) != edges.end())
1105 const CheapEdge correct_edge(
1108 edges.insert(correct_edge);
1124 struct ParallelEdges
1138 static const unsigned int
1144 const unsigned int ParallelEdges<2>::starter_edges[2] = {0, 2};
1147 const unsigned int ParallelEdges<2>::parallel_edges[4][1] = {{1},
1153 const unsigned int ParallelEdges<3>::starter_edges[3] = {0, 2, 8};
1156 const unsigned int ParallelEdges<3>::parallel_edges[12][3] = {
1189 AdjacentCell(
const unsigned int cell_index,
1190 const unsigned int edge_within_cell)
1203 class AdjacentCells;
1211 class AdjacentCells<2>
1218 using const_iterator =
const AdjacentCell *;
1229 push_back(
const AdjacentCell &adjacent_cell)
1293 class AdjacentCells<3> :
public std::vector<AdjacentCell>
1315 Edge(
const CellData<dim> &cell,
const unsigned int edge_number)
1330 if (vertex_indices[0] > vertex_indices[1])
1331 std::swap(vertex_indices[0], vertex_indices[1]);
1341 return ((vertex_indices[0] <
e.vertex_indices[0]) ||
1342 ((vertex_indices[0] ==
e.vertex_indices[0]) &&
1343 (vertex_indices[1] <
e.vertex_indices[1])));
1352 return ((vertex_indices[0] ==
e.vertex_indices[0]) &&
1353 (vertex_indices[1] ==
e.vertex_indices[1]));
1366 enum OrientationStatus
1396 Cell(
const CellData<dim> &c,
const std::vector<Edge<dim>> &edge_list)
1403 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1405 const Edge<dim>
e(c,
l);
1407 (std::lower_bound(edge_list.begin(), edge_list.end(),
e) -
1441 class EdgeDeltaSet<2>
1447 using const_iterator =
const unsigned int *;
1473 insert(
const unsigned int edge_index)
1534 class EdgeDeltaSet<3> :
public std::set<unsigned int>
1544 std::vector<Edge<dim>>
1551 std::vector<Edge<dim>> edge_list;
1553 for (
unsigned int i = 0; i < cells.size(); ++i)
1554 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1555 edge_list.emplace_back(cells[i], l);
1558 std::sort(edge_list.begin(), edge_list.end());
1559 edge_list.erase(std::unique(edge_list.begin(), edge_list.end()),
1572 std::vector<Cell<dim>>
1573 build_cells_and_connect_edges(
const std::vector<
CellData<dim>> &cells,
1574 std::vector<Edge<dim>> & edges)
1576 std::vector<Cell<dim>> cell_list;
1577 cell_list.reserve(cells.size());
1578 for (
unsigned int i = 0; i < cells.size(); ++i)
1582 cell_list.emplace_back(cells[i], edges);
1586 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1587 edges[cell_list.back().edge_indices[
l]].adjacent_cells.push_back(
1588 AdjacentCell(i, l));
1603 get_next_unoriented_cell(
const std::vector<Cell<dim>> &cells,
1604 const std::vector<Edge<dim>> &edges,
1605 const unsigned int current_cell)
1607 for (
unsigned int c = current_cell; c < cells.size(); ++c)
1608 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1610 Edge<dim>::not_oriented)
1625 orient_one_set_of_parallel_edges(
const std::vector<Cell<dim>> &cells,
1626 std::vector<Edge<dim>> & edges,
1627 const unsigned int cell,
1628 const unsigned int local_edge)
1655 edges[cells[cell].edge_indices[local_edge]].orientation_status =
1656 (dim == 2 ? Edge<dim>::backward : Edge<dim>::forward);
1672 edges[cells[cell].edge_indices[local_edge]].orientation_status =
1673 (dim == 2 ? Edge<dim>::forward : Edge<dim>::backward);
1682 EdgeDeltaSet<dim> Delta_k;
1683 EdgeDeltaSet<dim> Delta_k_minus_1;
1684 Delta_k_minus_1.insert(cells[cell].
edge_indices[local_edge]);
1686 while (Delta_k_minus_1.begin() !=
1687 Delta_k_minus_1.end())
1691 for (
typename EdgeDeltaSet<dim>::const_iterator delta =
1692 Delta_k_minus_1.begin();
1693 delta != Delta_k_minus_1.end();
1697 Edge<dim>::not_oriented,
1701 for (
typename AdjacentCells<dim>::const_iterator adjacent_cell =
1703 adjacent_cell != edges[*delta].adjacent_cells.end();
1706 const unsigned int K = adjacent_cell->cell_index;
1707 const unsigned int delta_is_edge_in_K =
1708 adjacent_cell->edge_within_cell;
1712 const unsigned int first_edge_vertex =
1713 (edges[*delta].orientation_status == Edge<dim>::forward ?
1714 edges[*delta].vertex_indices[0] :
1715 edges[*delta].vertex_indices[1]);
1716 const unsigned int first_edge_vertex_in_K =
1719 delta_is_edge_in_K, 0)];
1721 first_edge_vertex == first_edge_vertex_in_K ||
1722 first_edge_vertex ==
1724 dim>::line_to_cell_vertices(delta_is_edge_in_K, 1)],
1729 for (
unsigned int o_e = 0;
1730 o_e < ParallelEdges<dim>::n_other_parallel_edges;
1736 const unsigned int opposite_edge =
1737 cells[
K].edge_indices[ParallelEdges<
1739 const unsigned int first_opposite_edge_vertex =
1740 cells[
K].vertex_indices
1744 (first_edge_vertex == first_edge_vertex_in_K ? 0 :
1751 const typename Edge<dim>::OrientationStatus
1752 opposite_edge_orientation =
1753 (edges[opposite_edge].vertex_indices[0] ==
1754 first_opposite_edge_vertex ?
1755 Edge<dim>::forward :
1756 Edge<dim>::backward);
1761 Edge<dim>::not_oriented)
1765 edges[opposite_edge].orientation_status =
1766 opposite_edge_orientation;
1767 Delta_k.insert(opposite_edge);
1783 opposite_edge_orientation,
1789 opposite_edge_orientation)
1802 Delta_k_minus_1 = Delta_k;
1816 rotate_cell(
const std::vector<Cell<dim>> &cell_list,
1817 const std::vector<Edge<dim>> &edge_list,
1824 for (
unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++
e)
1831 starting_vertex_of_edge[
e] =
1835 starting_vertex_of_edge[
e] =
1851 if ((starting_vertex_of_edge[0] == starting_vertex_of_edge[2]) ||
1852 (starting_vertex_of_edge[0] == starting_vertex_of_edge[3]))
1853 origin_vertex_of_cell = starting_vertex_of_edge[0];
1854 else if ((starting_vertex_of_edge[1] ==
1855 starting_vertex_of_edge[2]) ||
1856 (starting_vertex_of_edge[1] ==
1857 starting_vertex_of_edge[3]))
1858 origin_vertex_of_cell = starting_vertex_of_edge[1];
1870 for (origin_vertex_of_cell = 0;
1871 origin_vertex_of_cell < GeometryInfo<dim>::vertices_per_cell;
1872 ++origin_vertex_of_cell)
1873 if (std::count(starting_vertex_of_edge,
1874 starting_vertex_of_edge +
1879 Assert(origin_vertex_of_cell <
1904 const unsigned int tmp = raw_cells[
cell_index].vertices[0];
1927 static const unsigned int cube_permutations[8][8] = {
1928 {0, 1, 2, 3, 4, 5, 6, 7},
1929 {1, 5, 3, 7, 0, 4, 2, 6},
1930 {2, 6, 0, 4, 3, 7, 1, 5},
1931 {3, 2, 1, 0, 7, 6, 5, 4},
1932 {4, 0, 6, 2, 5, 1, 7, 3},
1933 {5, 4, 7, 6, 1, 0, 3, 2},
1934 {6, 7, 4, 5, 2, 3, 0, 1},
1935 {7, 3, 5, 1, 6, 2, 4, 0}};
1940 temp_vertex_indices[v] =
1942 .
vertices[cube_permutations[origin_vertex_of_cell][v]];
1968 std::vector<Edge<dim>> edge_list = build_edges(cells);
1969 std::vector<Cell<dim>> cell_list =
1970 build_cells_and_connect_edges(cells, edge_list);
1974 unsigned int next_cell_with_unoriented_edge = 0;
1975 while ((next_cell_with_unoriented_edge = get_next_unoriented_cell(
1976 cell_list, edge_list, next_cell_with_unoriented_edge)) !=
1990 for (
unsigned int l = 0;
l < dim; ++
l)
1991 if (edge_list[cell_list[next_cell_with_unoriented_edge]
1994 orient_one_set_of_parallel_edges(
1997 next_cell_with_unoriented_edge,
1998 ParallelEdges<dim>::starter_edges[l]);
2002 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
2003 Assert(edge_list[cell_list[next_cell_with_unoriented_edge]
2012 for (
unsigned int c = 0; c < cells.size(); ++c)
2013 rotate_cell(cell_list, edge_list, c, cells);
2028 Assert(cells.size() != 0,
2030 "List of elements to orient must have at least one cell"));
2038 if (!is_consistent(cells))
2057 template <
int spacedim>
2081 Physics::Transformations::Rotations::rotation_matrix_2d(angle))
2100 Physics::Transformations::Rotations::rotation_matrix_3d(axis,
2115 template <
int spacedim>
2134 template <
int dim,
int spacedim>
2144 template <
int dim,
int spacedim>
2153 "GridTools::rotate() is only available for spacedim = 2."));
2188 const unsigned int axis,
2200 template <
int dim,
int spacedim>
2222 const unsigned int n_dofs = S.
n();
2234 const auto constrained_rhs =
2236 solver.
solve(SF, u, constrained_rhs, prec);
2249 const bool solve_for_absolute_positions)
2275 const auto reference_cell = ReferenceCells::get_hypercube<dim>();
2277 reference_cell.template get_default_linear_mapping<dim, dim>(),
2284 std::array<AffineConstraints<double>, dim> constraints;
2285 typename std::map<unsigned int, Point<dim>>::const_iterator map_end =
2293 for (
const unsigned int vertex_no : cell->vertex_indices())
2295 const unsigned int vertex_index = cell->vertex_index(vertex_no);
2296 const Point<dim> & vertex_point = cell->vertex(vertex_no);
2298 const typename std::map<unsigned int, Point<dim>>::const_iterator
2299 map_iter = new_points.find(vertex_index);
2301 if (map_iter != map_end)
2302 for (
unsigned int i = 0; i < dim; ++i)
2304 constraints[i].add_line(cell->vertex_dof_index(vertex_no, 0));
2305 constraints[i].set_inhomogeneity(
2306 cell->vertex_dof_index(vertex_no, 0),
2307 (solve_for_absolute_positions ?
2308 map_iter->second(i) :
2309 map_iter->second(i) - vertex_point[i]));
2314 for (
unsigned int i = 0; i < dim; ++i)
2315 constraints[i].close();
2319 for (
unsigned int i = 0; i < dim; ++i)
2320 us[i].reinit(dof_handler.
n_dofs());
2324 for (
unsigned int i = 0; i < dim; ++i)
2331 std::vector<bool> vertex_touched(
triangulation.n_vertices(),
false);
2333 for (
const unsigned int vertex_no : cell->vertex_indices())
2334 if (vertex_touched[cell->vertex_index(vertex_no)] ==
false)
2339 cell->vertex_dof_index(vertex_no, 0);
2340 for (
unsigned int i = 0; i < dim; ++i)
2341 if (solve_for_absolute_positions)
2342 v(i) = us[i](dof_index);
2344 v(i) += us[i](dof_index);
2346 vertex_touched[cell->vertex_index(vertex_no)] =
true;
2350 template <
int dim,
int spacedim>
2351 std::map<unsigned int, Point<spacedim>>
2354 std::map<unsigned int, Point<spacedim>> vertex_map;
2358 for (; cell != endc; ++cell)
2360 for (
const unsigned int i : cell->face_indices())
2364 if (face->at_boundary())
2366 for (
unsigned j = 0; j < face->n_vertices(); ++j)
2369 const unsigned int vertex_index = face->vertex_index(j);
2370 vertex_map[vertex_index] = vertex;
2382 template <
int dim,
int spacedim>
2386 const bool keep_boundary,
2387 const unsigned int seed)
2404 double almost_infinite_length = 0;
2409 almost_infinite_length += cell->diameter();
2411 std::vector<double> minimal_length(
triangulation.n_vertices(),
2412 almost_infinite_length);
2415 std::vector<bool> at_boundary(keep_boundary ?
triangulation.n_vertices() :
2420 const bool is_parallel_shared =
2423 for (
const auto &cell :
triangulation.active_cell_iterators())
2424 if (is_parallel_shared || cell->is_locally_owned())
2428 for (
unsigned int i = 0; i < cell->n_lines(); ++i)
2431 line = cell->line(i);
2433 if (keep_boundary && line->at_boundary())
2435 at_boundary[line->vertex_index(0)] =
true;
2436 at_boundary[line->vertex_index(1)] =
true;
2439 minimal_length[line->vertex_index(0)] =
2441 minimal_length[line->vertex_index(0)]);
2442 minimal_length[line->vertex_index(1)] =
2444 minimal_length[line->vertex_index(1)]);
2450 for (
unsigned int vertex = 0; vertex < 2; ++vertex)
2451 if (cell->at_boundary(vertex) ==
true)
2452 at_boundary[cell->vertex_index(vertex)] =
true;
2454 minimal_length[cell->vertex_index(0)] =
2456 minimal_length[cell->vertex_index(0)]);
2457 minimal_length[cell->vertex_index(1)] =
2459 minimal_length[cell->vertex_index(1)]);
2464 boost::random::mt19937 rng(seed);
2465 boost::random::uniform_real_distribution<> uniform_distribution(-1, 1);
2469 if (
auto distributed_triangulation =
2473 const std::vector<bool> locally_owned_vertices =
2475 std::vector<bool> vertex_moved(
triangulation.n_vertices(),
false);
2478 for (
const auto &cell :
triangulation.active_cell_iterators())
2479 if (cell->is_locally_owned())
2481 for (
const unsigned int vertex_no : cell->vertex_indices())
2483 const unsigned global_vertex_no =
2484 cell->vertex_index(vertex_no);
2489 if ((keep_boundary && at_boundary[global_vertex_no]) ||
2490 vertex_moved[global_vertex_no] ||
2491 !locally_owned_vertices[global_vertex_no])
2496 for (
unsigned int d = 0; d < spacedim; ++d)
2497 shift_vector(d) = uniform_distribution(rng);
2499 shift_vector *= factor * minimal_length[global_vertex_no] /
2503 cell->vertex(vertex_no) += shift_vector;
2504 vertex_moved[global_vertex_no] =
true;
2508 distributed_triangulation->communicate_locally_moved_vertices(
2509 locally_owned_vertices);
2519 std::vector<Point<spacedim>> new_vertex_locations(n_vertices);
2520 const std::vector<Point<spacedim>> &old_vertex_locations =
2523 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
2527 if (keep_boundary && at_boundary[vertex])
2528 new_vertex_locations[vertex] = old_vertex_locations[vertex];
2533 for (
unsigned int d = 0; d < spacedim; ++d)
2534 shift_vector(d) = uniform_distribution(rng);
2536 shift_vector *= factor * minimal_length[vertex] /
2540 new_vertex_locations[vertex] =
2541 old_vertex_locations[vertex] + shift_vector;
2546 for (
const auto &cell :
triangulation.active_cell_iterators())
2547 for (
const unsigned int vertex_no : cell->vertex_indices())
2548 cell->vertex(vertex_no) =
2549 new_vertex_locations[cell->vertex_index(vertex_no)];
2565 for (; cell != endc; ++cell)
2566 if (!cell->is_artificial())
2567 for (
const unsigned int face : cell->face_indices())
2568 if (cell->face(face)->has_children() &&
2569 !cell->face(face)->at_boundary())
2573 cell->face(face)->child(0)->vertex(1) =
2574 (cell->face(face)->vertex(0) +
2575 cell->face(face)->vertex(1)) /
2579 cell->face(face)->child(0)->vertex(1) =
2580 .5 * (cell->face(face)->vertex(0) +
2581 cell->face(face)->vertex(1));
2582 cell->face(face)->child(0)->vertex(2) =
2583 .5 * (cell->face(face)->vertex(0) +
2584 cell->face(face)->vertex(2));
2585 cell->face(face)->child(1)->vertex(3) =
2586 .5 * (cell->face(face)->vertex(1) +
2587 cell->face(face)->vertex(3));
2588 cell->face(face)->child(2)->vertex(3) =
2589 .5 * (cell->face(face)->vertex(2) +
2590 cell->face(face)->vertex(3));
2593 cell->face(face)->child(0)->vertex(3) =
2594 .25 * (cell->face(face)->vertex(0) +
2595 cell->face(face)->vertex(1) +
2596 cell->face(face)->vertex(2) +
2597 cell->face(face)->vertex(3));
2605 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
2609 const
Point<spacedim> & p,
2610 const
std::vector<
bool> &marked_vertices)
2619 marked_vertices.size() == 0,
2621 marked_vertices.size()));
2628 marked_vertices.size() == 0 ||
2629 std::equal(marked_vertices.begin(),
2630 marked_vertices.end(),
2632 [](
bool p,
bool q) { return !p || q; }),
2634 "marked_vertices should be a subset of used vertices in the triangulation "
2635 "but marked_vertices contains one or more vertices that are not used vertices!"));
2639 const std::vector<bool> &vertices_to_use = (marked_vertices.size() == 0) ?
2645 std::vector<bool>::const_iterator
first =
2646 std::find(vertices_to_use.begin(), vertices_to_use.end(),
true);
2651 unsigned int best_vertex = std::distance(vertices_to_use.begin(),
first);
2652 double best_dist = (p -
vertices[best_vertex]).norm_square();
2656 for (
unsigned int j = best_vertex + 1; j <
vertices.size(); ++j)
2657 if (vertices_to_use[j])
2659 const double dist = (p -
vertices[j]).norm_square();
2660 if (dist < best_dist)
2672 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
2676 const MeshType<dim, spacedim> &mesh,
2677 const
Point<spacedim> & p,
2678 const
std::vector<
bool> &marked_vertices)
2681 if (mapping.preserves_vertex_locations() ==
true)
2691 marked_vertices.size() == 0,
2693 marked_vertices.size()));
2701 marked_vertices.size() == 0 ||
2702 std::equal(marked_vertices.begin(),
2703 marked_vertices.end(),
2705 [](
bool p,
bool q) { return !p || q; }),
2707 "marked_vertices should be a subset of used vertices in the triangulation "
2708 "but marked_vertices contains one or more vertices that are not used vertices!"));
2711 if (marked_vertices.size() != 0)
2714 if (marked_vertices[it->first] ==
false)
2729 template <
int dim,
int spacedim>
2730 std::vector<std::vector<Tensor<1, spacedim>>>
2738 const unsigned int n_vertices = vertex_to_cells.size();
2743 std::vector<std::vector<Tensor<1, spacedim>>> vertex_to_cell_centers(
2745 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
2748 const unsigned int n_neighbor_cells = vertex_to_cells[vertex].size();
2749 vertex_to_cell_centers[vertex].resize(n_neighbor_cells);
2751 typename std::set<typename Triangulation<dim, spacedim>::
2752 active_cell_iterator>::iterator it =
2753 vertex_to_cells[vertex].begin();
2754 for (
unsigned int cell = 0; cell < n_neighbor_cells; ++cell, ++it)
2756 vertex_to_cell_centers[vertex][cell] =
2757 (*it)->center() -
vertices[vertex];
2758 vertex_to_cell_centers[vertex][cell] /=
2759 vertex_to_cell_centers[vertex][cell].
norm();
2762 return vertex_to_cell_centers;
2768 template <
int spacedim>
2771 const unsigned int a,
2772 const unsigned int b,
2776 const double scalar_product_a = center_directions[a] * point_direction;
2777 const double scalar_product_b = center_directions[b] * point_direction;
2782 return (scalar_product_a > scalar_product_b);
2786 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
2790 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim>>
2792 std::pair<typename ::internal::
2793 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
2798 const MeshType<dim, spacedim> &mesh,
2801 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator>>
2804 &vertex_to_cell_centers,
2805 const typename MeshType<dim, spacedim>::active_cell_iterator &cell_hint,
2806 const std::vector<bool> &marked_vertices,
2808 & used_vertices_rtree,
2809 const double tolerance,
2813 *relevant_cell_bounding_boxes_rtree)
2815 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
2818 cell_and_position.first = mesh.end();
2822 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
2824 cell_and_position_approx;
2826 if (relevant_cell_bounding_boxes_rtree !=
nullptr &&
2827 !relevant_cell_bounding_boxes_rtree->empty())
2833 for (
unsigned int d = 0; d < spacedim; ++d)
2835 p1[d] = p1[d] - tolerance;
2836 p2[d] = p2[d] + tolerance;
2841 if (relevant_cell_bounding_boxes_rtree->qbegin(
2842 boost::geometry::index::intersects(bb)) ==
2843 relevant_cell_bounding_boxes_rtree->qend())
2844 return cell_and_position;
2847 bool found_cell =
false;
2848 bool approx_cell =
false;
2850 unsigned int closest_vertex_index = 0;
2855 if (marked_vertices.size() && !used_vertices_rtree.empty())
2858 std::find(marked_vertices.begin(), marked_vertices.end(),
true);
2859 Assert(itr != marked_vertices.end(),
2861 closest_vertex_index = std::distance(marked_vertices.begin(), itr);
2865 auto current_cell = cell_hint;
2868 const auto cell_marked = [&mesh, &marked_vertices](
const auto &cell) {
2869 if (marked_vertices.size() == 0)
2872 if (cell != mesh.active_cell_iterators().end())
2873 for (
unsigned int i = 0; i < cell->n_vertices(); ++i)
2874 if (marked_vertices[cell->vertex_index(i)])
2881 const auto any_cell_marked = [&cell_marked](
const auto &cells) {
2882 return std::any_of(cells.begin(),
2884 [&cell_marked](
const auto &cell) {
2885 return cell_marked(cell);
2888 (void)any_cell_marked;
2890 while (found_cell ==
false)
2895 cell_marked(cell_hint))
2897 const auto cell_vertices = mapping.
get_vertices(current_cell);
2898 const unsigned int closest_vertex =
2899 find_closest_vertex_of_cell<dim, spacedim>(current_cell,
2902 vertex_to_point = p - cell_vertices[closest_vertex];
2903 closest_vertex_index = current_cell->vertex_index(closest_vertex);
2912#if defined(DEAL_II_WITH_BOOST_BUNDLED) || \
2913 !(defined(__clang_major__) && __clang_major__ >= 16) || \
2914 BOOST_VERSION >= 108100
2915 if (!used_vertices_rtree.empty())
2918 using ValueType = std::pair<Point<spacedim>,
unsigned int>;
2919 std::function<
bool(
const ValueType &)> marked;
2920 if (marked_vertices.size() == mesh.n_vertices())
2921 marked = [&marked_vertices](
const ValueType &value) ->
bool {
2922 return marked_vertices[value.second];
2925 marked = [](
const ValueType &) ->
bool {
return true; };
2927 std::vector<std::pair<Point<spacedim>,
unsigned int>> res;
2928 used_vertices_rtree.query(
2929 boost::geometry::index::nearest(p, 1) &&
2930 boost::geometry::index::satisfies(marked),
2931 std::back_inserter(res));
2939 if (any_cell_marked(vertex_to_cells[res[0].
second]))
2940 closest_vertex_index = res[0].second;
2946 mapping, mesh, p, marked_vertices);
2948 vertex_to_point = p - mesh.get_vertices()[closest_vertex_index];
2954 Assert(any_cell_marked(vertex_to_cells[closest_vertex_index]),
2959 const double vertex_point_norm = vertex_to_point.
norm();
2960 if (vertex_point_norm > 0)
2961 vertex_to_point /= vertex_point_norm;
2963 const unsigned int n_neighbor_cells =
2964 vertex_to_cells[closest_vertex_index].size();
2967 std::vector<unsigned int> neighbor_permutation(n_neighbor_cells);
2969 for (
unsigned int i = 0; i < n_neighbor_cells; ++i)
2970 neighbor_permutation[i] = i;
2972 auto comp = [&](
const unsigned int a,
const unsigned int b) ->
bool {
2973 return internal::compare_point_association<spacedim>(
2977 vertex_to_cell_centers[closest_vertex_index]);
2980 std::sort(neighbor_permutation.begin(),
2981 neighbor_permutation.end(),
2986 double best_distance = tolerance;
2990 for (
unsigned int i = 0; i < n_neighbor_cells; ++i)
2994 auto cell = vertex_to_cells[closest_vertex_index].begin();
2995 std::advance(cell, neighbor_permutation[i]);
2997 if (!(*cell)->is_artificial())
3004 cell_and_position.first = *cell;
3005 cell_and_position.second = p_unit;
3007 approx_cell =
false;
3016 if (dist < best_distance)
3018 best_distance = dist;
3019 cell_and_position_approx.first = *cell;
3020 cell_and_position_approx.second = p_unit;
3029 if (found_cell ==
true)
3030 return cell_and_position;
3031 else if (approx_cell ==
true)
3032 return cell_and_position_approx;
3048 mapping, mesh, p, marked_vertices, tolerance);
3050 current_cell =
typename MeshType<dim, spacedim>::active_cell_iterator();
3052 return cell_and_position;
3057 template <
int dim,
int spacedim>
3066 unsigned int closest_vertex = 0;
3068 for (
unsigned int v = 1; v < cell->n_vertices(); ++v)
3071 if (vertex_distance < minimum_distance)
3074 minimum_distance = vertex_distance;
3077 return closest_vertex;
3084 namespace BoundingBoxPredicate
3086 template <
class MeshType>
3092 cell_iterator &parent_cell,
3094 const typename MeshType::
3095 active_cell_iterator &)>
3098 bool has_predicate =
3100 std::vector<typename MeshType::active_cell_iterator> active_cells;
3101 if (parent_cell->is_active())
3102 active_cells = {parent_cell};
3106 active_cells = get_active_child_cells<MeshType>(parent_cell);
3108 const unsigned int spacedim = MeshType::space_dimension;
3112 while (i < active_cells.size() && !predicate(active_cells[i]))
3116 if (active_cells.size() == 0 || i == active_cells.size())
3119 return std::make_tuple(bbox, has_predicate);
3126 for (; i < active_cells.size(); ++i)
3127 if (predicate(active_cells[i]))
3128 for (
const unsigned int v : active_cells[i]->vertex_indices())
3129 for (
unsigned int d = 0; d < spacedim; ++d)
3131 minp[d] =
std::min(minp[d], active_cells[i]->vertex(v)[d]);
3132 maxp[d] =
std::max(maxp[d], active_cells[i]->vertex(v)[d]);
3135 has_predicate =
true;
3137 return std::make_tuple(bbox, has_predicate);
3144 template <
class MeshType>
3148 const MeshType &mesh,
3149 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
3151 const unsigned int refinement_level,
3152 const bool allow_merge,
3153 const unsigned int max_boxes)
3160 refinement_level <= mesh.n_levels(),
3162 "Error: refinement level is higher then total levels in the triangulation!"));
3164 const unsigned int spacedim = MeshType::space_dimension;
3165 std::vector<BoundingBox<spacedim>> bounding_boxes;
3169 for (
unsigned int i = 0; i < refinement_level; ++i)
3170 for (
const typename MeshType::cell_iterator &cell :
3171 mesh.active_cell_iterators_on_level(i))
3173 bool has_predicate =
false;
3175 std::tie(bbox, has_predicate) =
3177 MeshType>(cell, predicate);
3179 bounding_boxes.push_back(bbox);
3183 for (
const typename MeshType::cell_iterator &cell :
3184 mesh.cell_iterators_on_level(refinement_level))
3186 bool has_predicate =
false;
3188 std::tie(bbox, has_predicate) =
3190 MeshType>(cell, predicate);
3192 bounding_boxes.push_back(bbox);
3197 return bounding_boxes;
3203 std::vector<unsigned int> merged_boxes_idx;
3204 bool found_neighbors =
true;
3209 while (found_neighbors)
3211 found_neighbors =
false;
3212 for (
unsigned int i = 0; i < bounding_boxes.size() - 1; ++i)
3214 if (std::find(merged_boxes_idx.begin(),
3215 merged_boxes_idx.end(),
3216 i) == merged_boxes_idx.end())
3217 for (
unsigned int j = i + 1; j < bounding_boxes.size(); ++j)
3218 if (std::find(merged_boxes_idx.begin(),
3219 merged_boxes_idx.end(),
3220 j) == merged_boxes_idx.end() &&
3221 bounding_boxes[i].get_neighbor_type(
3222 bounding_boxes[j]) ==
3225 bounding_boxes[i].merge_with(bounding_boxes[j]);
3226 merged_boxes_idx.push_back(j);
3227 found_neighbors =
true;
3233 std::vector<BoundingBox<spacedim>> merged_b_boxes;
3234 for (
unsigned int i = 0; i < bounding_boxes.size(); ++i)
3235 if (std::find(merged_boxes_idx.begin(), merged_boxes_idx.end(), i) ==
3236 merged_boxes_idx.end())
3237 merged_b_boxes.push_back(bounding_boxes[i]);
3242 if ((merged_b_boxes.size() > max_boxes) && (spacedim > 1))
3244 std::vector<double> volumes;
3245 for (
unsigned int i = 0; i < merged_b_boxes.size(); ++i)
3246 volumes.push_back(merged_b_boxes[i].volume());
3248 while (merged_b_boxes.size() > max_boxes)
3250 unsigned int min_idx =
3251 std::min_element(volumes.begin(), volumes.end()) -
3253 volumes.erase(volumes.begin() + min_idx);
3255 bool not_removed =
true;
3256 for (
unsigned int i = 0;
3257 i < merged_b_boxes.size() && not_removed;
3262 if (i != min_idx && (merged_b_boxes[i].get_neighbor_type(
3263 merged_b_boxes[min_idx]) ==
3265 merged_b_boxes[i].get_neighbor_type(
3266 merged_b_boxes[min_idx]) ==
3269 merged_b_boxes[i].merge_with(merged_b_boxes[min_idx]);
3270 merged_b_boxes.erase(merged_b_boxes.begin() + min_idx);
3271 not_removed =
false;
3274 ExcMessage(
"Error: couldn't merge bounding boxes!"));
3277 Assert(merged_b_boxes.size() <= max_boxes,
3279 "Error: couldn't reach target number of bounding boxes!"));
3280 return merged_b_boxes;
3286 template <
int spacedim>
3288 std::tuple<std::vector<std::vector<unsigned int>>,
3289 std::map<unsigned int, unsigned int>,
3290 std::map<unsigned int, std::vector<unsigned int>>>
3298 unsigned int n_procs = global_bboxes.size();
3299 std::vector<std::vector<unsigned int>> point_owners(n_procs);
3300 std::map<unsigned int, unsigned int> map_owners_found;
3301 std::map<unsigned int, std::vector<unsigned int>> map_owners_guessed;
3303 unsigned int n_points = points.size();
3304 for (
unsigned int pt = 0; pt < n_points; ++pt)
3307 std::vector<unsigned int> owners_found;
3309 for (
unsigned int rk = 0; rk < n_procs; ++rk)
3312 if (bbox.point_inside(points[pt]))
3314 point_owners[rk].emplace_back(pt);
3315 owners_found.emplace_back(rk);
3319 Assert(owners_found.size() > 0,
3320 ExcMessage(
"No owners found for the point " +
3321 std::to_string(pt)));
3322 if (owners_found.size() == 1)
3323 map_owners_found[pt] = owners_found[0];
3326 map_owners_guessed[pt] = owners_found;
3329 return std::make_tuple(std::move(point_owners),
3330 std::move(map_owners_found),
3331 std::move(map_owners_guessed));
3334 template <
int spacedim>
3336 std::tuple<std::map<unsigned int, std::vector<unsigned int>>,
3337 std::map<unsigned int, unsigned int>,
3338 std::map<unsigned int, std::vector<unsigned int>>>
3346 std::map<unsigned int, std::vector<unsigned int>> point_owners;
3347 std::map<unsigned int, unsigned int> map_owners_found;
3348 std::map<unsigned int, std::vector<unsigned int>> map_owners_guessed;
3349 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>> search_result;
3351 unsigned int n_points = points.size();
3352 for (
unsigned int pt_n = 0; pt_n < n_points; ++pt_n)
3354 search_result.clear();
3357 covering_rtree.query(boost::geometry::index::intersects(points[pt_n]),
3358 std::back_inserter(search_result));
3361 std::set<unsigned int> owners_found;
3363 for (
const auto &rank_bbox : search_result)
3367 const bool pt_inserted = owners_found.insert(pt_n).second;
3369 point_owners[rank_bbox.second].emplace_back(pt_n);
3371 Assert(owners_found.size() > 0,
3372 ExcMessage(
"No owners found for the point " +
3373 std::to_string(pt_n)));
3374 if (owners_found.size() == 1)
3375 map_owners_found[pt_n] = *owners_found.begin();
3378 std::copy(owners_found.begin(),
3380 std::back_inserter(map_owners_guessed[pt_n]));
3383 return std::make_tuple(std::move(point_owners),
3384 std::move(map_owners_found),
3385 std::move(map_owners_guessed));
3389 template <
int dim,
int spacedim>
3391 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>>
3395 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>>
3400 for (; cell != endc; ++cell)
3401 for (
const unsigned int i : cell->vertex_indices())
3406 for (; cell != endc; ++cell)
3408 for (
const unsigned int i : cell->face_indices())
3410 if ((cell->at_boundary(i) ==
false) &&
3411 (cell->neighbor(i)->is_active()))
3414 adjacent_cell = cell->neighbor(i);
3415 for (
unsigned int j = 0; j < cell->face(i)->n_vertices(); ++j)
3424 for (
unsigned int i = 0; i < cell->n_lines(); ++i)
3425 if (cell->line(i)->has_children())
3439 template <
int dim,
int spacedim>
3440 std::map<unsigned int, types::global_vertex_index>
3444 std::map<unsigned int, types::global_vertex_index>
3445 local_to_global_vertex_index;
3447#ifndef DEAL_II_WITH_MPI
3454 ExcMessage(
"This function does not make any sense "
3455 "for parallel::distributed::Triangulation "
3456 "objects if you do not have MPI enabled."));
3460 using active_cell_iterator =
3462 const std::vector<std::set<active_cell_iterator>> vertex_to_cell =
3467 unsigned int max_cellid_size = 0;
3468 std::set<std::pair<types::subdomain_id, types::global_vertex_index>>
3470 std::map<types::subdomain_id, std::set<unsigned int>> vertices_to_recv;
3476 std::set<active_cell_iterator> missing_vert_cells;
3477 std::set<unsigned int> used_vertex_index;
3478 for (
const auto &cell :
triangulation.active_cell_iterators())
3480 if (cell->is_locally_owned())
3482 for (
const unsigned int i : cell->vertex_indices())
3485 for (
const auto &adjacent_cell :
3486 vertex_to_cell[cell->vertex_index(i)])
3487 lowest_subdomain_id =
std::min(lowest_subdomain_id,
3488 adjacent_cell->subdomain_id());
3491 if (lowest_subdomain_id == cell->subdomain_id())
3495 if (used_vertex_index.find(cell->vertex_index(i)) ==
3496 used_vertex_index.end())
3499 local_to_global_vertex_index[cell->vertex_index(i)] =
3504 for (
const auto &adjacent_cell :
3505 vertex_to_cell[cell->vertex_index(i)])
3506 if (adjacent_cell->subdomain_id() !=
3507 cell->subdomain_id())
3511 tmp(adjacent_cell->subdomain_id(),
3512 cell->vertex_index(i));
3513 if (vertices_added.find(tmp) ==
3514 vertices_added.end())
3516 vertices_to_send[adjacent_cell
3519 cell->vertex_index(i),
3520 cell->id().to_string());
3521 if (cell->id().to_string().size() >
3524 cell->id().to_string().size();
3525 vertices_added.insert(tmp);
3528 used_vertex_index.insert(cell->vertex_index(i));
3535 vertices_to_recv[lowest_subdomain_id].insert(
3536 cell->vertex_index(i));
3537 missing_vert_cells.insert(cell);
3544 if (cell->is_ghost())
3546 for (
const unsigned int i : cell->face_indices())
3548 if (cell->at_boundary(i) ==
false)
3550 if (cell->neighbor(i)->is_active())
3553 spacedim>::active_cell_iterator
3554 adjacent_cell = cell->neighbor(i);
3555 if ((adjacent_cell->is_locally_owned()))
3558 adjacent_cell->subdomain_id();
3559 if (cell->subdomain_id() < adj_subdomain_id)
3560 for (
unsigned int j = 0;
3561 j < cell->face(i)->n_vertices();
3564 vertices_to_recv[cell->subdomain_id()].insert(
3565 cell->face(i)->vertex_index(j));
3566 missing_vert_cells.insert(cell);
3582 int ierr = MPI_Exscan(&next_index,
3590 for (
auto &global_index_it : local_to_global_vertex_index)
3591 global_index_it.second +=
shift;
3605 std::vector<std::vector<types::global_vertex_index>> vertices_send_buffers(
3606 vertices_to_send.size());
3607 std::vector<MPI_Request> first_requests(vertices_to_send.size());
3611 std::string>>>::iterator
3612 vert_to_send_it = vertices_to_send.begin(),
3613 vert_to_send_end = vertices_to_send.end();
3614 for (
unsigned int i = 0; vert_to_send_it != vert_to_send_end;
3615 ++vert_to_send_it, ++i)
3617 int destination = vert_to_send_it->first;
3618 const unsigned int n_vertices = vert_to_send_it->second.size();
3619 const int buffer_size = 2 * n_vertices;
3620 vertices_send_buffers[i].resize(buffer_size);
3623 for (
unsigned int j = 0; j < n_vertices; ++j)
3625 vertices_send_buffers[i][2 * j] =
3626 std::get<0>(vert_to_send_it->second[j]);
3627 vertices_send_buffers[i][2 * j + 1] =
3628 local_to_global_vertex_index[std::get<1>(
3629 vert_to_send_it->second[j])];
3633 ierr = MPI_Isend(vertices_send_buffers[i].data(),
3639 &first_requests[i]);
3644 std::vector<std::vector<types::global_vertex_index>> vertices_recv_buffers(
3645 vertices_to_recv.size());
3646 typename std::map<types::subdomain_id, std::set<unsigned int>>::iterator
3647 vert_to_recv_it = vertices_to_recv.begin(),
3648 vert_to_recv_end = vertices_to_recv.end();
3649 for (
unsigned int i = 0; vert_to_recv_it != vert_to_recv_end;
3650 ++vert_to_recv_it, ++i)
3652 int source = vert_to_recv_it->first;
3653 const unsigned int n_vertices = vert_to_recv_it->second.size();
3654 const int buffer_size = 2 * n_vertices;
3655 vertices_recv_buffers[i].resize(buffer_size);
3658 ierr = MPI_Recv(vertices_recv_buffers[i].data(),
3669 MPI_Waitall(first_requests.size(),
3670 first_requests.data(),
3671 MPI_STATUSES_IGNORE);
3675 std::vector<std::vector<char>> cellids_send_buffers(
3676 vertices_to_send.size());
3677 std::vector<MPI_Request> second_requests(vertices_to_send.size());
3678 vert_to_send_it = vertices_to_send.begin();
3679 for (
unsigned int i = 0; vert_to_send_it != vert_to_send_end;
3680 ++vert_to_send_it, ++i)
3682 int destination = vert_to_send_it->first;
3683 const unsigned int n_vertices = vert_to_send_it->second.size();
3684 const int buffer_size = max_cellid_size * n_vertices;
3685 cellids_send_buffers[i].resize(buffer_size);
3688 unsigned int pos = 0;
3689 for (
unsigned int j = 0; j < n_vertices; ++j)
3691 std::string cell_id = std::get<2>(vert_to_send_it->second[j]);
3692 for (
unsigned int k = 0; k < max_cellid_size; ++k, ++pos)
3694 if (k < cell_id.size())
3695 cellids_send_buffers[i][pos] = cell_id[k];
3699 cellids_send_buffers[i][pos] =
'-';
3704 ierr = MPI_Isend(cellids_send_buffers[i].data(),
3710 &second_requests[i]);
3715 std::vector<std::vector<char>> cellids_recv_buffers(
3716 vertices_to_recv.size());
3717 vert_to_recv_it = vertices_to_recv.begin();
3718 for (
unsigned int i = 0; vert_to_recv_it != vert_to_recv_end;
3719 ++vert_to_recv_it, ++i)
3721 int source = vert_to_recv_it->first;
3722 const unsigned int n_vertices = vert_to_recv_it->second.size();
3723 const int buffer_size = max_cellid_size * n_vertices;
3724 cellids_recv_buffers[i].resize(buffer_size);
3727 ierr = MPI_Recv(cellids_recv_buffers[i].data(),
3739 vert_to_recv_it = vertices_to_recv.begin();
3740 for (
unsigned int i = 0; vert_to_recv_it != vert_to_recv_end;
3741 ++i, ++vert_to_recv_it)
3743 for (
unsigned int j = 0; j < vert_to_recv_it->second.size(); ++j)
3745 const unsigned int local_pos_recv = vertices_recv_buffers[i][2 * j];
3747 vertices_recv_buffers[i][2 * j + 1];
3748 const std::string cellid_recv(
3749 &cellids_recv_buffers[i][max_cellid_size * j],
3750 &cellids_recv_buffers[i][max_cellid_size * j] + max_cellid_size);
3752 typename std::set<active_cell_iterator>::iterator
3753 cell_set_it = missing_vert_cells.begin(),
3754 end_cell_set = missing_vert_cells.end();
3755 for (; (found ==
false) && (cell_set_it != end_cell_set);
3758 typename std::set<active_cell_iterator>::iterator
3760 vertex_to_cell[(*cell_set_it)->vertex_index(i)].begin(),
3762 vertex_to_cell[(*cell_set_it)->vertex_index(i)].end();
3763 for (; candidate_cell != end_cell; ++candidate_cell)
3765 std::string current_cellid =
3766 (*candidate_cell)->id().to_string();
3767 current_cellid.resize(max_cellid_size,
'-');
3768 if (current_cellid.compare(cellid_recv) == 0)
3770 local_to_global_vertex_index
3771 [(*candidate_cell)->vertex_index(local_pos_recv)] =
3784 MPI_Waitall(second_requests.size(),
3785 second_requests.data(),
3786 MPI_STATUSES_IGNORE);
3789 return local_to_global_vertex_index;
3794 template <
int dim,
int spacedim>
3810 for (
const auto &cell :
triangulation.active_cell_iterators())
3812 const unsigned int index = cell->active_cell_index();
3813 cell_connectivity.
add(index, index);
3814 for (
auto f : cell->face_indices())
3815 if ((cell->at_boundary(f) ==
false) &&
3816 (cell->neighbor(f)->has_children() ==
false))
3818 const unsigned int other_index =
3819 cell->neighbor(f)->active_cell_index();
3820 cell_connectivity.
add(index, other_index);
3821 cell_connectivity.
add(other_index, index);
3828 template <
int dim,
int spacedim>
3834 std::vector<std::vector<unsigned int>> vertex_to_cell(
3836 for (
const auto &cell :
triangulation.active_cell_iterators())
3838 for (
const unsigned int v : cell->vertex_indices())
3839 vertex_to_cell[cell->vertex_index(v)].push_back(
3840 cell->active_cell_index());
3845 for (
const auto &cell :
triangulation.active_cell_iterators())
3847 for (
const unsigned int v : cell->vertex_indices())
3848 for (
unsigned int n = 0;
3849 n < vertex_to_cell[cell->vertex_index(v)].size();
3851 cell_connectivity.
add(cell->active_cell_index(),
3852 vertex_to_cell[cell->vertex_index(v)][n]);
3857 template <
int dim,
int spacedim>
3861 const unsigned int level,
3864 std::vector<std::vector<unsigned int>> vertex_to_cell(
3871 for (
const unsigned int v : cell->vertex_indices())
3872 vertex_to_cell[cell->vertex_index(v)].push_back(cell->index());
3882 for (
const unsigned int v : cell->vertex_indices())
3883 for (
unsigned int n = 0;
3884 n < vertex_to_cell[cell->vertex_index(v)].size();
3886 cell_connectivity.
add(cell->index(),
3887 vertex_to_cell[cell->vertex_index(v)][n]);
3893 template <
int dim,
int spacedim>
3901 ExcMessage(
"Objects of type parallel::distributed::Triangulation "
3902 "are already partitioned implicitly and can not be "
3903 "partitioned again explicitly."));
3905 std::vector<unsigned int> cell_weights;
3915 for (
const auto &cell :
triangulation.active_cell_iterators())
3916 if (cell->is_locally_owned())
3917 cell_weights[cell->active_cell_index()] =
3927 if (
const auto shared_tria =
3931 shared_tria->get_communicator(),
3935 Assert(std::accumulate(cell_weights.begin(),
3937 std::uint64_t(0)) > 0,
3938 ExcMessage(
"The global sum of weights over all active cells "
3939 "is zero. Please verify how you generate weights."));
3951 template <
int dim,
int spacedim>
3954 const std::vector<unsigned int> &cell_weights,
3960 ExcMessage(
"Objects of type parallel::distributed::Triangulation "
3961 "are already partitioned implicitly and can not be "
3962 "partitioned again explicitly."));
3966 if (n_partitions == 1)
3968 for (
const auto &cell :
triangulation.active_cell_iterators())
3969 cell->set_subdomain_id(0);
3983 sp_cell_connectivity.
copy_from(cell_connectivity);
3986 sp_cell_connectivity,
3993 template <
int dim,
int spacedim>
4002 ExcMessage(
"Objects of type parallel::distributed::Triangulation "
4003 "are already partitioned implicitly and can not be "
4004 "partitioned again explicitly."));
4006 std::vector<unsigned int> cell_weights;
4016 for (
const auto &cell :
triangulation.active_cell_iterators() |
4018 cell_weights[cell->active_cell_index()] =
4028 if (
const auto shared_tria =
4032 shared_tria->get_communicator(),
4036 Assert(std::accumulate(cell_weights.begin(),
4038 std::uint64_t(0)) > 0,
4039 ExcMessage(
"The global sum of weights over all active cells "
4040 "is zero. Please verify how you generate weights."));
4046 cell_connection_graph,
4053 template <
int dim,
int spacedim>
4056 const std::vector<unsigned int> &cell_weights,
4063 ExcMessage(
"Objects of type parallel::distributed::Triangulation "
4064 "are already partitioned implicitly and can not be "
4065 "partitioned again explicitly."));
4068 ExcMessage(
"Connectivity graph has wrong size"));
4070 ExcMessage(
"Connectivity graph has wrong size"));
4076 if (n_partitions == 1)
4078 for (
const auto &cell :
triangulation.active_cell_iterators())
4079 cell->set_subdomain_id(0);
4087 std::vector<unsigned int> partition_indices(
triangulation.n_active_cells());
4095 for (
const auto &cell :
triangulation.active_cell_iterators())
4096 cell->set_subdomain_id(partition_indices[cell->active_cell_index()]);
4108 unsigned int & current_proc_idx,
4109 unsigned int & current_cell_idx,
4110 const unsigned int n_active_cells,
4111 const unsigned int n_partitions)
4113 if (cell->is_active())
4115 while (current_cell_idx >=
4116 std::floor(
static_cast<uint_least64_t
>(n_active_cells) *
4117 (current_proc_idx + 1) / n_partitions))
4119 cell->set_subdomain_id(current_proc_idx);
4124 for (
unsigned int n = 0; n < cell->n_children(); ++n)
4134 template <
int dim,
int spacedim>
4138 const bool group_siblings)
4142 ExcMessage(
"Objects of type parallel::distributed::Triangulation "
4143 "are already partitioned implicitly and can not be "
4144 "partitioned again explicitly."));
4152 if (n_partitions == 1)
4154 for (
const auto &cell :
triangulation.active_cell_iterators())
4155 cell->set_subdomain_id(0);
4161 std::vector<types::global_dof_index> coarse_cell_to_p4est_tree_permutation;
4162 std::vector<types::global_dof_index> p4est_tree_to_coarse_cell_permutation;
4168 coarse_cell_to_p4est_tree_permutation.resize(
triangulation.n_cells(0));
4170 coarse_cell_to_p4est_tree_permutation);
4172 p4est_tree_to_coarse_cell_permutation =
4175 unsigned int current_proc_idx = 0;
4176 unsigned int current_cell_idx = 0;
4177 const unsigned int n_active_cells =
triangulation.n_active_cells();
4181 for (
unsigned int idx = 0; idx <
triangulation.n_cells(0); ++idx)
4183 const unsigned int coarse_cell_idx =
4184 p4est_tree_to_coarse_cell_permutation[idx];
4207 for (; cell != endc; ++cell)
4209 if (cell->is_active())
4211 bool all_children_active =
true;
4212 std::map<unsigned int, unsigned int> map_cpu_n_cells;
4213 for (
unsigned int n = 0; n < cell->n_children(); ++n)
4214 if (!cell->child(n)->is_active())
4216 all_children_active =
false;
4220 ++map_cpu_n_cells[cell->child(n)->subdomain_id()];
4222 if (!all_children_active)
4225 unsigned int new_owner = cell->child(0)->subdomain_id();
4226 for (std::map<unsigned int, unsigned int>::iterator it =
4227 map_cpu_n_cells.begin();
4228 it != map_cpu_n_cells.end();
4230 if (it->second > map_cpu_n_cells[new_owner])
4231 new_owner = it->first;
4233 for (
unsigned int n = 0; n < cell->n_children(); ++n)
4234 cell->child(n)->set_subdomain_id(new_owner);
4240 template <
int dim,
int spacedim>
4245 for (
int lvl = n_levels - 1; lvl >= 0; --lvl)
4247 for (
const auto &cell :
triangulation.cell_iterators_on_level(lvl))
4249 if (cell->is_active())
4250 cell->set_level_subdomain_id(cell->subdomain_id());
4253 Assert(cell->child(0)->level_subdomain_id() !=
4256 cell->set_level_subdomain_id(
4257 cell->child(0)->level_subdomain_id());
4269 template <
int dim,
int spacedim>
4274 const std::vector<CellId> & cell_ids,
4275 std::vector<types::subdomain_id> &subdomain_ids)
4277#ifndef DEAL_II_WITH_P4EST
4280 (void)subdomain_ids;
4284 "You are attempting to use a functionality that is only available "
4285 "if deal.II was configured to use p4est, but cmake did not find a "
4286 "valid p4est library."));
4291 for (
const auto &cell_id : cell_ids)
4294 typename ::internal::p4est::types<dim>::quadrant p4est_cell,
4297 ::internal::p4est::init_coarse_quadrant<dim>(p4est_cell);
4298 for (
const auto &child_index : cell_id.get_child_indices())
4300 ::internal::p4est::init_quadrant_children<dim>(
4301 p4est_cell, p4est_children);
4303 p4est_children[
static_cast<unsigned int>(child_index)];
4309 const_cast<typename ::internal::p4est::types<dim>::forest
4311 cell_id.get_coarse_cell_id(),
4318 subdomain_ids.push_back(owner);
4325 template <
int spacedim>
4329 const std::vector<CellId> &,
4330 std::vector<types::subdomain_id> &)
4339 template <
int dim,
int spacedim>
4340 std::vector<types::subdomain_id>
4342 const std::vector<CellId> & cell_ids)
4344 std::vector<types::subdomain_id> subdomain_ids;
4345 subdomain_ids.reserve(cell_ids.size());
4354 *parallel_tria =
dynamic_cast<
4358 internal::get_subdomain_association(*parallel_tria,
4368 const std::vector<types::subdomain_id> &true_subdomain_ids_of_cells =
4369 shared_tria->get_true_subdomain_ids_of_cells();
4371 for (
const auto &cell_id : cell_ids)
4373 const unsigned int active_cell_index =
4374 shared_tria->create_cell_iterator(cell_id)->active_cell_index();
4375 subdomain_ids.push_back(
4376 true_subdomain_ids_of_cells[active_cell_index]);
4383 for (
const auto &cell_id : cell_ids)
4385 subdomain_ids.push_back(
4386 triangulation.create_cell_iterator(cell_id)->subdomain_id());
4390 return subdomain_ids;
4395 template <
int dim,
int spacedim>
4398 std::vector<types::subdomain_id> & subdomain)
4403 for (
const auto &cell :
triangulation.active_cell_iterators())
4404 subdomain[cell->active_cell_index()] = cell->subdomain_id();
4409 template <
int dim,
int spacedim>
4415 unsigned int count = 0;
4416 for (
const auto &cell :
triangulation.active_cell_iterators())
4417 if (cell->subdomain_id() == subdomain)
4425 template <
int dim,
int spacedim>
4430 std::vector<bool> locally_owned_vertices =
4437 if (
const auto *tr =
dynamic_cast<
4440 for (
const auto &cell :
triangulation.active_cell_iterators())
4441 if (cell->is_artificial() ||
4442 (cell->is_ghost() &&
4443 (cell->subdomain_id() < tr->locally_owned_subdomain())))
4444 for (
const unsigned int v : cell->vertex_indices())
4445 locally_owned_vertices[cell->vertex_index(v)] =
false;
4447 return locally_owned_vertices;
4452 template <
int dim,
int spacedim>
4457 double min_diameter = std::numeric_limits<double>::max();
4458 for (
const auto &cell :
triangulation.active_cell_iterators())
4459 if (!cell->is_artificial())
4460 min_diameter =
std::min(min_diameter, cell->diameter(mapping));
4462 double global_min_diameter = 0;
4464#ifdef DEAL_II_WITH_MPI
4468 global_min_diameter =
4472 global_min_diameter = min_diameter;
4474 return global_min_diameter;
4479 template <
int dim,
int spacedim>
4484 double max_diameter = 0.;
4485 for (
const auto &cell :
triangulation.active_cell_iterators())
4486 if (!cell->is_artificial())
4487 max_diameter =
std::max(max_diameter, cell->diameter(mapping));
4489 double global_max_diameter = 0;
4491#ifdef DEAL_II_WITH_MPI
4495 global_max_diameter =
4499 global_max_diameter = max_diameter;
4501 return global_max_diameter;
4508 namespace FixUpDistortedChildCells
4531 template <
typename Iterator,
int spacedim>
4536 const unsigned int structdim =
4537 Iterator::AccessorType::structure_dimension;
4538 Assert(spacedim == Iterator::AccessorType::dimension,
4544 Assert(object->refinement_case() ==
4552 Tensor<spacedim - structdim, spacedim>
4555 for (
const unsigned int i :
object->vertex_indices())
4556 parent_vertices[i] = object->vertex(i);
4559 parent_vertices, parent_alternating_forms);
4561 const Tensor<spacedim - structdim, spacedim>
4562 average_parent_alternating_form =
4563 std::accumulate(parent_alternating_forms,
4564 parent_alternating_forms +
4578 Tensor<spacedim - structdim, spacedim> child_alternating_forms
4582 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4583 for (
const unsigned int i :
object->child(c)->vertex_indices())
4584 child_vertices[c][i] = object->child(c)->vertex(i);
4592 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4594 1] = object_mid_point;
4596 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4598 child_vertices[c], child_alternating_forms[c]);
4610 double objective = 0;
4611 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4612 for (
const unsigned int i :
object->child(c)->vertex_indices())
4614 (child_alternating_forms[c][i] -
4615 average_parent_alternating_form /
std::pow(2., 1. * structdim))
4627 template <
typename Iterator>
4630 const unsigned int f,
4631 std::integral_constant<int, 1>)
4633 return object->vertex(f);
4643 template <
typename Iterator>
4646 const unsigned int f,
4647 std::integral_constant<int, 2>)
4649 return object->line(f)->center();
4659 template <
typename Iterator>
4662 const unsigned int f,
4663 std::integral_constant<int, 3>)
4665 return object->face(f)->center();
4692 template <
typename Iterator>
4696 const unsigned int structdim =
4697 Iterator::AccessorType::structure_dimension;
4699 double diameter =
object->diameter();
4700 for (
const unsigned int f :
object->face_indices())
4701 for (
unsigned int e = f + 1; e <
object->n_faces(); ++e)
4706 std::integral_constant<int, structdim>())
4708 object, e, std::integral_constant<int, structdim>())));
4719 template <
typename Iterator>
4723 const unsigned int structdim =
4724 Iterator::AccessorType::structure_dimension;
4725 const unsigned int spacedim = Iterator::AccessorType::space_dimension;
4732 Assert(object->refinement_case() ==
4742 unsigned int iteration = 0;
4747 double initial_delta = 0;
4754 const double step_length =
diameter / 4 / (iteration + 1);
4759 for (
unsigned int d = 0; d < spacedim; ++d)
4761 const double eps = step_length / 10;
4775 if (gradient.norm() == 0)
4784 std::min(2 * current_value / (gradient * gradient),
4785 step_length / gradient.norm()) *
4790 const double previous_value = current_value;
4794 initial_delta = (previous_value - current_value);
4797 if ((iteration >= 1) &&
4798 ((previous_value - current_value < 0) ||
4799 (std::fabs(previous_value - current_value) <
4800 0.001 * initial_delta)))
4805 while (iteration < 20);
4821 double old_min_product, new_min_product;
4826 parent_vertices[i] = object->vertex(i);
4828 Tensor<spacedim - structdim, spacedim>
4831 parent_vertices, parent_alternating_forms);
4837 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4838 for (
const unsigned int i :
object->child(c)->vertex_indices())
4839 child_vertices[c][i] = object->child(c)->vertex(i);
4841 Tensor<spacedim - structdim, spacedim> child_alternating_forms
4845 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4847 child_vertices[c], child_alternating_forms[c]);
4850 child_alternating_forms[0][0] * parent_alternating_forms[0];
4851 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4852 for (
const unsigned int i :
object->child(c)->vertex_indices())
4853 for (
const unsigned int j :
object->vertex_indices())
4854 old_min_product = std::min<double>(old_min_product,
4855 child_alternating_forms[c][i] *
4856 parent_alternating_forms[j]);
4864 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4866 1] = object_mid_point;
4868 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4870 child_vertices[c], child_alternating_forms[c]);
4873 child_alternating_forms[0][0] * parent_alternating_forms[0];
4874 for (
unsigned int c = 0; c <
object->n_children(); ++c)
4875 for (
const unsigned int i :
object->child(c)->vertex_indices())
4876 for (
const unsigned int j :
object->vertex_indices())
4877 new_min_product = std::min<double>(new_min_product,
4878 child_alternating_forms[c][i] *
4879 parent_alternating_forms[j]);
4887 if (new_min_product >= old_min_product)
4888 object->child(0)->vertex(
4895 return (
std::max(new_min_product, old_min_product) > 0);
4901 template <
int dim,
int spacedim>
4904 const typename ::Triangulation<dim, spacedim>::cell_iterator
4906 std::integral_constant<int, dim>,
4907 std::integral_constant<int, spacedim>)
4917 for (
auto f : cell->face_indices())
4920 Assert(cell->face(f)->refinement_case() ==
4924 bool subface_is_more_refined =
false;
4925 for (
unsigned int g = 0;
4926 g < GeometryInfo<dim>::max_children_per_face;
4928 if (cell->face(f)->child(g)->has_children())
4930 subface_is_more_refined =
true;
4934 if (subface_is_more_refined ==
true)
4945 template <
int dim,
int spacedim>
4953 dim != 1 && spacedim != 1,
4954 "This function is only valid when dim != 1 or spacedim != 1.");
4958 for (
typename std::list<
4967 Assert(!cell->is_active(),
4969 "This function is only valid for a list of cells that "
4970 "have children (i.e., no cell in the list may be active)."));
4974 std::integral_constant<int, dim>(),
4975 std::integral_constant<int, spacedim>());
4982 return unfixable_subset;
4987 template <
int dim,
int spacedim>
4990 const bool reset_boundary_ids)
4993 std::vector<types::manifold_id> dst_manifold_ids(src_boundary_ids.size());
4994 auto m_it = dst_manifold_ids.begin();
4995 for (
const auto b : src_boundary_ids)
5000 const std::vector<types::boundary_id> reset_boundary_id =
5001 reset_boundary_ids ?
5002 std::vector<types::boundary_id>(src_boundary_ids.size(), 0) :
5012 template <
int dim,
int spacedim>
5015 const std::vector<types::boundary_id> &src_boundary_ids,
5016 const std::vector<types::manifold_id> &dst_manifold_ids,
5018 const std::vector<types::boundary_id> &reset_boundary_ids_)
5021 const auto reset_boundary_ids =
5022 reset_boundary_ids_.size() ? reset_boundary_ids_ : src_boundary_ids;
5031 for (
auto f : cell->face_indices())
5032 if (cell->face(f)->at_boundary())
5033 for (
unsigned int e = 0; e < cell->face(f)->n_lines(); ++e)
5035 const auto bid = cell->face(f)->line(e)->boundary_id();
5036 const unsigned int ind = std::find(src_boundary_ids.begin(),
5037 src_boundary_ids.end(),
5039 src_boundary_ids.begin();
5040 if (ind < src_boundary_ids.size())
5041 cell->face(f)->line(e)->set_manifold_id(
5042 dst_manifold_ids[ind]);
5047 for (
auto f : cell->face_indices())
5048 if (cell->face(f)->at_boundary())
5050 const auto bid = cell->face(f)->boundary_id();
5051 const unsigned int ind =
5052 std::find(src_boundary_ids.begin(), src_boundary_ids.end(), bid) -
5053 src_boundary_ids.begin();
5055 if (ind < src_boundary_ids.size())
5058 cell->face(f)->set_manifold_id(dst_manifold_ids[ind]);
5060 cell->face(f)->set_boundary_id(reset_boundary_ids[ind]);
5064 for (
unsigned int e = 0; e < cell->face(f)->n_lines(); ++e)
5066 const auto bid = cell->face(f)->line(e)->boundary_id();
5067 const unsigned int ind = std::find(src_boundary_ids.begin(),
5068 src_boundary_ids.end(),
5070 src_boundary_ids.begin();
5071 if (ind < src_boundary_ids.size())
5072 cell->face(f)->line(e)->set_boundary_id(
5073 reset_boundary_ids[ind]);
5079 template <
int dim,
int spacedim>
5082 const bool compute_face_ids)
5088 for (; cell != endc; ++cell)
5090 cell->set_manifold_id(cell->material_id());
5091 if (compute_face_ids ==
true)
5093 for (
auto f : cell->face_indices())
5095 if (cell->at_boundary(f) ==
false)
5096 cell->face(f)->set_manifold_id(
5098 cell->neighbor(f)->material_id()));
5100 cell->face(f)->set_manifold_id(cell->material_id());
5107 template <
int dim,
int spacedim>
5112 const std::set<types::manifold_id> &)> &disambiguation_function,
5113 bool overwrite_only_flat_manifold_ids)
5118 const unsigned int n_subobjects =
5122 std::vector<std::set<types::manifold_id>> manifold_ids(n_subobjects + 1);
5123 std::vector<unsigned int> backup;
5127 unsigned next_index = 1;
5131 for (
unsigned int l = 0; l < cell->n_lines(); ++l)
5133 if (cell->line(l)->user_index() == 0)
5136 manifold_ids[next_index].insert(cell->manifold_id());
5137 cell->line(l)->set_user_index(next_index++);
5140 manifold_ids[cell->line(l)->user_index()].insert(
5141 cell->manifold_id());
5144 for (
unsigned int l = 0; l < cell->n_faces(); ++l)
5146 if (cell->quad(l)->user_index() == 0)
5149 manifold_ids[next_index].insert(cell->manifold_id());
5150 cell->quad(l)->set_user_index(next_index++);
5153 manifold_ids[cell->quad(l)->user_index()].insert(
5154 cell->manifold_id());
5160 for (
unsigned int l = 0; l < cell->n_lines(); ++l)
5162 const auto id = cell->line(l)->user_index();
5166 if (cell->line(l)->manifold_id() ==
5168 overwrite_only_flat_manifold_ids ==
false)
5169 cell->line(l)->set_manifold_id(
5170 disambiguation_function(manifold_ids[
id]));
5171 cell->line(l)->set_user_index(0);
5175 for (
unsigned int l = 0; l < cell->n_faces(); ++l)
5177 const auto id = cell->quad(l)->user_index();
5181 if (cell->quad(l)->manifold_id() ==
5183 overwrite_only_flat_manifold_ids ==
false)
5184 cell->quad(l)->set_manifold_id(
5185 disambiguation_function(manifold_ids[
id]));
5186 cell->quad(l)->set_user_index(0);
5195 template <
int dim,
int spacedim>
5196 std::pair<unsigned int, double>
5200 double max_ratio = 1;
5201 unsigned int index = 0;
5203 for (
unsigned int i = 0; i < dim; ++i)
5204 for (
unsigned int j = i + 1; j < dim; ++j)
5206 unsigned int ax = i % dim;
5207 unsigned int next_ax = j % dim;
5210 cell->extent_in_direction(ax) / cell->extent_in_direction(next_ax);
5212 if (ratio > max_ratio)
5217 else if (1.0 / ratio > max_ratio)
5219 max_ratio = 1.0 / ratio;
5223 return std::make_pair(index, max_ratio);
5227 template <
int dim,
int spacedim>
5230 const bool isotropic,
5231 const unsigned int max_iterations)
5233 unsigned int iter = 0;
5234 bool continue_refinement =
true;
5236 while (continue_refinement && (iter < max_iterations))
5240 continue_refinement =
false;
5243 for (
const unsigned int j : cell->face_indices())
5244 if (cell->at_boundary(j) ==
false &&
5245 cell->neighbor(j)->has_children())
5249 cell->set_refine_flag();
5250 continue_refinement =
true;
5253 continue_refinement |= cell->flag_for_face_refinement(j);
5260 template <
int dim,
int spacedim>
5263 const double max_ratio,
5264 const unsigned int max_iterations)
5266 unsigned int iter = 0;
5267 bool continue_refinement =
true;
5269 while (continue_refinement && (iter < max_iterations))
5272 continue_refinement =
false;
5275 std::pair<unsigned int, double> info =
5276 GridTools::get_longest_direction<dim, spacedim>(cell);
5277 if (info.second > max_ratio)
5279 cell->set_refine_flag(
5281 continue_refinement =
true;
5289 template <
int dim,
int spacedim>
5292 const double limit_angle_fraction)
5300 "have hanging nodes."));
5304 bool has_cells_with_more_than_dim_faces_on_boundary =
true;
5305 bool has_cells_with_dim_faces_on_boundary =
false;
5307 unsigned int refinement_cycles = 0;
5309 while (has_cells_with_more_than_dim_faces_on_boundary)
5311 has_cells_with_more_than_dim_faces_on_boundary =
false;
5315 unsigned int boundary_face_counter = 0;
5316 for (
auto f : cell->face_indices())
5317 if (cell->face(f)->at_boundary())
5318 boundary_face_counter++;
5319 if (boundary_face_counter > dim)
5321 has_cells_with_more_than_dim_faces_on_boundary =
true;
5324 else if (boundary_face_counter == dim)
5325 has_cells_with_dim_faces_on_boundary =
true;
5327 if (has_cells_with_more_than_dim_faces_on_boundary)
5330 refinement_cycles++;
5334 if (has_cells_with_dim_faces_on_boundary)
5337 refinement_cycles++;
5341 while (refinement_cycles > 0)
5344 cell->set_coarsen_flag();
5346 refinement_cycles--;
5356 std::vector<CellData<dim>> cells_to_add;
5360 const unsigned int v0 = 0,
v1 = 1, v2 = (dim > 1 ? 2 : 0),
5361 v3 = (dim > 1 ? 3 : 0);
5365 double angle_fraction = 0;
5371 p0[spacedim > 1 ? 1 : 0] = 1;
5375 if (cell->face(
v0)->at_boundary() && cell->face(v3)->at_boundary())
5377 p0 = cell->vertex(
v0) - cell->vertex(v2);
5378 p1 = cell->vertex(v3) - cell->vertex(v2);
5379 vertex_at_corner = v2;
5381 else if (cell->face(v3)->at_boundary() &&
5382 cell->face(
v1)->at_boundary())
5384 p0 = cell->vertex(v2) - cell->vertex(v3);
5385 p1 = cell->vertex(
v1) - cell->vertex(v3);
5386 vertex_at_corner = v3;
5388 else if (cell->face(1)->at_boundary() &&
5389 cell->face(2)->at_boundary())
5391 p0 = cell->vertex(
v0) - cell->vertex(
v1);
5392 p1 = cell->vertex(v3) - cell->vertex(
v1);
5393 vertex_at_corner =
v1;
5395 else if (cell->face(2)->at_boundary() &&
5396 cell->face(0)->at_boundary())
5398 p0 = cell->vertex(v2) - cell->vertex(
v0);
5399 p1 = cell->vertex(
v1) - cell->vertex(
v0);
5400 vertex_at_corner =
v0;
5404 angle_fraction = std::acos(p0 * p1) /
numbers::PI;
5411 if (angle_fraction > limit_angle_fraction)
5413 auto flags_removal = [&](
unsigned int f1,
5416 unsigned int n2) ->
void {
5417 cells_to_remove[cell->active_cell_index()] =
true;
5418 cells_to_remove[cell->neighbor(n1)->active_cell_index()] =
true;
5419 cells_to_remove[cell->neighbor(n2)->active_cell_index()] =
true;
5421 faces_to_remove[cell->face(f1)->index()] =
true;
5422 faces_to_remove[cell->face(f2)->index()] =
true;
5424 faces_to_remove[cell->neighbor(n1)->face(f1)->index()] =
true;
5425 faces_to_remove[cell->neighbor(n2)->face(f2)->index()] =
true;
5428 auto cell_creation = [&](
const unsigned int vv0,
5429 const unsigned int vv1,
5430 const unsigned int f0,
5431 const unsigned int f1,
5433 const unsigned int n0,
5434 const unsigned int v0n0,
5435 const unsigned int v1n0,
5437 const unsigned int n1,
5438 const unsigned int v0n1,
5439 const unsigned int v1n1) {
5445 c1.
vertices[v2] = cell->neighbor(n0)->vertex_index(v0n0);
5446 c1.
vertices[v3] = cell->neighbor(n0)->vertex_index(v1n0);
5452 c2.
vertices[
v1] = cell->neighbor(n1)->vertex_index(v0n1);
5453 c2.
vertices[v2] = cell->vertex_index(vv1);
5454 c2.
vertices[v3] = cell->neighbor(n1)->vertex_index(v1n1);
5459 l1.
vertices[0] = cell->vertex_index(vv0);
5460 l1.
vertices[1] = cell->neighbor(n0)->vertex_index(v0n0);
5466 l2.
vertices[0] = cell->vertex_index(vv0);
5467 l2.
vertices[1] = cell->neighbor(n1)->vertex_index(v0n1);
5473 cells_to_add.push_back(c1);
5474 cells_to_add.push_back(c2);
5479 switch (vertex_at_corner)
5482 flags_removal(0, 2, 3, 1);
5483 cell_creation(0, 3, 0, 2, 3, 2, 3, 1, 1, 3);
5486 flags_removal(1, 2, 3, 0);
5487 cell_creation(1, 2, 2, 1, 0, 0, 2, 3, 3, 2);
5490 flags_removal(3, 0, 1, 2);
5491 cell_creation(2, 1, 3, 0, 1, 3, 1, 2, 0, 1);
5494 flags_removal(3, 1, 0, 2);
5495 cell_creation(3, 0, 1, 3, 2, 1, 0, 0, 2, 0);
5508 if (cells_to_add.size() == 0)
5510 while (refinement_cycles > 0)
5513 cell->set_coarsen_flag();
5515 refinement_cycles--;
5523 if (cells_to_remove[cell->active_cell_index()] ==
false)
5526 for (
const unsigned int v : cell->vertex_indices())
5527 c.
vertices[v] = cell->vertex_index(v);
5530 cells_to_add.push_back(c);
5538 for (; face != endf; ++face)
5539 if ((face->at_boundary() ||
5541 faces_to_remove[face->index()] ==
false)
5543 for (
unsigned int l = 0; l < face->n_lines(); ++l)
5548 for (
const unsigned int v : face->vertex_indices())
5549 line.
vertices[v] = face->vertex_index(v);
5555 for (
const unsigned int v : face->line(l)->vertex_indices())
5556 line.
vertices[v] = face->line(l)->vertex_index(v);
5565 for (
const unsigned int v : face->vertex_indices())
5566 quad.
vertices[v] = face->vertex_index(v);
5574 subcelldata_to_add);
5579 std::map<types::manifold_id, std::unique_ptr<Manifold<dim, spacedim>>>
5582 for (
const auto manifold_id : manifold_ids)
5591 for (
const auto manifold_id : manifold_ids)
5598 template <
int dim,
int spacedim>
5601 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
5602 std::vector<std::vector<Point<dim>>>,
5603 std::vector<std::vector<unsigned int>>>
5615 auto &cells = std::get<0>(cqmp);
5616 auto &qpoints = std::get<1>(cqmp);
5617 auto &maps = std::get<2>(cqmp);
5619 return std::make_tuple(std::move(cells),
5626 template <
int dim,
int spacedim>
5629 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
5630 std::vector<std::vector<Point<dim>>>,
5631 std::vector<std::vector<unsigned int>>,
5632 std::vector<unsigned int>>
5642 Assert((dim == spacedim),
5643 ExcMessage(
"Only implemented for dim==spacedim."));
5652 const unsigned int np = points.size();
5654 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>
5656 std::vector<std::vector<Point<dim>>> qpoints_out;
5657 std::vector<std::vector<unsigned int>> maps_out;
5658 std::vector<unsigned int> missing_points_out;
5662 return std::make_tuple(std::move(cells_out),
5663 std::move(qpoints_out),
5664 std::move(maps_out),
5665 std::move(missing_points_out));
5673 std::vector<std::pair<Point<spacedim>,
unsigned int>> points_and_ids(np);
5674 for (
unsigned int i = 0; i < np; ++i)
5675 points_and_ids[i] = std::make_pair(points[i], i);
5676 const auto p_tree =
pack_rtree(points_and_ids);
5679 std::vector<bool> found_points(points.size(),
false);
5682 const auto already_found = [&found_points](
const auto &id) {
5684 return found_points[
id.second];
5690 const auto store_cell_point_and_id =
5694 const unsigned int &id) {
5695 const auto it = std::find(cells_out.rbegin(), cells_out.rend(), cell);
5696 if (it != cells_out.rend())
5698 const auto cell_id =
5699 (cells_out.size() - 1 - (it - cells_out.rbegin()));
5700 qpoints_out[cell_id].emplace_back(ref_point);
5701 maps_out[cell_id].emplace_back(
id);
5705 cells_out.emplace_back(cell);
5706 qpoints_out.emplace_back(std::vector<
Point<dim>>({ref_point}));
5707 maps_out.emplace_back(std::vector<unsigned int>({
id}));
5712 const auto check_all_points_within_box = [&](
const auto &leaf) {
5713 const double relative_tolerance = 1e-12;
5716 const auto &cell_hint = leaf.second;
5718 for (
const auto &point_and_id :
5719 p_tree | bgi::adaptors::queried(!bgi::satisfies(already_found) &&
5720 bgi::intersects(box)))
5722 const auto id = point_and_id.second;
5723 const auto cell_and_ref =
5727 const auto &cell = cell_and_ref.first;
5728 const auto &ref_point = cell_and_ref.second;
5731 store_cell_point_and_id(cell, ref_point,
id);
5733 missing_points_out.emplace_back(
id);
5736 found_points[id] =
true;
5742 check_all_points_within_box(
5743 std::make_pair(mapping.get_bounding_box(cell_hint), cell_hint));
5746 for (
unsigned int i = 0; i < np; ++i)
5747 if (found_points[i] ==
false)
5750 const auto leaf = b_tree.qbegin(bgi::nearest(points[i], 1));
5752 if (leaf != b_tree.qend())
5753 check_all_points_within_box(*leaf);
5761 for (
unsigned int i = 0; i < np; ++i)
5762 if (found_points[i] ==
false)
5763 missing_points_out.emplace_back(i);
5770 unsigned int c = cells_out.size();
5771 unsigned int qps = 0;
5777 for (
unsigned int n = 0; n < c; ++n)
5780 qps += qpoints_out[n].size();
5783 Assert(qps + missing_points_out.size() == np,
5787 return std::make_tuple(std::move(cells_out),
5788 std::move(qpoints_out),
5789 std::move(maps_out),
5790 std::move(missing_points_out));
5795 template <
int dim,
int spacedim>
5798 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
5799 std::vector<std::vector<Point<dim>>>,
5800 std::vector<std::vector<unsigned int>>,
5801 std::vector<std::vector<Point<spacedim>>>,
5802 std::vector<std::vector<unsigned int>>>
5810 const double tolerance,
5811 const std::vector<bool> & marked_vertices,
5812 const bool enforce_unique_mapping)
5822 enforce_unique_mapping)
5827 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
5828 std::vector<std::vector<Point<dim>>>,
5829 std::vector<std::vector<unsigned int>>,
5830 std::vector<std::vector<Point<spacedim>>>,
5831 std::vector<std::vector<unsigned int>>>
5834 std::pair<int, int> dummy{-1, -1};
5836 for (
unsigned int i = 0; i < all.size(); ++i)
5838 if (dummy != std::get<0>(all[i]))
5840 std::get<0>(result).push_back(
5843 std::get<0>(all[i]).
first,
5844 std::get<0>(all[i]).
second});
5846 const unsigned int new_size = std::get<0>(result).size();
5848 std::get<1>(result).resize(new_size);
5849 std::get<2>(result).resize(new_size);
5850 std::get<3>(result).resize(new_size);
5851 std::get<4>(result).resize(new_size);
5853 dummy = std::get<0>(all[i]);
5856 std::get<1>(result).back().push_back(
5857 std::get<3>(all[i]));
5858 std::get<2>(result).back().push_back(std::get<2>(all[i]));
5859 std::get<3>(result).back().push_back(std::get<4>(all[i]));
5860 std::get<4>(result).back().push_back(std::get<1>(all[i]));
5876 template <
int spacedim,
typename T>
5877 std::tuple<std::vector<unsigned int>,
5878 std::vector<unsigned int>,
5879 std::vector<unsigned int>>
5883 const std::vector<T> & entities,
5884 const double tolerance)
5886 std::vector<std::vector<BoundingBox<spacedim>>> global_bboxes_temp;
5887 auto *global_bboxes_to_be_used = &global_bboxes;
5889 if (global_bboxes.size() == 1)
5891 global_bboxes_temp =
5893 global_bboxes_to_be_used = &global_bboxes_temp;
5896 std::vector<std::pair<unsigned int, unsigned int>> ranks_and_indices;
5897 ranks_and_indices.reserve(entities.size());
5902 const auto is_valid = [](
const auto &bb) {
5903 for (
unsigned int i = 0; i < spacedim; ++i)
5904 if (bb.get_boundary_points().first[i] >
5905 bb.get_boundary_points().second[i])
5912 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>>
5915 for (
unsigned rank = 0; rank < global_bboxes_to_be_used->size();
5917 for (
const auto &box : (*global_bboxes_to_be_used)[rank])
5919 boxes_and_ranks.emplace_back(box, rank);
5922 const auto tree =
pack_rtree(boxes_and_ranks);
5925 for (
unsigned int i = 0; i < entities.size(); ++i)
5932 std::set<unsigned int> my_ranks;
5934 for (
const auto &box_and_rank :
5935 tree | boost::geometry::index::adaptors::queried(
5936 boost::geometry::index::intersects(bb)))
5937 my_ranks.insert(box_and_rank.second);
5939 for (
const auto rank : my_ranks)
5940 ranks_and_indices.emplace_back(rank, i);
5949 std::sort(ranks_and_indices.begin(), ranks_and_indices.end());
5951 std::vector<unsigned int> ranks;
5952 std::vector<unsigned int> ptr;
5953 std::vector<unsigned int> indices;
5957 for (
const std::pair<unsigned int, unsigned int> &i : ranks_and_indices)
5959 if (current_rank != i.first)
5961 current_rank = i.first;
5962 ranks.push_back(current_rank);
5963 ptr.push_back(indices.size());
5966 indices.push_back(i.second);
5968 ptr.push_back(indices.size());
5970 return {std::move(ranks), std::move(ptr), std::move(indices)};
5975 template <
int dim,
int spacedim>
5977 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
5983 const std::vector<bool> &marked_vertices,
5984 const double tolerance,
5985 const bool enforce_unique_mapping)
5988 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
5990 locally_owned_active_cells_around_point;
6007 cell_hint = first_cell.first;
6010 const auto active_cells_around_point =
6018 if (enforce_unique_mapping)
6025 for (
const auto &cell : active_cells_around_point)
6026 lowes_rank =
std::min(lowes_rank, cell.first->subdomain_id());
6028 if (lowes_rank != my_rank)
6032 locally_owned_active_cells_around_point.reserve(
6033 active_cells_around_point.size());
6035 for (
const auto &cell : active_cells_around_point)
6036 if (cell.first->is_locally_owned())
6037 locally_owned_active_cells_around_point.push_back(cell);
6040 std::sort(locally_owned_active_cells_around_point.begin(),
6041 locally_owned_active_cells_around_point.end(),
6042 [](
const auto &a,
const auto &b) { return a.first < b.first; });
6044 if (enforce_unique_mapping &&
6045 locally_owned_active_cells_around_point.size() > 1)
6047 return {locally_owned_active_cells_around_point.front()};
6049 return locally_owned_active_cells_around_point;
6052 template <
int dim,
int spacedim>
6055 : n_searched_points(
numbers::invalid_unsigned_int)
6058 template <
int dim,
int spacedim>
6066 Assert(recv_components.empty() ||
6067 std::get<1>(*std::max_element(recv_components.begin(),
6068 recv_components.end(),
6069 [](
const auto &a,
const auto &b) {
6070 return std::get<1>(a) <
6072 })) < n_searched_points,
6084 std::sort(send_components.begin(),
6085 send_components.end(),
6086 [&](
const auto &a,
const auto &b) {
6087 if (std::get<1>(a) != std::get<1>(b))
6088 return std::get<1>(a) < std::get<1>(b);
6090 if (std::get<2>(a) != std::get<2>(b))
6091 return std::get<2>(a) < std::get<2>(b);
6093 return std::get<0>(a) < std::get<0>(b);
6098 i < send_components.size();
6101 std::get<5>(send_components[i]) = i;
6103 if (dummy != std::get<1>(send_components[i]))
6105 dummy = std::get<1>(send_components[i]);
6106 send_ranks.push_back(dummy);
6107 send_ptrs.push_back(i);
6110 send_ptrs.push_back(send_components.size());
6114 std::sort(send_components.begin(),
6115 send_components.end(),
6116 [&](
const auto &a,
const auto &b) {
6117 if (std::get<0>(a) != std::get<0>(b))
6118 return std::get<0>(a) < std::get<0>(b);
6120 if (std::get<1>(a) != std::get<1>(b))
6121 return std::get<1>(a) < std::get<1>(b);
6123 if (std::get<2>(a) != std::get<2>(b))
6124 return std::get<2>(a) < std::get<2>(b);
6126 return std::get<5>(a) < std::get<5>(b);
6130 if (recv_components.size() > 0)
6133 std::sort(recv_components.begin(),
6134 recv_components.end(),
6135 [&](
const auto &a,
const auto &b) {
6136 if (std::get<0>(a) != std::get<0>(b))
6137 return std::get<0>(a) < std::get<0>(b);
6139 return std::get<1>(a) < std::get<1>(b);
6144 i < recv_components.size();
6147 std::get<2>(recv_components[i]) = i;
6149 if (dummy != std::get<0>(recv_components[i]))
6151 dummy = std::get<0>(recv_components[i]);
6152 recv_ranks.push_back(dummy);
6153 recv_ptrs.push_back(i);
6156 recv_ptrs.push_back(recv_components.size());
6160 std::sort(recv_components.begin(),
6161 recv_components.end(),
6162 [&](
const auto &a,
const auto &b) {
6163 if (std::get<1>(a) != std::get<1>(b))
6164 return std::get<1>(a) < std::get<1>(b);
6166 if (std::get<0>(a) != std::get<0>(b))
6167 return std::get<0>(a) < std::get<0>(b);
6169 return std::get<2>(a) < std::get<2>(b);
6176 template <
int dim,
int spacedim>
6182 const std::vector<bool> & marked_vertices,
6183 const double tolerance,
6184 const bool perform_handshake,
6185 const bool enforce_unique_mapping)
6196 comm, global_bboxes, points, tolerance);
6198 const auto &potential_owners_ranks = std::get<0>(potential_owners);
6199 const auto &potential_owners_ptrs = std::get<1>(potential_owners);
6200 const auto &potential_owners_indices = std::get<2>(potential_owners);
6204 const auto translate = [&](
const unsigned int other_rank) {
6205 const auto ptr = std::find(potential_owners_ranks.begin(),
6206 potential_owners_ranks.end(),
6211 const auto other_rank_index =
6212 std::distance(potential_owners_ranks.begin(), ptr);
6214 return other_rank_index;
6218 (marked_vertices.size() == 0) ||
6221 "The marked_vertices vector has to be either empty or its size has "
6222 "to equal the number of vertices of the triangulation."));
6224 using RequestType = std::vector<std::pair<unsigned int, Point<spacedim>>>;
6225 using AnswerType = std::vector<unsigned int>;
6231 const bool has_relevant_vertices =
6232 (marked_vertices.size() == 0) ||
6233 (std::find(marked_vertices.begin(), marked_vertices.end(),
true) !=
6234 marked_vertices.end());
6236 const auto create_request = [&](
const unsigned int other_rank) {
6237 const auto other_rank_index = translate(other_rank);
6239 RequestType request;
6240 request.reserve(potential_owners_ptrs[other_rank_index + 1] -
6241 potential_owners_ptrs[other_rank_index]);
6243 for (
unsigned int i = potential_owners_ptrs[other_rank_index];
6244 i < potential_owners_ptrs[other_rank_index + 1];
6246 request.emplace_back(potential_owners_indices[i],
6247 points[potential_owners_indices[i]]);
6252 const auto answer_request =
6253 [&](
const unsigned int &other_rank,
6254 const RequestType & request) -> AnswerType {
6255 AnswerType answer(request.size(), 0);
6257 if (has_relevant_vertices)
6261 for (
unsigned int i = 0; i < request.size(); ++i)
6263 const auto &index_and_point = request[i];
6265 const auto cells_and_reference_positions =
6268 index_and_point.second,
6272 enforce_unique_mapping);
6277 for (
const auto &cell_and_reference_position :
6278 cells_and_reference_positions)
6280 const auto cell = cell_and_reference_position.first;
6281 auto reference_position =
6282 cell_and_reference_position.second;
6286 if (cell->reference_cell().is_hyper_cube())
6287 reference_position =
6289 reference_position);
6291 send_components.emplace_back(
6292 std::pair<int, int>(cell->level(), cell->index()),
6294 index_and_point.first,
6296 index_and_point.second,
6300 answer[i] = cells_and_reference_positions.size();
6304 if (perform_handshake)
6310 const auto process_answer = [&](
const unsigned int other_rank,
6311 const AnswerType & answer) {
6312 if (perform_handshake)
6314 const auto other_rank_index = translate(other_rank);
6316 for (
unsigned int i = 0; i < answer.size(); ++i)
6317 for (
unsigned int j = 0; j < answer[i]; ++j)
6318 recv_components.emplace_back(
6320 potential_owners_indices
6321 [i + potential_owners_ptrs[other_rank_index]],
6326 Utilities::MPI::ConsensusAlgorithms::selector<RequestType, AnswerType>(
6327 potential_owners_ranks,
6340 template <
int structdim,
int spacedim>
6342 DistributedComputePointLocationsInternal<dim, spacedim>
6345 const unsigned int n_points_1D,
6348 const bool consistent_numbering_of_sender_and_receiver)
const
6350 using CellIterator =
6366 for (
auto const &recv_component : recv_components)
6373 std::get<2>(recv_component));
6375 for (
unsigned int i = 0; i < quad.
size(); ++i)
6379 result.recv_components.emplace_back(
6380 std::get<0>(recv_component),
6381 result.recv_components.size(),
6389 result.n_searched_points = result.recv_components.size();
6394 std::map<unsigned int, std::vector<unsigned int>> indices_of_rank;
6395 std::map<unsigned int, unsigned int> counter;
6396 std::set<unsigned int> send_ranks;
6397 if (consistent_numbering_of_sender_and_receiver)
6399 for (
const auto &sc : send_components)
6400 send_ranks.insert(std::get<1>(sc));
6402 for (
const auto rank : send_ranks)
6406 indices_of_rank = communicate_indices(result.recv_components,
6410 for (
const auto &send_component : send_components)
6412 const CellIterator cell(&
tria,
6413 std::get<0>(send_component).
first,
6414 std::get<0>(send_component).
second);
6418 std::get<3>(send_component));
6420 const auto rank = std::get<1>(send_component);
6422 for (
unsigned int q = 0; q < quad.
size(); ++q)
6426 result.send_components.emplace_back(std::make_tuple(
6427 std::get<0>(send_component),
6429 indices_of_rank.empty() ?
6430 result.send_components.size() :
6431 indices_of_rank.at(rank)[counter.at(rank)],
6436 if (!indices_of_rank.empty())
6441 result.finalize_setup();
6448 template <
int structdim,
int spacedim>
6449 std::map<unsigned int, std::vector<unsigned int>>
6452 const std::vector<std::tuple<unsigned int, unsigned int, unsigned int>>
6453 & point_recv_components,
6456#ifndef DEAL_II_WITH_MPI
6458 (void)point_recv_components;
6464 const auto mpi_tag =
6469 std::set<unsigned int> send_ranks;
6470 for (
const auto &sc : send_components)
6471 send_ranks.insert(std::get<1>(sc));
6472 std::set<unsigned int> recv_ranks;
6473 for (
const auto &rc : recv_components)
6474 recv_ranks.insert(std::get<0>(rc));
6476 std::vector<MPI_Request> requests;
6477 requests.reserve(send_ranks.size());
6480 std::map<unsigned int, std::vector<unsigned int>> indices_of_rank;
6481 indices_of_rank[my_rank] = std::vector<unsigned int>();
6484 std::map<unsigned int, std::vector<unsigned int>> send_indices_of_rank;
6485 for (
const auto rank : recv_ranks)
6486 if (rank != my_rank)
6487 send_indices_of_rank[rank] = std::vector<unsigned int>();
6490 for (
const auto &point_recv_component : point_recv_components)
6492 const auto rank = std::get<0>(point_recv_component);
6493 const auto idx = std::get<1>(point_recv_component);
6495 if (rank == my_rank)
6496 indices_of_rank[rank].emplace_back(idx);
6498 send_indices_of_rank[rank].emplace_back(idx);
6502 for (
const auto rank : recv_ranks)
6504 if (rank == my_rank)
6509 requests.push_back(MPI_Request());
6511 const int ierr = MPI_Isend(buffer.data(),
6522 for (
const auto rank : send_ranks)
6524 if (rank == my_rank)
6528 int ierr = MPI_Probe(MPI_ANY_SOURCE, mpi_tag,
comm, &status);
6532 ierr = MPI_Get_count(&status, MPI_CHAR, &message_length);
6535 std::vector<char> buffer(message_length);
6537 ierr = MPI_Recv(buffer.data(),
6546 indices_of_rank[status.MPI_SOURCE] =
6547 Utilities::unpack<std::vector<unsigned int>>(buffer,
false);
6552 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
6555 return indices_of_rank;
6561 template <
int structdim,
int dim,
int spacedim>
6565 const std::vector<std::vector<
Point<spacedim>>> &intersection_requests,
6567 const std::vector<bool> & marked_vertices,
6568 const double tolerance)
6570 using IntersectionRequest = std::vector<Point<spacedim>>;
6572 using IntersectionAnswer =
6575 spacedim>::IntersectionType;
6588 comm, global_bboxes, intersection_requests, tolerance);
6590 const auto &potential_owners_ranks = std::get<0>(potential_owners);
6591 const auto &potential_owners_ptrs = std::get<1>(potential_owners);
6592 const auto &potential_owners_indices = std::get<2>(potential_owners);
6594 const auto translate = [&](
const unsigned int other_rank) {
6595 const auto ptr = std::find(potential_owners_ranks.begin(),
6596 potential_owners_ranks.end(),
6601 const auto other_rank_index =
6602 std::distance(potential_owners_ranks.begin(), ptr);
6604 return other_rank_index;
6608 (marked_vertices.size() == 0) ||
6611 "The marked_vertices vector has to be either empty or its size has "
6612 "to equal the number of vertices of the triangulation."));
6618 const bool has_relevant_vertices =
6619 (marked_vertices.size() == 0) ||
6620 (std::find(marked_vertices.begin(), marked_vertices.end(),
true) !=
6621 marked_vertices.end());
6627 std::vector<std::pair<unsigned int, IntersectionRequest>>;
6631 std::vector<std::pair<unsigned int, IntersectionAnswer>>;
6633 const auto create_request = [&](
const unsigned int other_rank) {
6634 const auto other_rank_index = translate(other_rank);
6636 RequestType request;
6637 request.reserve(potential_owners_ptrs[other_rank_index + 1] -
6638 potential_owners_ptrs[other_rank_index]);
6640 for (
unsigned int i = potential_owners_ptrs[other_rank_index];
6641 i < potential_owners_ptrs[other_rank_index + 1];
6643 request.emplace_back(
6644 potential_owners_indices[i],
6645 intersection_requests[potential_owners_indices[i]]);
6653 const auto construct_locally_owned_cell_bounding_boxes_rtree =
6654 [&cache](
const std::vector<bool> &marked_verts) {
6655 const auto cell_marked = [&marked_verts](
const auto &cell) {
6656 for (
const unsigned int v : cell->vertex_indices())
6657 if (marked_verts[cell->vertex_index(v)])
6662 const auto &boxes_and_cells =
6665 if (marked_verts.size() == 0)
6666 return boxes_and_cells;
6668 std::vector<std::pair<
6671 potential_boxes_and_cells;
6673 for (
const auto &box_and_cell : boxes_and_cells)
6674 if (cell_marked(box_and_cell.second))
6675 potential_boxes_and_cells.emplace_back(box_and_cell);
6677 return pack_rtree(potential_boxes_and_cells);
6682 std::pair<BoundingBox<spacedim>,
6686 const auto answer_request =
6687 [&](
const unsigned int &other_rank,
6688 const RequestType & request) -> AnswerType {
6691 if (has_relevant_vertices)
6693 if (marked_cell_tree.empty())
6696 construct_locally_owned_cell_bounding_boxes_rtree(
6701 for (
unsigned int i = 0; i < request.size(); ++i)
6707 for (
const auto &box_cell :
6709 boost::geometry::index::adaptors::queried(
6710 boost::geometry::index::intersects(bb)))
6712#ifdef DEAL_II_WITH_CGAL
6713 const auto &cell = box_cell.second;
6714 const auto &request_index = request[i].first;
6715 auto requested_intersection = request[i].second;
6716 CGALWrappers::resort_dealii_vertices_to_cgal_order(
6717 structdim, requested_intersection);
6719 auto const &try_intersection =
6720 CGALWrappers::get_vertices_in_cgal_order(
6723 const auto &found_intersections = CGALWrappers::
6724 compute_intersection_of_cells<dim, structdim, spacedim>(
6725 try_intersection, requested_intersection, tolerance);
6727 if (found_intersections.size() > 0)
6729 for (
const auto &found_intersection :
6730 found_intersections)
6732 answer.emplace_back(request_index,
6733 found_intersection);
6735 send_components.emplace_back(
6736 std::make_pair(cell->level(), cell->index()),
6739 found_intersection);
6754 const auto process_answer = [&](
const unsigned int other_rank,
6755 const AnswerType & answer) {
6756 for (
unsigned int i = 0; i < answer.size(); ++i)
6757 recv_components.emplace_back(other_rank,
6762 Utilities::MPI::ConsensusAlgorithms::selector<RequestType, AnswerType>(
6763 potential_owners_ranks,
6771 std::stable_sort(recv_components.begin(),
6772 recv_components.end(),
6773 [&](
const auto &a,
const auto &b) {
6775 if (std::get<1>(a) != std::get<1>(b))
6776 return std::get<1>(a) < std::get<1>(b);
6779 return std::get<0>(a) < std::get<0>(b);
6784 std::stable_sort(send_components.begin(),
6785 send_components.end(),
6786 [&](
const auto &a,
const auto &b) {
6788 if (std::get<1>(a) != std::get<1>(b))
6789 return std::get<1>(a) < std::get<1>(b);
6792 return std::get<2>(a) < std::get<2>(b);
6796 recv_ptrs.assign(intersection_requests.size() + 1, 0);
6797 for (
const auto &rc : recv_components)
6798 ++recv_ptrs[std::get<1>(rc) + 1];
6799 for (
unsigned int i = 0; i < intersection_requests.size(); ++i)
6800 recv_ptrs[i + 1] += recv_ptrs[i];
6809 template <
int dim,
int spacedim>
6810 std::map<unsigned int, Point<spacedim>>
6814 std::map<unsigned int, Point<spacedim>> result;
6817 if (!cell->is_artificial())
6820 for (
unsigned int i = 0; i < vs.size(); ++i)
6821 result[cell->vertex_index(i)] = vs[i];
6828 template <
int spacedim>
6833 auto id_and_v = std::min_element(
6838 return p1.second.distance(p) < p2.second.distance(p);
6840 return id_and_v->first;
6844 template <
int dim,
int spacedim>
6845 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
6852 const std::vector<bool> &marked_vertices,
6853 const double tolerance)
6858 const auto &vertex_to_cell_centers =
6866 vertex_to_cell_centers,
6869 used_vertices_rtree,
6873 template <
int spacedim>
6874 std::vector<std::vector<BoundingBox<spacedim>>>
6879#ifndef DEAL_II_WITH_MPI
6881 (void)mpi_communicator;
6884 "GridTools::exchange_local_bounding_boxes() requires MPI."));
6888 unsigned int n_bboxes = local_bboxes.size();
6890 int n_local_data = 2 * spacedim * n_bboxes;
6892 std::vector<double> loc_data_array(n_local_data);
6893 for (
unsigned int i = 0; i < n_bboxes; ++i)
6894 for (
unsigned int d = 0; d < spacedim; ++d)
6897 loc_data_array[2 * i * spacedim + d] =
6898 local_bboxes[i].get_boundary_points().first[d];
6899 loc_data_array[2 * i * spacedim + spacedim + d] =
6900 local_bboxes[i].get_boundary_points().second[d];
6907 std::vector<int> size_all_data(n_procs);
6910 int ierr = MPI_Allgather(&n_local_data,
6913 size_all_data.data(),
6921 std::vector<int> rdispls(n_procs);
6923 for (
unsigned int i = 1; i < n_procs; ++i)
6924 rdispls[i] = rdispls[i - 1] + size_all_data[i - 1];
6928 std::vector<double> data_array(rdispls.back() + size_all_data.back());
6930 ierr = MPI_Allgatherv(loc_data_array.data(),
6934 size_all_data.data(),
6941 std::vector<std::vector<BoundingBox<spacedim>>> global_bboxes(n_procs);
6942 unsigned int begin_idx = 0;
6943 for (
unsigned int i = 0; i < n_procs; ++i)
6946 unsigned int n_bbox_i = size_all_data[i] / (spacedim * 2);
6947 global_bboxes[i].resize(n_bbox_i);
6948 for (
unsigned int bbox = 0; bbox < n_bbox_i; ++bbox)
6951 for (
unsigned int d = 0; d < spacedim; ++d)
6953 p1[d] = data_array[begin_idx + 2 * bbox * spacedim + d];
6955 data_array[begin_idx + 2 * bbox * spacedim + spacedim + d];
6958 global_bboxes[i][bbox] = loc_bbox;
6961 begin_idx += size_all_data[i];
6963 return global_bboxes;
6969 template <
int spacedim>
6975#ifndef DEAL_II_WITH_MPI
6976 (void)mpi_communicator;
6978 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>> boxes_index(
6979 local_description.size());
6981 for (
unsigned int i = 0; i < local_description.size(); ++i)
6982 boxes_index[i] = std::make_pair(local_description[i], 0u);
6986 const std::vector<std::vector<BoundingBox<spacedim>>> global_bboxes =
6990 const unsigned int n_procs =
6994 std::vector<unsigned int> bboxes_position(n_procs);
6996 unsigned int tot_bboxes = 0;
6997 for (
const auto &process_bboxes : global_bboxes)
6998 tot_bboxes += process_bboxes.size();
7001 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>>
7003 flat_global_bboxes.reserve(tot_bboxes);
7004 unsigned int process_index = 0;
7005 for (
const auto &process_bboxes : global_bboxes)
7008 std::vector<std::pair<BoundingBox<spacedim>,
unsigned int>>
7009 boxes_and_indices(process_bboxes.size());
7012 for (
unsigned int i = 0; i < process_bboxes.size(); ++i)
7013 boxes_and_indices[i] =
7014 std::make_pair(process_bboxes[i], process_index);
7016 flat_global_bboxes.insert(flat_global_bboxes.end(),
7017 boxes_and_indices.begin(),
7018 boxes_and_indices.end());
7026 flat_global_bboxes.begin(), flat_global_bboxes.end());
7032 template <
int dim,
int spacedim>
7042 static const int lookup_table_2d[2][2] =
7049 static const int lookup_table_3d[2][2][2][4] =
7071 if (pair.first.first->level() != pair.second.first.first->level())
7074 const auto face_a = pair.first.first->face(pair.first.second);
7076 pair.second.first.first->face(pair.second.first.second);
7077 const auto mask = pair.second.second;
7082 for (
unsigned int i = 0; i < face_a->n_vertices(); ++i)
7084 const bool face_orientation = mask[0];
7085 const bool face_flip = mask[1];
7086 const bool face_rotation = mask[2];
7096 j = lookup_table_2d[face_flip][i];
7099 j = lookup_table_3d[face_orientation][face_flip]
7107 const auto vertex_a = face_a->vertex_index(i);
7108 const auto vertex_b = face_b->vertex_index(j);
7109 unsigned int temp =
std::min(vertex_a, vertex_b);
7113 temp =
std::min(temp, it_a->second);
7117 temp =
std::min(temp, it_b->second);
7120 it_a->second = temp;
7125 it_b->second = temp;
7135 if (p.first == p.second)
7137 unsigned int temp = p.second;
7155 template <
int dim,
int spacedim>
7156 std::map<unsigned int, std::set<::types::subdomain_id>>
7175 for (
const auto &cell :
7177 for (
const unsigned int v : cell->vertex_indices())
7178 vertex_of_own_cell[cell->vertex_index(v)] =
true;
7182 std::map<unsigned int, std::set<types::subdomain_id>> result;
7186 if (cell->is_ghost())
7191 for (
const unsigned int v : cell->vertex_indices())
7194 if (vertex_of_own_cell[cell->vertex_index(v)])
7195 result[cell->vertex_index(v)].insert(owner);
7198 auto coinciding_vertex_group =
7200 if (coinciding_vertex_group !=
7202 for (
auto coinciding_vertex :
7204 if (vertex_of_own_cell[coinciding_vertex])
7205 result[coinciding_vertex].insert(owner);
7217 unsigned int n_vertices,
7218 unsigned int n_sub_vertices,
7219 unsigned int n_configurations,
7220 unsigned int n_lines,
7221 unsigned int n_cols,
7222 typename value_type>
7225 const std::array<unsigned int, n_configurations> & cut_line_table,
7228 const std::vector<value_type> & ls_values,
7230 const std::vector<unsigned int> &
mask,
7231 const double iso_level,
7232 const double tolerance,
7235 const bool write_back_cell_data)
7239 constexpr unsigned int X =
static_cast<unsigned int>(-1);
7242 unsigned int configuration = 0;
7243 for (
unsigned int v = 0; v < n_vertices; ++v)
7244 if (ls_values[
mask[v]] < iso_level)
7245 configuration |= (1 << v);
7248 if (cut_line_table[configuration] == 0)
7253 const auto interpolate = [&](
const unsigned int i,
const unsigned int j) {
7254 if (
std::abs(iso_level - ls_values[
mask[i]]) < tolerance)
7255 return points[
mask[i]];
7256 if (
std::abs(iso_level - ls_values[
mask[j]]) < tolerance)
7257 return points[
mask[j]];
7259 return points[
mask[i]];
7261 const double mu = (iso_level - ls_values[
mask[i]]) /
7262 (ls_values[
mask[j]] - ls_values[
mask[i]]);
7265 mu * (points[
mask[j]] - points[
mask[i]]));
7269 std::array<Point<dim>, n_lines> vertex_list_all;
7270 for (
unsigned int l = 0; l < n_lines; ++l)
7271 if (cut_line_table[configuration] & (1 << l))
7272 vertex_list_all[l] =
7273 interpolate(line_to_vertex_table[l][0], line_to_vertex_table[l][1]);
7276 unsigned int local_vertex_count = 0;
7277 std::array<Point<dim>, n_lines> vertex_list_reduced;
7278 std::array<unsigned int, n_lines> local_remap;
7279 std::fill(local_remap.begin(), local_remap.end(), X);
7280 for (
int i = 0; new_line_table[configuration][i] != X; ++i)
7281 if (local_remap[new_line_table[configuration][i]] == X)
7283 vertex_list_reduced[local_vertex_count] =
7284 vertex_list_all[new_line_table[configuration][i]];
7285 local_remap[new_line_table[configuration][i]] = local_vertex_count;
7286 local_vertex_count++;
7290 const unsigned int n_vertices_old =
vertices.size();
7291 for (
unsigned int i = 0; i < local_vertex_count; ++i)
7292 vertices.push_back(vertex_list_reduced[i]);
7295 if (write_back_cell_data && dim > 1)
7297 for (
unsigned int i = 0; new_line_table[configuration][i] != X;
7298 i += n_sub_vertices)
7300 cells.resize(cells.size() + 1);
7301 cells.back().vertices.resize(n_sub_vertices);
7303 for (
unsigned int v = 0; v < n_sub_vertices; ++v)
7304 cells.back().vertices[v] =
7305 local_remap[new_line_table[configuration][i + v]] +
7314 template <
int dim,
typename VectorType>
7318 const unsigned int n_subdivisions,
7319 const double tolerance)
7320 : n_subdivisions(n_subdivisions)
7321 , tolerance(tolerance)
7322 , fe_values(mapping,
7324 create_quadrature_rule(n_subdivisions),
7330 template <
int dim,
typename VectorType>
7333 const unsigned int n_subdivisions)
7335 std::vector<Point<dim>> quadrature_points;
7339 for (
unsigned int i = 0; i <= n_subdivisions; ++i)
7340 quadrature_points.emplace_back(1.0 / n_subdivisions * i);
7344 for (
unsigned int j = 0; j <= n_subdivisions; ++j)
7345 for (
unsigned int i = 0; i <= n_subdivisions; ++i)
7346 quadrature_points.emplace_back(1.0 / n_subdivisions * i,
7347 1.0 / n_subdivisions * j);
7351 for (
unsigned int k = 0; k <= n_subdivisions; ++k)
7352 for (
unsigned int j = 0; j <= n_subdivisions; ++j)
7353 for (
unsigned int i = 0; i <= n_subdivisions; ++i)
7354 quadrature_points.emplace_back(1.0 / n_subdivisions * i,
7355 1.0 / n_subdivisions * j,
7356 1.0 / n_subdivisions * k);
7360 return {quadrature_points};
7365 template <
int dim,
typename VectorType>
7369 const VectorType & ls_vector,
7370 const double iso_level,
7377 "Not implemented for dim==1. Use the alternative process()-function "
7378 "not returning a vector of CellData objects."));
7382 process_cell(cell, ls_vector, iso_level,
vertices, cells);
7385 template <
int dim,
typename VectorType>
7389 const VectorType & ls_vector,
7390 const double iso_level,
7395 process_cell(cell, ls_vector, iso_level,
vertices);
7401 template <
int dim,
typename VectorType>
7405 const VectorType & ls_vector,
7406 const double iso_level,
7413 "Not implemented for dim==1. Use the alternative process_cell()-function "
7414 "not returning a vector of CellData objects."));
7416 std::vector<value_type> ls_values;
7418 fe_values.reinit(cell);
7419 ls_values.resize(fe_values.n_quadrature_points);
7420 fe_values.get_function_values(ls_vector, ls_values);
7422 ls_values, fe_values.get_quadrature_points(), iso_level,
vertices, cells);
7425 template <
int dim,
typename VectorType>
7429 const VectorType & ls_vector,
7430 const double iso_level,
7434 std::vector<
CellData<dim == 1 ? 1 : dim - 1>> dummy_cells;
7436 std::vector<value_type> ls_values;
7438 fe_values.reinit(cell);
7439 ls_values.resize(fe_values.n_quadrature_points);
7440 fe_values.get_function_values(ls_vector, ls_values);
7442 process_cell(ls_values,
7443 fe_values.get_quadrature_points(),
7451 template <
int dim,
typename VectorType>
7454 std::vector<value_type> & ls_values,
7456 const double iso_level,
7459 const bool write_back_cell_data)
const
7461 const unsigned p = n_subdivisions + 1;
7465 for (
unsigned int i = 0; i < n_subdivisions; ++i)
7467 std::vector<unsigned int> mask{i + 0, i + 1};
7470 if (
std::abs(iso_level - ls_values[mask[0]]) < tolerance)
7471 vertices.emplace_back(points[mask[0]]);
7472 else if (
std::abs(iso_level - ls_values[mask[1]]) < tolerance)
7474 if (i + 1 == n_subdivisions)
7475 vertices.emplace_back(points[mask[1]]);
7478 else if (((ls_values[mask[0]] > iso_level) &&
7479 (ls_values[mask[1]] < iso_level)) ||
7480 ((ls_values[mask[0]] < iso_level) &&
7481 (ls_values[mask[1]] > iso_level)))
7484 const double mu = (iso_level - ls_values[mask[0]]) /
7485 (ls_values[mask[1]] - ls_values[mask[0]]);
7488 vertices.emplace_back(points[mask[0]] +
7489 mu * (points[mask[1]] - points[mask[0]]));
7495 for (
unsigned int j = 0; j < n_subdivisions; ++j)
7496 for (
unsigned int i = 0; i < n_subdivisions; ++i)
7498 std::vector<unsigned int> mask{p * (j + 0) + (i + 0),
7499 p * (j + 0) + (i + 1),
7500 p * (j + 1) + (i + 1),
7501 p * (j + 1) + (i + 0)};
7503 process_sub_cell(ls_values,
7509 write_back_cell_data);
7514 for (
unsigned int k = 0; k < n_subdivisions; ++k)
7515 for (
unsigned int j = 0; j < n_subdivisions; ++j)
7516 for (
unsigned int i = 0; i < n_subdivisions; ++i)
7518 std::vector<unsigned int> mask{
7519 p * p * (k + 0) + p * (j + 0) + (i + 0),
7520 p * p * (k + 0) + p * (j + 0) + (i + 1),
7521 p * p * (k + 0) + p * (j + 1) + (i + 1),
7522 p * p * (k + 0) + p * (j + 1) + (i + 0),
7523 p * p * (k + 1) + p * (j + 0) + (i + 0),
7524 p * p * (k + 1) + p * (j + 0) + (i + 1),
7525 p * p * (k + 1) + p * (j + 1) + (i + 1),
7526 p * p * (k + 1) + p * (j + 1) + (i + 0)};
7528 process_sub_cell(ls_values,
7534 write_back_cell_data);
7541 template <
int dim,
typename VectorType>
7544 const std::vector<value_type> & ls_values,
7545 const std::vector<
Point<2>> & points,
7546 const std::vector<unsigned int> &mask,
7547 const double iso_level,
7550 const bool write_back_cell_data)
const
7553 constexpr unsigned int n_vertices = 4;
7554 constexpr unsigned int n_sub_vertices = 2;
7555 constexpr unsigned int n_lines = 4;
7556 constexpr unsigned int n_configurations =
Utilities::pow(2, n_vertices);
7557 constexpr unsigned int X =
static_cast<unsigned int>(-1);
7561 constexpr std::array<unsigned int, n_configurations> cut_line_table = {
7597 {{X, X, X, X, X}}}};
7601 {{{0, 3}}, {{1, 2}}, {{0, 1}}, {{3, 2}}}};
7611 line_to_vertex_table,
7619 write_back_cell_data);
7624 template <
int dim,
typename VectorType>
7627 const std::vector<value_type> & ls_values,
7628 const std::vector<
Point<3>> & points,
7629 const std::vector<unsigned int> &mask,
7630 const double iso_level,
7633 const bool write_back_cell_data)
const
7636 constexpr unsigned int n_vertices = 8;
7637 constexpr unsigned int n_sub_vertices = 3;
7638 constexpr unsigned int n_lines = 12;
7639 constexpr unsigned int n_configurations =
Utilities::pow(2, n_vertices);
7640 constexpr unsigned int X =
static_cast<unsigned int>(-1);
7645 constexpr std::array<unsigned int, n_configurations> cut_line_table = {{
7646 0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905,
7647 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, 0x190, 0x99, 0x393, 0x29a,
7648 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93,
7649 0xf99, 0xe90, 0x230, 0x339, 0x33, 0x13a, 0x636, 0x73f, 0x435, 0x53c,
7650 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, 0x3a0, 0x2a9,
7651 0x1a3, 0xaa, 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6,
7652 0xfaa, 0xea3, 0xda9, 0xca0, 0x460, 0x569, 0x663, 0x76a, 0x66, 0x16f,
7653 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
7654 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff, 0x3f5, 0x2fc, 0xdfc, 0xcf5,
7655 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, 0x650, 0x759, 0x453, 0x55a,
7656 0x256, 0x35f, 0x55, 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53,
7657 0x859, 0x950, 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc,
7658 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, 0x8c0, 0x9c9,
7659 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc, 0x1c5, 0x2cf, 0x3c6,
7660 0x4ca, 0x5c3, 0x6c9, 0x7c0, 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f,
7661 0xf55, 0xe5c, 0x15c, 0x55, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
7662 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5,
7663 0xff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, 0xb60, 0xa69, 0x963, 0x86a,
7664 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66, 0x76a, 0x663,
7665 0x569, 0x460, 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
7666 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa, 0x1a3, 0x2a9, 0x3a0, 0xd30, 0xc39,
7667 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636,
7668 0x13a, 0x33, 0x339, 0x230, 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f,
7669 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99, 0x190,
7670 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605,
7671 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0}};
7677 {{{X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7678 {{0, 8, 3, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7679 {{0, 1, 9, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7680 {{1, 8, 3, 9, 8, 1, X, X, X, X, X, X, X, X, X, X}},
7681 {{1, 2, 10, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7682 {{0, 8, 3, 1, 2, 10, X, X, X, X, X, X, X, X, X, X}},
7683 {{9, 2, 10, 0, 2, 9, X, X, X, X, X, X, X, X, X, X}},
7684 {{2, 8, 3, 2, 10, 8, 10, 9, 8, X, X, X, X, X, X, X}},
7685 {{3, 11, 2, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7686 {{0, 11, 2, 8, 11, 0, X, X, X, X, X, X, X, X, X, X}},
7687 {{1, 9, 0, 2, 3, 11, X, X, X, X, X, X, X, X, X, X}},
7688 {{1, 11, 2, 1, 9, 11, 9, 8, 11, X, X, X, X, X, X, X}},
7689 {{3, 10, 1, 11, 10, 3, X, X, X, X, X, X, X, X, X, X}},
7690 {{0, 10, 1, 0, 8, 10, 8, 11, 10, X, X, X, X, X, X, X}},
7691 {{3, 9, 0, 3, 11, 9, 11, 10, 9, X, X, X, X, X, X, X}},
7692 {{9, 8, 10, 10, 8, 11, X, X, X, X, X, X, X, X, X, X}},
7693 {{4, 7, 8, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7694 {{4, 3, 0, 7, 3, 4, X, X, X, X, X, X, X, X, X, X}},
7695 {{0, 1, 9, 8, 4, 7, X, X, X, X, X, X, X, X, X, X}},
7696 {{4, 1, 9, 4, 7, 1, 7, 3, 1, X, X, X, X, X, X, X}},
7697 {{1, 2, 10, 8, 4, 7, X, X, X, X, X, X, X, X, X, X}},
7698 {{3, 4, 7, 3, 0, 4, 1, 2, 10, X, X, X, X, X, X, X}},
7699 {{9, 2, 10, 9, 0, 2, 8, 4, 7, X, X, X, X, X, X, X}},
7700 {{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, X, X, X, X}},
7701 {{8, 4, 7, 3, 11, 2, X, X, X, X, X, X, X, X, X, X}},
7702 {{11, 4, 7, 11, 2, 4, 2, 0, 4, X, X, X, X, X, X, X}},
7703 {{9, 0, 1, 8, 4, 7, 2, 3, 11, X, X, X, X, X, X, X}},
7704 {{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, X, X, X, X}},
7705 {{3, 10, 1, 3, 11, 10, 7, 8, 4, X, X, X, X, X, X, X}},
7706 {{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, X, X, X, X}},
7707 {{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, X, X, X, X}},
7708 {{4, 7, 11, 4, 11, 9, 9, 11, 10, X, X, X, X, X, X, X}},
7709 {{9, 5, 4, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7710 {{9, 5, 4, 0, 8, 3, X, X, X, X, X, X, X, X, X, X}},
7711 {{0, 5, 4, 1, 5, 0, X, X, X, X, X, X, X, X, X, X}},
7712 {{8, 5, 4, 8, 3, 5, 3, 1, 5, X, X, X, X, X, X, X}},
7713 {{1, 2, 10, 9, 5, 4, X, X, X, X, X, X, X, X, X, X}},
7714 {{3, 0, 8, 1, 2, 10, 4, 9, 5, X, X, X, X, X, X, X}},
7715 {{5, 2, 10, 5, 4, 2, 4, 0, 2, X, X, X, X, X, X, X}},
7716 {{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, X, X, X, X}},
7717 {{9, 5, 4, 2, 3, 11, X, X, X, X, X, X, X, X, X, X}},
7718 {{0, 11, 2, 0, 8, 11, 4, 9, 5, X, X, X, X, X, X, X}},
7719 {{0, 5, 4, 0, 1, 5, 2, 3, 11, X, X, X, X, X, X, X}},
7720 {{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, X, X, X, X}},
7721 {{10, 3, 11, 10, 1, 3, 9, 5, 4, X, X, X, X, X, X, X}},
7722 {{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, X, X, X, X}},
7723 {{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, X, X, X, X}},
7724 {{5, 4, 8, 5, 8, 10, 10, 8, 11, X, X, X, X, X, X, X}},
7725 {{9, 7, 8, 5, 7, 9, X, X, X, X, X, X, X, X, X, X}},
7726 {{9, 3, 0, 9, 5, 3, 5, 7, 3, X, X, X, X, X, X, X}},
7727 {{0, 7, 8, 0, 1, 7, 1, 5, 7, X, X, X, X, X, X, X}},
7728 {{1, 5, 3, 3, 5, 7, X, X, X, X, X, X, X, X, X, X}},
7729 {{9, 7, 8, 9, 5, 7, 10, 1, 2, X, X, X, X, X, X, X}},
7730 {{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, X, X, X, X}},
7731 {{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, X, X, X, X}},
7732 {{2, 10, 5, 2, 5, 3, 3, 5, 7, X, X, X, X, X, X, X}},
7733 {{7, 9, 5, 7, 8, 9, 3, 11, 2, X, X, X, X, X, X, X}},
7734 {{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, X, X, X, X}},
7735 {{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, X, X, X, X}},
7736 {{11, 2, 1, 11, 1, 7, 7, 1, 5, X, X, X, X, X, X, X}},
7737 {{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, X, X, X, X}},
7738 {{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, X}},
7739 {{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, X}},
7740 {{11, 10, 5, 7, 11, 5, X, X, X, X, X, X, X, X, X, X}},
7741 {{10, 6, 5, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7742 {{0, 8, 3, 5, 10, 6, X, X, X, X, X, X, X, X, X, X}},
7743 {{9, 0, 1, 5, 10, 6, X, X, X, X, X, X, X, X, X, X}},
7744 {{1, 8, 3, 1, 9, 8, 5, 10, 6, X, X, X, X, X, X, X}},
7745 {{1, 6, 5, 2, 6, 1, X, X, X, X, X, X, X, X, X, X}},
7746 {{1, 6, 5, 1, 2, 6, 3, 0, 8, X, X, X, X, X, X, X}},
7747 {{9, 6, 5, 9, 0, 6, 0, 2, 6, X, X, X, X, X, X, X}},
7748 {{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, X, X, X, X}},
7749 {{2, 3, 11, 10, 6, 5, X, X, X, X, X, X, X, X, X, X}},
7750 {{11, 0, 8, 11, 2, 0, 10, 6, 5, X, X, X, X, X, X, X}},
7751 {{0, 1, 9, 2, 3, 11, 5, 10, 6, X, X, X, X, X, X, X}},
7752 {{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, X, X, X, X}},
7753 {{6, 3, 11, 6, 5, 3, 5, 1, 3, X, X, X, X, X, X, X}},
7754 {{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, X, X, X, X}},
7755 {{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, X, X, X, X}},
7756 {{6, 5, 9, 6, 9, 11, 11, 9, 8, X, X, X, X, X, X, X}},
7757 {{5, 10, 6, 4, 7, 8, X, X, X, X, X, X, X, X, X, X}},
7758 {{4, 3, 0, 4, 7, 3, 6, 5, 10, X, X, X, X, X, X, X}},
7759 {{1, 9, 0, 5, 10, 6, 8, 4, 7, X, X, X, X, X, X, X}},
7760 {{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, X, X, X, X}},
7761 {{6, 1, 2, 6, 5, 1, 4, 7, 8, X, X, X, X, X, X, X}},
7762 {{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, X, X, X, X}},
7763 {{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, X, X, X, X}},
7764 {{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, X}},
7765 {{3, 11, 2, 7, 8, 4, 10, 6, 5, X, X, X, X, X, X, X}},
7766 {{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, X, X, X, X}},
7767 {{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, X, X, X, X}},
7768 {{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, X}},
7769 {{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, X, X, X, X}},
7770 {{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, X}},
7771 {{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, X}},
7772 {{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, X, X, X, X}},
7773 {{10, 4, 9, 6, 4, 10, X, X, X, X, X, X, X, X, X, X}},
7774 {{4, 10, 6, 4, 9, 10, 0, 8, 3, X, X, X, X, X, X, X}},
7775 {{10, 0, 1, 10, 6, 0, 6, 4, 0, X, X, X, X, X, X, X}},
7776 {{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, X, X, X, X}},
7777 {{1, 4, 9, 1, 2, 4, 2, 6, 4, X, X, X, X, X, X, X}},
7778 {{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, X, X, X, X}},
7779 {{0, 2, 4, 4, 2, 6, X, X, X, X, X, X, X, X, X, X}},
7780 {{8, 3, 2, 8, 2, 4, 4, 2, 6, X, X, X, X, X, X, X}},
7781 {{10, 4, 9, 10, 6, 4, 11, 2, 3, X, X, X, X, X, X, X}},
7782 {{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, X, X, X, X}},
7783 {{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, X, X, X, X}},
7784 {{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, X}},
7785 {{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, X, X, X, X}},
7786 {{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, X}},
7787 {{3, 11, 6, 3, 6, 0, 0, 6, 4, X, X, X, X, X, X, X}},
7788 {{6, 4, 8, 11, 6, 8, X, X, X, X, X, X, X, X, X, X}},
7789 {{7, 10, 6, 7, 8, 10, 8, 9, 10, X, X, X, X, X, X, X}},
7790 {{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, X, X, X, X}},
7791 {{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, X, X, X, X}},
7792 {{10, 6, 7, 10, 7, 1, 1, 7, 3, X, X, X, X, X, X, X}},
7793 {{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, X, X, X, X}},
7794 {{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, X}},
7795 {{7, 8, 0, 7, 0, 6, 6, 0, 2, X, X, X, X, X, X, X}},
7796 {{7, 3, 2, 6, 7, 2, X, X, X, X, X, X, X, X, X, X}},
7797 {{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, X, X, X, X}},
7798 {{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, X}},
7799 {{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, X}},
7800 {{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, X, X, X, X}},
7801 {{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, X}},
7802 {{0, 9, 1, 11, 6, 7, X, X, X, X, X, X, X, X, X, X}},
7803 {{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, X, X, X, X}},
7804 {{7, 11, 6, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7805 {{7, 6, 11, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7806 {{3, 0, 8, 11, 7, 6, X, X, X, X, X, X, X, X, X, X}},
7807 {{0, 1, 9, 11, 7, 6, X, X, X, X, X, X, X, X, X, X}},
7808 {{8, 1, 9, 8, 3, 1, 11, 7, 6, X, X, X, X, X, X, X}},
7809 {{10, 1, 2, 6, 11, 7, X, X, X, X, X, X, X, X, X, X}},
7810 {{1, 2, 10, 3, 0, 8, 6, 11, 7, X, X, X, X, X, X, X}},
7811 {{2, 9, 0, 2, 10, 9, 6, 11, 7, X, X, X, X, X, X, X}},
7812 {{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, X, X, X, X}},
7813 {{7, 2, 3, 6, 2, 7, X, X, X, X, X, X, X, X, X, X}},
7814 {{7, 0, 8, 7, 6, 0, 6, 2, 0, X, X, X, X, X, X, X}},
7815 {{2, 7, 6, 2, 3, 7, 0, 1, 9, X, X, X, X, X, X, X}},
7816 {{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, X, X, X, X}},
7817 {{10, 7, 6, 10, 1, 7, 1, 3, 7, X, X, X, X, X, X, X}},
7818 {{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, X, X, X, X}},
7819 {{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, X, X, X, X}},
7820 {{7, 6, 10, 7, 10, 8, 8, 10, 9, X, X, X, X, X, X, X}},
7821 {{6, 8, 4, 11, 8, 6, X, X, X, X, X, X, X, X, X, X}},
7822 {{3, 6, 11, 3, 0, 6, 0, 4, 6, X, X, X, X, X, X, X}},
7823 {{8, 6, 11, 8, 4, 6, 9, 0, 1, X, X, X, X, X, X, X}},
7824 {{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, X, X, X, X}},
7825 {{6, 8, 4, 6, 11, 8, 2, 10, 1, X, X, X, X, X, X, X}},
7826 {{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, X, X, X, X}},
7827 {{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, X, X, X, X}},
7828 {{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, X}},
7829 {{8, 2, 3, 8, 4, 2, 4, 6, 2, X, X, X, X, X, X, X}},
7830 {{0, 4, 2, 4, 6, 2, X, X, X, X, X, X, X, X, X, X}},
7831 {{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, X, X, X, X}},
7832 {{1, 9, 4, 1, 4, 2, 2, 4, 6, X, X, X, X, X, X, X}},
7833 {{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, X, X, X, X}},
7834 {{10, 1, 0, 10, 0, 6, 6, 0, 4, X, X, X, X, X, X, X}},
7835 {{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, X}},
7836 {{10, 9, 4, 6, 10, 4, X, X, X, X, X, X, X, X, X, X}},
7837 {{4, 9, 5, 7, 6, 11, X, X, X, X, X, X, X, X, X, X}},
7838 {{0, 8, 3, 4, 9, 5, 11, 7, 6, X, X, X, X, X, X, X}},
7839 {{5, 0, 1, 5, 4, 0, 7, 6, 11, X, X, X, X, X, X, X}},
7840 {{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, X, X, X, X}},
7841 {{9, 5, 4, 10, 1, 2, 7, 6, 11, X, X, X, X, X, X, X}},
7842 {{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, X, X, X, X}},
7843 {{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, X, X, X, X}},
7844 {{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, X}},
7845 {{7, 2, 3, 7, 6, 2, 5, 4, 9, X, X, X, X, X, X, X}},
7846 {{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, X, X, X, X}},
7847 {{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, X, X, X, X}},
7848 {{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, X}},
7849 {{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, X, X, X, X}},
7850 {{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, X}},
7851 {{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, X}},
7852 {{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, X, X, X, X}},
7853 {{6, 9, 5, 6, 11, 9, 11, 8, 9, X, X, X, X, X, X, X}},
7854 {{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, X, X, X, X}},
7855 {{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, X, X, X, X}},
7856 {{6, 11, 3, 6, 3, 5, 5, 3, 1, X, X, X, X, X, X, X}},
7857 {{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, X, X, X, X}},
7858 {{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, X}},
7859 {{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, X}},
7860 {{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, X, X, X, X}},
7861 {{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, X, X, X, X}},
7862 {{9, 5, 6, 9, 6, 0, 0, 6, 2, X, X, X, X, X, X, X}},
7863 {{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, X}},
7864 {{1, 5, 6, 2, 1, 6, X, X, X, X, X, X, X, X, X, X}},
7865 {{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, X}},
7866 {{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, X, X, X, X}},
7867 {{0, 3, 8, 5, 6, 10, X, X, X, X, X, X, X, X, X, X}},
7868 {{10, 5, 6, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7869 {{11, 5, 10, 7, 5, 11, X, X, X, X, X, X, X, X, X, X}},
7870 {{11, 5, 10, 11, 7, 5, 8, 3, 0, X, X, X, X, X, X, X}},
7871 {{5, 11, 7, 5, 10, 11, 1, 9, 0, X, X, X, X, X, X, X}},
7872 {{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, X, X, X, X}},
7873 {{11, 1, 2, 11, 7, 1, 7, 5, 1, X, X, X, X, X, X, X}},
7874 {{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, X, X, X, X}},
7875 {{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, X, X, X, X}},
7876 {{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, X}},
7877 {{2, 5, 10, 2, 3, 5, 3, 7, 5, X, X, X, X, X, X, X}},
7878 {{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, X, X, X, X}},
7879 {{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, X, X, X, X}},
7880 {{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, X}},
7881 {{1, 3, 5, 3, 7, 5, X, X, X, X, X, X, X, X, X, X}},
7882 {{0, 8, 7, 0, 7, 1, 1, 7, 5, X, X, X, X, X, X, X}},
7883 {{9, 0, 3, 9, 3, 5, 5, 3, 7, X, X, X, X, X, X, X}},
7884 {{9, 8, 7, 5, 9, 7, X, X, X, X, X, X, X, X, X, X}},
7885 {{5, 8, 4, 5, 10, 8, 10, 11, 8, X, X, X, X, X, X, X}},
7886 {{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, X, X, X, X}},
7887 {{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, X, X, X, X}},
7888 {{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, X}},
7889 {{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, X, X, X, X}},
7890 {{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, X}},
7891 {{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, X}},
7892 {{9, 4, 5, 2, 11, 3, X, X, X, X, X, X, X, X, X, X}},
7893 {{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, X, X, X, X}},
7894 {{5, 10, 2, 5, 2, 4, 4, 2, 0, X, X, X, X, X, X, X}},
7895 {{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, X}},
7896 {{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, X, X, X, X}},
7897 {{8, 4, 5, 8, 5, 3, 3, 5, 1, X, X, X, X, X, X, X}},
7898 {{0, 4, 5, 1, 0, 5, X, X, X, X, X, X, X, X, X, X}},
7899 {{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, X, X, X, X}},
7900 {{9, 4, 5, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7901 {{4, 11, 7, 4, 9, 11, 9, 10, 11, X, X, X, X, X, X, X}},
7902 {{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, X, X, X, X}},
7903 {{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, X, X, X, X}},
7904 {{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, X}},
7905 {{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, X, X, X, X}},
7906 {{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, X}},
7907 {{11, 7, 4, 11, 4, 2, 2, 4, 0, X, X, X, X, X, X, X}},
7908 {{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, X, X, X, X}},
7909 {{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, X, X, X, X}},
7910 {{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, X}},
7911 {{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, X}},
7912 {{1, 10, 2, 8, 7, 4, X, X, X, X, X, X, X, X, X, X}},
7913 {{4, 9, 1, 4, 1, 7, 7, 1, 3, X, X, X, X, X, X, X}},
7914 {{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, X, X, X, X}},
7915 {{4, 0, 3, 7, 4, 3, X, X, X, X, X, X, X, X, X, X}},
7916 {{4, 8, 7, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7917 {{9, 10, 8, 10, 11, 8, X, X, X, X, X, X, X, X, X, X}},
7918 {{3, 0, 9, 3, 9, 11, 11, 9, 10, X, X, X, X, X, X, X}},
7919 {{0, 1, 10, 0, 10, 8, 8, 10, 11, X, X, X, X, X, X, X}},
7920 {{3, 1, 10, 11, 3, 10, X, X, X, X, X, X, X, X, X, X}},
7921 {{1, 2, 11, 1, 11, 9, 9, 11, 8, X, X, X, X, X, X, X}},
7922 {{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, X, X, X, X}},
7923 {{0, 2, 11, 8, 0, 11, X, X, X, X, X, X, X, X, X, X}},
7924 {{3, 2, 11, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7925 {{2, 3, 8, 2, 8, 10, 10, 8, 9, X, X, X, X, X, X, X}},
7926 {{9, 10, 2, 0, 9, 2, X, X, X, X, X, X, X, X, X, X}},
7927 {{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, X, X, X, X}},
7928 {{1, 10, 2, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7929 {{1, 3, 8, 9, 1, 8, X, X, X, X, X, X, X, X, X, X}},
7930 {{0, 9, 1, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7931 {{0, 3, 8, X, X, X, X, X, X, X, X, X, X, X, X, X}},
7932 {{X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X}}}};
7957 line_to_vertex_table,
7965 write_back_cell_data);
7972#include "grid_tools.inst"
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
void distribute(VectorType &vec) const
BoundingBox< spacedim, Number > create_extended_relative(const Number relative_amount) const
Number side_length(const unsigned int direction) const
BoundingBox< spacedim, Number > create_extended(const Number amount) const
void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
types::global_dof_index n_dofs() const
void reinit(const size_type m, const size_type n, const IndexSet &rowset=IndexSet())
void add(const size_type i, const size_type j)
const DerivativeForm< 1, dim, spacedim > & jacobian(const unsigned int q_point) const
double JxW(const unsigned int q_point) const
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell)
number singular_value(const size_type i) const
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const =0
Abstract base class for mapping classes.
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const =0
virtual boost::container::small_vector< Point< spacedim >, GeometryInfo< dim >::vertices_per_cell > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
numbers::NumberTraits< Number >::real_type square() const
numbers::NumberTraits< Number >::real_type distance_square(const Point< dim, Number > &p) const
void initialize(const MatrixType &A, const AdditionalData ¶meters=AdditionalData())
Quadrature< spacedim > compute_affine_transformation(const std::array< Point< spacedim >, dim+1 > &vertices) const
const Point< dim > & point(const unsigned int i) const
unsigned int size() const
static ReferenceCell n_vertices_to_type(const int dim, const unsigned int n_vertices)
void solve(const MatrixType &A, VectorType &x, const VectorType &b, const PreconditionerType &preconditioner)
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
numbers::NumberTraits< Number >::real_type norm() const
IteratorState::IteratorStates state() const
virtual MPI_Comm get_communicator() const
unsigned int n_quads() const
void load_user_indices(const std::vector< unsigned int > &v)
bool all_reference_cells_are_hyper_cube() const
face_iterator end_face() const
const std::map< std::pair< cell_iterator, unsigned int >, std::pair< std::pair< cell_iterator, unsigned int >, std::bitset< 3 > > > & get_periodic_face_map() const
unsigned int n_lines() const
unsigned int n_raw_faces() const
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
unsigned int n_active_cells() const
void refine_global(const unsigned int times=1)
const std::vector< Point< spacedim > > & get_vertices() const
unsigned int n_levels() const
cell_iterator end() const
virtual bool has_hanging_nodes() const
bool vertex_used(const unsigned int index) const
virtual void execute_coarsening_and_refinement()
unsigned int n_cells() const
const std::vector< bool > & get_used_vertices() const
Triangulation< dim, spacedim > & get_triangulation()
unsigned int n_vertices() const
void save_user_indices(std::vector< unsigned int > &v) const
virtual std::vector< types::boundary_id > get_boundary_ids() const
active_face_iterator begin_active_face() const
active_cell_iterator begin_active(const unsigned int level=0) const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcMeshNotOrientable()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcNeedsMPI()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
static ::ExceptionBase & ExcGridHasInvalidCell(int arg1)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNeedsCGAL()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcScalingFactorNotPositive(double arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::active_cell_iterator active_cell_iterator
typename IteratorSelector::line_iterator line_iterator
LinearOperator< Range, Domain, Payload > linear_operator(const OperatorExemplar &, const Matrix &)
PackagedOperation< Range > constrained_right_hand_side(const AffineConstraints< typename Range::value_type > &constraints, const LinearOperator< Range, Domain, Payload > &linop, const Range &right_hand_side)
LinearOperator< Range, Domain, Payload > constrained_linear_operator(const AffineConstraints< typename Range::value_type > &constraints, const LinearOperator< Range, Domain, Payload > &linop)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
@ update_values
Shape function values.
@ update_JxW_values
Transformed quadrature weights.
@ update_jacobians
Volume element.
@ update_quadrature_points
Transformed quadrature points.
const Manifold< dim, spacedim > & get_manifold(const types::manifold_id number) const
void copy_boundary_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool reset_boundary_ids=false)
void copy_material_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool compute_face_ids=false)
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={})
virtual std::vector< types::manifold_id > get_manifold_ids() const
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
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)
Task< RT > new_task(const std::function< RT()> &function)
CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt K
@ valid
Iterator points to a valid object.
void create_laplace_matrix(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim > &q, SparseMatrixType &matrix, const Function< spacedim, typename SparseMatrixType::value_type > *const a=nullptr, const AffineConstraints< typename SparseMatrixType::value_type > &constraints=AffineConstraints< typename SparseMatrixType::value_type >())
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
constexpr const ReferenceCell Wedge
constexpr const ReferenceCell Pyramid
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
T max(const T &t, const MPI_Comm mpi_communicator)
T min(const T &t, const MPI_Comm mpi_communicator)
std::vector< T > all_gather(const MPI_Comm comm, const T &object_to_send)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
constexpr T pow(const T base, const int iexp)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
std::vector< Integer > invert_permutation(const std::vector< Integer > &permutation)
static constexpr double PI
const types::boundary_id internal_face_boundary_id
const types::subdomain_id artificial_subdomain_id
static const unsigned int invalid_unsigned_int
const types::manifold_id flat_manifold_id
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
std::uint64_t global_vertex_index
unsigned int subdomain_id
typename internal::ndarray::HelperArray< T, Ns... >::type ndarray
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
boost::geometry::index::rtree< LeafType, IndexType, IndexableGetter > RTree
RTree< typename LeafTypeIterator::value_type, IndexType, IndexableGetter > pack_rtree(const LeafTypeIterator &begin, const LeafTypeIterator &end)
void swap(SmartPointer< T, P > &t1, SmartPointer< T, Q > &t2)
std::vector< unsigned int > vertices
types::manifold_id manifold_id
types::material_id material_id
types::boundary_id boundary_id
static double distance_to_unit_cell(const Point< dim > &p)
static unsigned int line_to_cell_vertices(const unsigned int line, const unsigned int vertex)
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices()
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim - dim, spacedim >(&forms)[vertices_per_cell])
std::vector< CellData< 2 > > boundary_quads
bool check_consistency(const unsigned int dim) const
std::vector< CellData< 1 > > boundary_lines
std::list< typename Triangulation< dim, spacedim >::cell_iterator > distorted_cells
DEAL_II_HOST constexpr Number determinant(const SymmetricTensor< 2, dim, Number > &)
bool operator<(const SynchronousIterators< Iterators > &a, const SynchronousIterators< Iterators > &b)
std::map< unsigned int, unsigned int > vertex_to_coinciding_vertex_group
std::map< unsigned int, std::vector< unsigned int > > coinciding_vertex_groups
const ::Triangulation< dim, spacedim > & tria
#define DEAL_II_VERTEX_INDEX_MPI_TYPE