21#include <boost/container/small_vector.hpp>
36 template <
int structdim>
44 if (std::lexicographical_compare(std::begin(a.
vertices),
46 std::begin(b.vertices),
47 std::end(b.vertices)))
54 if (std::equal(std::begin(a.
vertices),
56 std::begin(b.vertices)))
61 "Two CellData objects with equal vertices must "
62 "have the same material/boundary ids and manifold "
87 template <
typename FaceIteratorType>
91 CellData<dim - 1> face_cell_data(face->n_vertices());
92 for (
unsigned int vertex_n = 0; vertex_n < face->n_vertices();
94 face_cell_data.vertices[vertex_n] = face->vertex_index(vertex_n);
95 face_cell_data.boundary_id = face->boundary_id();
96 face_cell_data.manifold_id = face->manifold_id();
98 face_data.insert(std::move(face_cell_data));
111 if constexpr (dim - 1 == 0)
113 if constexpr (dim - 1 == 1)
115 else if constexpr (dim - 1 == 2)
135 template <
typename FaceIteratorType>
150 template <
int dim,
int spacedim>
152 tuple<std::vector<Point<spacedim>>, std::vector<CellData<dim>>,
SubCellData>
156 ExcMessage(
"The input triangulation must be non-empty."));
158 std::vector<Point<spacedim>> vertices = tria.
get_vertices();
159 std::vector<CellData<dim>> cells;
169 for (
const unsigned int cell_vertex_n : cell->vertex_indices())
171 Assert(cell->vertex_index(cell_vertex_n) < vertices.size(),
174 cell->vertex_index(cell_vertex_n);
178 cells.emplace_back(std::move(cell_data));
183 for (
const unsigned int face_n : cell->face_indices())
186 const auto face = cell->face(face_n);
195 for (
unsigned int line_n = 0; line_n < cell->n_lines(); ++line_n)
197 const auto line = cell->line(line_n);
203 for (
const unsigned int vertex_n : line->vertex_indices())
205 line->vertex_index(vertex_n);
208 line_data.insert(std::move(line_cell_data));
217 for (
const CellData<1> &face_line_data : line_data)
225 return std::tuple<std::vector<Point<spacedim>>,
226 std::vector<CellData<dim>>,
229 std::move(subcell_data));
234 template <
int dim,
int spacedim>
243 "Invalid SubCellData supplied according to ::check_consistency(). "
244 "This is caused by data containing objects for the wrong dimension."));
247 std::vector<bool> vertex_used(vertices.size(),
false);
248 for (
unsigned int c = 0; c < cells.size(); ++c)
249 for (
unsigned int v = 0; v < cells[c].vertices.size(); ++v)
251 Assert(cells[c].vertices[v] < vertices.size(),
252 ExcMessage(
"Invalid vertex index encountered! cells[" +
256 " is invalid, because only " +
258 " vertices were supplied."));
259 vertex_used[cells[c].vertices[v]] =
true;
266 std::vector<unsigned int> new_vertex_numbers(vertices.size(),
268 unsigned int next_free_number = 0;
269 for (
unsigned int i = 0; i < vertices.size(); ++i)
270 if (vertex_used[i] ==
true)
272 new_vertex_numbers[i] = next_free_number;
277 for (
unsigned int c = 0; c < cells.size(); ++c)
278 for (
auto &v : cells[c].vertices)
279 v = new_vertex_numbers[v];
284 for (
unsigned int v = 0;
289 new_vertex_numbers.size(),
291 "Invalid vertex index in subcelldata.boundary_lines. "
292 "subcelldata.boundary_lines[" +
297 " is invalid, because only " +
299 " vertices were supplied."));
306 for (
unsigned int v = 0;
311 new_vertex_numbers.size(),
313 "Invalid vertex index in subcelldata.boundary_quads. "
314 "subcelldata.boundary_quads[" +
319 " is invalid, because only " +
321 " vertices were supplied."));
329 std::vector<Point<spacedim>> tmp;
330 tmp.reserve(std::count(vertex_used.begin(), vertex_used.end(),
true));
331 for (
unsigned int v = 0; v < vertices.size(); ++v)
332 if (vertex_used[v] ==
true)
333 tmp.push_back(vertices[v]);
339 template <
int dim,
int spacedim>
344 std::vector<unsigned int> &considered_vertices,
351 std::vector<unsigned int> new_vertex_numbers(vertices.size());
352 std::iota(new_vertex_numbers.begin(), new_vertex_numbers.end(), 0);
355 if (considered_vertices.empty())
356 considered_vertices = new_vertex_numbers;
371 unsigned int longest_coordinate_direction = 0;
372 double longest_coordinate_length = bbox.
side_length(0);
373 for (
unsigned int d = 1; d < spacedim; ++d)
375 const double coordinate_length = bbox.
side_length(d);
376 if (longest_coordinate_length < coordinate_length)
378 longest_coordinate_length = coordinate_length;
379 longest_coordinate_direction = d;
385 std::vector<std::pair<unsigned int, Point<spacedim>>> sorted_vertices;
386 sorted_vertices.reserve(vertices.size());
387 for (
const unsigned int vertex_n : considered_vertices)
390 sorted_vertices.emplace_back(vertex_n, vertices[vertex_n]);
392 std::sort(sorted_vertices.begin(),
393 sorted_vertices.end(),
396 return a.second[longest_coordinate_direction] <
397 b.second[longest_coordinate_direction];
402 for (
unsigned int d = 0; d < spacedim; ++d)
410 auto range_start = sorted_vertices.begin();
411 while (range_start != sorted_vertices.end())
413 auto range_end = range_start + 1;
414 while (range_end != sorted_vertices.end() &&
415 std::abs(range_end->second[longest_coordinate_direction] -
416 range_start->second[longest_coordinate_direction]) <
422 std::sort(range_start,
426 return a.first < b.first;
438 for (
auto it =
reference + 1; it != range_end; ++it)
440 if (within_tolerance(
reference->second, it->second))
442 new_vertex_numbers[it->first] =
reference->first;
448 range_start = range_end;
455 for (
auto &cell : cells)
456 for (
auto &vertex_index : cell.vertices)
457 vertex_index = new_vertex_numbers[vertex_index];
459 for (
auto &vertex_index : quad.vertices)
460 vertex_index = new_vertex_numbers[vertex_index];
462 for (
auto &vertex_index : line.vertices)
463 vertex_index = new_vertex_numbers[vertex_index];
475 if (vertices.empty())
483 for (
unsigned int i = 0; i < vertices.size(); ++i)
484 map_point_to_local_vertex_index[vertices[i]] = i;
487 if (map_point_to_local_vertex_index.size() == vertices.size())
491 vertices.resize(map_point_to_local_vertex_index.size());
494 for (
const auto &p : map_point_to_local_vertex_index)
495 vertices[j++] = p.first;
501 template <
int dim,
int spacedim>
512 if (dim == 2 && spacedim == 3)
515 std::size_t n_negative_cells = 0;
516 std::size_t cell_no = 0;
517 for (
auto &cell : cells)
525 const auto reference_cell =
526 ReferenceCells::n_vertices_to_reference_cell<dim>(
529 if (reference_cell.is_hyper_cube())
534 std::swap(cell.vertices[1], cell.vertices[2]);
539 std::swap(cell.vertices[0], cell.vertices[2]);
540 std::swap(cell.vertices[1], cell.vertices[3]);
541 std::swap(cell.vertices[4], cell.vertices[6]);
542 std::swap(cell.vertices[5], cell.vertices[7]);
545 else if (reference_cell.is_simplex())
550 std::swap(cell.vertices[cell.vertices.size() - 2],
551 cell.vertices[cell.vertices.size() - 1]);
556 std::swap(cell.vertices[0], cell.vertices[3]);
557 std::swap(cell.vertices[1], cell.vertices[4]);
558 std::swap(cell.vertices[2], cell.vertices[5]);
564 std::swap(cell.vertices[2], cell.vertices[3]);
578 return n_negative_cells;
582 template <
int dim,
int spacedim>
588 const std::size_t n_negative_cells =
597 AssertThrow(n_negative_cells == 0 || n_negative_cells == cells.size(),
600 "This function assumes that either all cells have positive "
601 "volume, or that all cells have been specified in an "
602 "inverted vertex order so that their volume is negative. "
603 "(In the latter case, this class automatically inverts "
604 "every cell.) However, the mesh you have specified "
605 "appears to have both cells with positive and cells with "
606 "negative volume. You need to check your mesh which "
607 "cells these are and how they got there.\n"
608 "As a hint, of the total ") +
609 std::to_string(cells.size()) +
" cells in the mesh, " +
610 std::to_string(n_negative_cells) +
611 " appear to have a negative volume."));
629 CheapEdge(
const unsigned int v0,
const unsigned int v1)
641 return ((v0 <
e.v0) || ((v0 ==
e.v0) && (v1 <
e.v1)));
664 std::set<CheapEdge> edges;
676 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
678 const CheapEdge reverse_edge(
681 if (edges.find(reverse_edge) != edges.end())
686 const CheapEdge correct_edge(
689 edges.insert(correct_edge);
719 static const unsigned int
725 const unsigned int ParallelEdges<2>::starter_edges[2] = {0, 2};
728 const unsigned int ParallelEdges<2>::parallel_edges[4][1] = {{1},
734 const unsigned int ParallelEdges<3>::starter_edges[3] = {0, 2, 8};
737 const unsigned int ParallelEdges<3>::parallel_edges[12][3] = {
770 AdjacentCell(
const unsigned int cell_index,
771 const unsigned int edge_within_cell)
792 class AdjacentCells<2>
810 push_back(
const AdjacentCell &adjacent_cell)
874 class AdjacentCells<3> :
public std::vector<AdjacentCell>
896 Edge(
const CellData<dim> &cell,
const unsigned int edge_number)
911 if (vertex_indices[0] > vertex_indices[1])
912 std::swap(vertex_indices[0], vertex_indices[1]);
922 return ((vertex_indices[0] <
e.vertex_indices[0]) ||
923 ((vertex_indices[0] ==
e.vertex_indices[0]) &&
924 (vertex_indices[1] <
e.vertex_indices[1])));
933 return ((vertex_indices[0] ==
e.vertex_indices[0]) &&
934 (vertex_indices[1] ==
e.vertex_indices[1]));
947 enum OrientationStatus
977 Cell(
const CellData<dim> &c,
const std::vector<Edge<dim>> &edge_list)
984 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
986 const Edge<dim>
e(c,
l);
988 (std::lower_bound(edge_list.begin(), edge_list.end(),
e) -
1022 class EdgeDeltaSet<2>
1054 insert(
const unsigned int edge_index)
1115 class EdgeDeltaSet<3> :
public std::set<unsigned int>
1125 std::vector<Edge<dim>>
1132 std::vector<Edge<dim>> edge_list;
1134 for (
unsigned int i = 0; i < cells.size(); ++i)
1135 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1136 edge_list.emplace_back(cells[i], l);
1139 std::sort(edge_list.begin(), edge_list.end());
1140 edge_list.erase(std::unique(edge_list.begin(), edge_list.end()),
1153 std::vector<Cell<dim>>
1154 build_cells_and_connect_edges(
const std::vector<
CellData<dim>> &cells,
1155 std::vector<Edge<dim>> &edges)
1157 std::vector<Cell<dim>> cell_list;
1158 cell_list.reserve(cells.size());
1159 for (
unsigned int i = 0; i < cells.size(); ++i)
1163 cell_list.emplace_back(cells[i], edges);
1167 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1168 edges[cell_list.back().edge_indices[
l]].adjacent_cells.push_back(
1169 AdjacentCell(i, l));
1184 get_next_unoriented_cell(
const std::vector<Cell<dim>> &cells,
1185 const std::vector<Edge<dim>> &edges,
1186 const unsigned int current_cell)
1188 for (
unsigned int c = current_cell; c < cells.size(); ++c)
1189 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1191 Edge<dim>::not_oriented)
1206 orient_one_set_of_parallel_edges(
const std::vector<Cell<dim>> &cells,
1207 std::vector<Edge<dim>> &edges,
1208 const unsigned int cell,
1209 const unsigned int local_edge)
1236 edges[cells[cell].edge_indices[local_edge]].orientation_status =
1237 (dim == 2 ? Edge<dim>::backward : Edge<dim>::forward);
1253 edges[cells[cell].edge_indices[local_edge]].orientation_status =
1254 (dim == 2 ? Edge<dim>::forward : Edge<dim>::backward);
1263 EdgeDeltaSet<dim> Delta_k;
1264 EdgeDeltaSet<dim> Delta_k_minus_1;
1265 Delta_k_minus_1.insert(cells[cell].
edge_indices[local_edge]);
1267 while (Delta_k_minus_1.begin() !=
1268 Delta_k_minus_1.end())
1272 for (
typename EdgeDeltaSet<dim>::const_iterator delta =
1273 Delta_k_minus_1.begin();
1274 delta != Delta_k_minus_1.end();
1278 Edge<dim>::not_oriented,
1282 for (
typename AdjacentCells<dim>::const_iterator adjacent_cell =
1284 adjacent_cell != edges[*delta].adjacent_cells.end();
1287 const unsigned int K = adjacent_cell->cell_index;
1288 const unsigned int delta_is_edge_in_K =
1289 adjacent_cell->edge_within_cell;
1293 const unsigned int first_edge_vertex =
1294 (edges[*delta].orientation_status == Edge<dim>::forward ?
1295 edges[*delta].vertex_indices[0] :
1296 edges[*delta].vertex_indices[1]);
1297 const unsigned int first_edge_vertex_in_K =
1300 delta_is_edge_in_K, 0)];
1302 first_edge_vertex == first_edge_vertex_in_K ||
1303 first_edge_vertex ==
1305 dim>::line_to_cell_vertices(delta_is_edge_in_K, 1)],
1310 for (
unsigned int o_e = 0;
1311 o_e < ParallelEdges<dim>::n_other_parallel_edges;
1317 const unsigned int opposite_edge =
1318 cells[
K].edge_indices[ParallelEdges<
1320 const unsigned int first_opposite_edge_vertex =
1321 cells[
K].vertex_indices
1325 (first_edge_vertex == first_edge_vertex_in_K ? 0 :
1332 const typename Edge<dim>::OrientationStatus
1333 opposite_edge_orientation =
1334 (edges[opposite_edge].vertex_indices[0] ==
1335 first_opposite_edge_vertex ?
1336 Edge<dim>::forward :
1337 Edge<dim>::backward);
1342 Edge<dim>::not_oriented)
1346 edges[opposite_edge].orientation_status =
1347 opposite_edge_orientation;
1348 Delta_k.insert(opposite_edge);
1364 opposite_edge_orientation,
1370 opposite_edge_orientation)
1383 Delta_k_minus_1 = Delta_k;
1397 rotate_cell(
const std::vector<Cell<dim>> &cell_list,
1398 const std::vector<Edge<dim>> &edge_list,
1405 for (
unsigned int e = 0; e < GeometryInfo<dim>::lines_per_cell; ++
e)
1412 starting_vertex_of_edge[
e] =
1416 starting_vertex_of_edge[
e] =
1432 if ((starting_vertex_of_edge[0] == starting_vertex_of_edge[2]) ||
1433 (starting_vertex_of_edge[0] == starting_vertex_of_edge[3]))
1434 origin_vertex_of_cell = starting_vertex_of_edge[0];
1435 else if ((starting_vertex_of_edge[1] ==
1436 starting_vertex_of_edge[2]) ||
1437 (starting_vertex_of_edge[1] ==
1438 starting_vertex_of_edge[3]))
1439 origin_vertex_of_cell = starting_vertex_of_edge[1];
1451 for (origin_vertex_of_cell = 0;
1452 origin_vertex_of_cell < GeometryInfo<dim>::vertices_per_cell;
1453 ++origin_vertex_of_cell)
1454 if (std::count(starting_vertex_of_edge,
1455 starting_vertex_of_edge +
1460 Assert(origin_vertex_of_cell <
1483 while (raw_cells[
cell_index].vertices[0] != origin_vertex_of_cell)
1485 const unsigned int tmp = raw_cells[
cell_index].vertices[0];
1508 static const unsigned int cube_permutations[8][8] = {
1509 {0, 1, 2, 3, 4, 5, 6, 7},
1510 {1, 5, 3, 7, 0, 4, 2, 6},
1511 {2, 6, 0, 4, 3, 7, 1, 5},
1512 {3, 2, 1, 0, 7, 6, 5, 4},
1513 {4, 0, 6, 2, 5, 1, 7, 3},
1514 {5, 4, 7, 6, 1, 0, 3, 2},
1515 {6, 7, 4, 5, 2, 3, 0, 1},
1516 {7, 3, 5, 1, 6, 2, 4, 0}};
1521 temp_vertex_indices[v] =
1523 .vertices[cube_permutations[origin_vertex_of_cell][v]];
1525 raw_cells[
cell_index].vertices[v] = temp_vertex_indices[v];
1549 std::vector<Edge<dim>> edge_list = build_edges(cells);
1550 std::vector<Cell<dim>> cell_list =
1551 build_cells_and_connect_edges(cells, edge_list);
1555 unsigned int next_cell_with_unoriented_edge = 0;
1556 while ((next_cell_with_unoriented_edge = get_next_unoriented_cell(
1557 cell_list, edge_list, next_cell_with_unoriented_edge)) !=
1571 for (
unsigned int l = 0;
l < dim; ++
l)
1572 if (edge_list[cell_list[next_cell_with_unoriented_edge]
1575 orient_one_set_of_parallel_edges(
1578 next_cell_with_unoriented_edge,
1579 ParallelEdges<dim>::starter_edges[l]);
1583 for (
unsigned int l = 0; l < GeometryInfo<dim>::lines_per_cell; ++
l)
1584 Assert(edge_list[cell_list[next_cell_with_unoriented_edge]
1593 for (
unsigned int c = 0; c < cells.size(); ++c)
1594 rotate_cell(cell_list, edge_list, c, cells);
1611 Assert(cells.size() != 0,
1613 "List of elements to orient must have at least one cell"));
1621 if (!is_consistent(cells))
1638 template <
int dim,
int spacedim>
1639 std::map<unsigned int, Point<spacedim>>
1642 std::map<unsigned int, Point<spacedim>> vertex_map;
1646 for (; cell != endc; ++cell)
1648 for (
const unsigned int i : cell->face_indices())
1652 if (face->at_boundary())
1654 for (
unsigned j = 0; j < face->n_vertices(); ++j)
1657 const unsigned int vertex_index = face->vertex_index(j);
1658 vertex_map[vertex_index] = vertex;
1668 template <
int dim,
int spacedim>
1669 std::vector<std::vector<std::pair<unsigned int, Point<spacedim>>>>
1677 std::map<unsigned int, unsigned int> face_vertex_indices;
1678 std::map<unsigned int, Point<spacedim>> vertex_to_point;
1683 for (
const unsigned int f : cell->face_indices())
1685 if (cell->face(f)->at_boundary())
1689 const unsigned int v0 = cell->face(f)->vertex_index(0);
1690 const unsigned int v1 = cell->face(f)->vertex_index(1);
1695 vertex_to_point[
v0] = v_mapped[f];
1696 face_vertex_indices[
v0] =
v1;
1698 else if (cell->reference_cell() ==
1703 if (f == 0 || f == 3)
1706 vertex_to_point[
v1] =
1709 face_vertex_indices[
v1] =
v0;
1714 vertex_to_point[
v0] =
1717 face_vertex_indices[
v0] =
v1;
1728 std::vector<std::vector<std::pair<unsigned int, Point<spacedim>>>>
1730 std::vector<std::pair<unsigned int, Point<spacedim>>> current_boundary;
1733 unsigned int start_index = face_vertex_indices.begin()->first;
1734 unsigned int current_index = start_index;
1738 while (face_vertex_indices.size() > 0)
1740 const auto vertex_it = vertex_to_point.find(current_index);
1741 Assert(vertex_it != vertex_to_point.end(),
1742 ExcMessage(
"This should not occur, please report bug"));
1743 current_boundary.emplace_back(vertex_it->first, vertex_it->second);
1744 vertex_to_point.erase(vertex_it);
1746 const auto it = face_vertex_indices.find(current_index);
1749 Assert(it != face_vertex_indices.end(),
1750 ExcMessage(
"Triangulation might contain holes"));
1752 current_index = it->second;
1753 face_vertex_indices.erase(it);
1756 if (current_index == start_index)
1758 boundaries.push_back(current_boundary);
1759 current_boundary.clear();
1761 if (face_vertex_indices.size() == 0)
1768 start_index = face_vertex_indices.begin()->first;
1769 current_index = start_index;
1777 template <
int dim,
int spacedim>
1780 const bool isotropic,
1781 const unsigned int max_iterations)
1783 unsigned int iter = 0;
1784 bool continue_refinement =
true;
1786 while (continue_refinement && (iter < max_iterations))
1790 continue_refinement =
false;
1793 for (
const unsigned int j : cell->face_indices())
1794 if (cell->at_boundary(j) ==
false &&
1795 cell->neighbor(j)->has_children())
1799 cell->set_refine_flag();
1800 continue_refinement =
true;
1803 continue_refinement |= cell->flag_for_face_refinement(j);
1812 template <
int dim,
int spacedim>
1815 const double max_ratio,
1816 const unsigned int max_iterations)
1818 unsigned int iter = 0;
1819 bool continue_refinement =
true;
1821 while (continue_refinement && (iter < max_iterations))
1824 continue_refinement =
false;
1827 std::pair<unsigned int, double> info =
1828 GridTools::get_longest_direction<dim, spacedim>(cell);
1829 if (info.second > max_ratio)
1831 cell->set_refine_flag(
1833 continue_refinement =
true;
1842 template <
int dim,
int spacedim>
1843 std::map<unsigned int, Point<spacedim>>
1847 std::map<unsigned int, Point<spacedim>> result;
1850 if (!cell->is_artificial())
1853 for (
unsigned int i = 0; i < vs.size(); ++i)
1854 result[cell->vertex_index(i)] = vs[i];
1862 template <
int dim,
int spacedim>
1864 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>>
1868 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>>
1872 endc = triangulation.
end();
1873 for (; cell != endc; ++cell)
1874 for (
const unsigned int i : cell->vertex_indices())
1879 if (triangulation.Triangulation<dim, spacedim>::has_hanging_nodes())
1886 for (; cell != endc; ++cell)
1888 for (
const unsigned int i : cell->face_indices())
1890 if ((cell->at_boundary(i) ==
false) &&
1891 (cell->neighbor(i)->is_active()))
1894 adjacent_cell = cell->neighbor(i);
1895 for (
unsigned int j = 0; j < cell->face(i)->n_vertices();
1905 for (
unsigned int i = 0; i < cell->n_lines(); ++i)
1906 if (cell->line(i)->has_children())
1921 template <
int dim,
int spacedim>
1939 const unsigned int index = cell->active_cell_index();
1940 cell_connectivity.
add(index, index);
1941 for (
auto f : cell->face_indices())
1942 if ((cell->at_boundary(f) ==
false) &&
1943 (cell->neighbor(f)->has_children() ==
false))
1945 const unsigned int other_index =
1946 cell->neighbor(f)->active_cell_index();
1947 cell_connectivity.
add(index, other_index);
1948 cell_connectivity.
add(other_index, index);
1955 template <
int dim,
int spacedim>
1995 std::vector<boost::container::small_vector<unsigned int, 16>>
1999 for (
const unsigned int v : cell->vertex_indices())
2000 vertex_to_cell[cell->vertex_index(v)].push_back(
2001 cell->active_cell_index());
2006 std::vector<types::global_dof_index> neighbors;
2010 for (
const unsigned int v : cell->vertex_indices())
2011 neighbors.insert(neighbors.end(),
2012 vertex_to_cell[cell->vertex_index(v)].begin(),
2013 vertex_to_cell[cell->vertex_index(v)].end());
2014 std::sort(neighbors.begin(), neighbors.end());
2015 cell_connectivity.
add_entries(cell->active_cell_index(),
2017 std::unique(neighbors.begin(),
2024 template <
int dim,
int spacedim>
2028 const unsigned int level,
2031 std::vector<boost::container::small_vector<unsigned int, 16>>
2038 for (
const unsigned int v : cell->vertex_indices())
2039 vertex_to_cell[cell->vertex_index(v)].push_back(cell->index());
2044 std::vector<types::global_dof_index> neighbors;
2048 for (
const unsigned int v : cell->vertex_indices())
2049 neighbors.insert(neighbors.end(),
2050 vertex_to_cell[cell->vertex_index(v)].begin(),
2051 vertex_to_cell[cell->vertex_index(v)].end());
2052 std::sort(neighbors.begin(), neighbors.end());
2055 std::unique(neighbors.begin(),
2063 template <
int dim,
int spacedim>
2076 for (
unsigned int face = 4; face < 6; ++face)
2078 const auto face_iter = cell->face(face);
2079 const std::array<types::geometric_orientation, 2> line_orientations{
2080 {face_iter->line_orientation(0), face_iter->line_orientation(1)}};
2081 const std::array<unsigned int, 2> line_vertex_indices{
2084 const std::array<unsigned int, 4> raw_vertex_indices{
2085 {face_iter->line(0)->vertex_index(1 - line_vertex_indices[0]),
2086 face_iter->line(1)->vertex_index(1 - line_vertex_indices[1]),
2087 face_iter->line(0)->vertex_index(line_vertex_indices[0]),
2088 face_iter->line(1)->vertex_index(line_vertex_indices[1])}};
2090 const auto combined_orientation =
2091 cell->combined_face_orientation(face);
2092 const std::array<unsigned int, 4> vertex_order{
2095 combined_orientation),
2098 combined_orientation),
2101 combined_orientation),
2104 combined_orientation)}};
2106 const unsigned int index = 4 * (face - 4);
2107 for (
unsigned int i = 0; i < 4; ++i)
2112 const std::array<types::geometric_orientation, 2> line_orientations{
2113 {cell->line_orientation(0), cell->line_orientation(1)}};
2114 const std::array<unsigned int, 2> line_vertex_indices{
2117 const std::array<unsigned int, 4> raw_vertex_indices{
2118 {cell->line(0)->vertex_index(1 - line_vertex_indices[0]),
2119 cell->line(1)->vertex_index(1 - line_vertex_indices[1]),
2120 cell->line(0)->vertex_index(line_vertex_indices[0]),
2121 cell->line(1)->vertex_index(line_vertex_indices[1])}};
2122 for (
unsigned int i = 0; i < 4; ++i)
2133 for (
const unsigned int i : cell->vertex_indices())
2135 const auto [face_index, vertex_index] =
2137 const auto vertex_within_face_index =
2141 cell->combined_face_orientation(face_index));
2143 cell->face(face_index)->vertex_index(vertex_within_face_index);
2151#include "grid/grid_tools_topology.inst"
* * const_iterator()=default
***mech_lbc_system increment_interpolation_handlers push_back(scale_z_handler)
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
Number side_length(const unsigned int direction) const
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_unique_and_sorted=false)
void reinit(const size_type m, const size_type n, const IndexSet &rowset=IndexSet())
void add(const size_type i, const size_type j)
Abstract base class for mapping classes.
virtual boost::container::small_vector< Point< spacedim >, ReferenceCells::max_n_vertices< dim >() > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
std::array< unsigned int, 2 > standard_vertex_to_face_and_vertex_index(const unsigned int vertex) const
unsigned int standard_to_real_face_vertex(const unsigned int vertex, const unsigned int face, const types::geometric_orientation face_orientation) const
bool all_reference_cells_are_hyper_cube() const
cell_iterator begin(const unsigned int level=0) const
unsigned int n_active_cells() const
const std::vector< Point< spacedim > > & get_vertices() const
unsigned int n_levels() const
cell_iterator end() const
virtual void execute_coarsening_and_refinement()
unsigned int n_cells() const
unsigned int n_vertices() const
active_cell_iterator begin_active(const unsigned int level=0) const
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
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()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcGridHasInvalidCell(int arg1)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
void consistently_order_cells(std::vector< CellData< dim > > &cells)
CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt K
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 ReferenceCell< 3 > Hexahedron
constexpr ReferenceCell< 2 > Quadrilateral
constexpr ReferenceCell< 1 > Line
constexpr ReferenceCell< 2 > Triangle
constexpr ReferenceCell< 3 > Pyramid
constexpr ReferenceCell< 3 > Wedge
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
constexpr unsigned int invalid_unsigned_int
constexpr types::boundary_id internal_face_boundary_id
constexpr types::manifold_id flat_manifold_id
constexpr types::geometric_orientation default_geometric_orientation
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
void swap(ObserverPointer< T, P > &t1, ObserverPointer< T, Q > &t2)
types::manifold_id manifold_id
std_cxx26::inplace_vector< unsigned int, ReferenceCells::max_n_vertices< structdim >()> vertices
types::material_id material_id
types::boundary_id boundary_id
static unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
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()
std::vector< CellData< 2 > > boundary_quads
bool check_consistency(const unsigned int dim) const
std::vector< CellData< 1 > > boundary_lines
bool operator<(const SynchronousIterators< Iterators > &a, const SynchronousIterators< Iterators > &b)