deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
grid_tools.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2001 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_grid_tools_h
14#define dealii_grid_tools_h
15
16
17#include <deal.II/base/config.h>
18
21#include <deal.II/base/point.h>
22
24
26
28
30#include <deal.II/fe/mapping.h>
31
35#include <deal.II/grid/tria.h>
38
43
45
46#include <boost/archive/binary_iarchive.hpp>
47#include <boost/archive/binary_oarchive.hpp>
48#include <boost/random/mersenne_twister.hpp>
49#include <boost/serialization/array.hpp>
50#include <boost/serialization/vector.hpp>
51
52#ifdef DEAL_II_WITH_ZLIB
53# include <boost/iostreams/device/back_inserter.hpp>
54# include <boost/iostreams/filter/gzip.hpp>
55# include <boost/iostreams/filtering_stream.hpp>
56# include <boost/iostreams/stream.hpp>
57#endif
58
59#include <optional>
60#include <set>
61
62#ifdef DEAL_II_HAVE_CXX20
63# include <concepts>
64#endif
65
66
68
69// Forward declarations
70#ifndef DOXYGEN
71namespace parallel
72{
73 namespace distributed
74 {
75 template <int dim, int spacedim>
77 class Triangulation;
78 }
79} // namespace parallel
80
81namespace hp
82{
83 template <int, int>
84 class MappingCollection;
85}
86
87class SparsityPattern;
88
89namespace GridTools
90{
91 template <int dim, int spacedim>
92 class Cache;
93}
94#endif
95
96namespace internal
97{
98 template <int dim, int spacedim, typename MeshType>
101 {
102 public:
103#ifndef _MSC_VER
104 using type = typename MeshType::active_cell_iterator;
105#else
107#endif
108 };
109
110#ifdef _MSC_VER
111 template <int dim, int spacedim>
112 class ActiveCellIterator<dim, spacedim, DoFHandler<dim, spacedim>>
113 {
114 public:
115 using type =
117 };
118#endif
119} // namespace internal
120
129namespace GridTools
130{
217 template <int dim, typename Transformation, int spacedim>
219 (std::invocable<Transformation, Point<spacedim>> &&
220 std::assignable_from<
222 std::invoke_result_t<Transformation, Point<spacedim>>>))
223 void transform(const Transformation &transformation,
224 Triangulation<dim, spacedim> &triangulation);
225
232 template <int dim, int spacedim>
233 void
234 shift(const Tensor<1, spacedim> &shift_vector,
235 Triangulation<dim, spacedim> &triangulation);
236
237
248 template <int dim, int spacedim>
249 void
250 rotate(const double angle, Triangulation<dim, spacedim> &triangulation);
251
264 template <int dim>
265 void
266 rotate(const Tensor<1, 3, double> &axis,
267 const double angle,
268 Triangulation<dim, 3> &triangulation);
269
327 template <int dim>
328 void
329 laplace_transform(const std::map<unsigned int, Point<dim>> &new_points,
330 Triangulation<dim> &tria,
331 const Function<dim, double> *coefficient = nullptr,
332 const bool solve_for_absolute_positions = false);
333
341 template <int dim, int spacedim>
342 void
343 scale(const double scaling_factor,
344 Triangulation<dim, spacedim> &triangulation);
345
375 template <int dim, int spacedim>
376 void
378 const double factor,
379 Triangulation<dim, spacedim> &triangulation,
380 const bool keep_boundary = true,
381 const unsigned int seed = boost::random::mt19937::default_seed);
382
472 template <int dim, int spacedim>
473 void
474 regularize_corner_cells(Triangulation<dim, spacedim> &tria,
475 const double limit_angle_fraction = .75);
476
540 template <int dim, int spacedim>
541#ifndef DOXYGEN
542 std::tuple<
543 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
544 std::vector<std::vector<Point<dim>>>,
545 std::vector<std::vector<unsigned int>>>
546#else
547 return_type
548#endif
550 const Cache<dim, spacedim> &cache,
551 const std::vector<Point<spacedim>> &points,
553 &cell_hint =
555
589 template <int dim, int spacedim>
590#ifndef DOXYGEN
591 std::tuple<
592 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
593 std::vector<std::vector<Point<dim>>>,
594 std::vector<std::vector<unsigned int>>,
595 std::vector<unsigned int>>
596#else
597 return_type
598#endif
600 const Cache<dim, spacedim> &cache,
601 const std::vector<Point<spacedim>> &points,
603 &cell_hint =
605
694 template <int dim, int spacedim>
695#ifndef DOXYGEN
696 std::tuple<
697 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
698 std::vector<std::vector<Point<dim>>>,
699 std::vector<std::vector<unsigned int>>,
700 std::vector<std::vector<Point<spacedim>>>,
701 std::vector<std::vector<unsigned int>>>
702#else
703 return_type
704#endif
707 const std::vector<Point<spacedim>> &local_points,
708 const std::vector<std::vector<BoundingBox<spacedim>>> &global_bboxes,
709 const double tolerance = 1e-10,
710 const std::vector<bool> &marked_vertices = {},
711 const bool enforce_unique_mapping = true);
712
713 namespace internal
714 {
729 template <int dim, int spacedim>
731 {
733
740 void
742
746 unsigned int n_searched_points;
747
754 std::vector<std::tuple<std::pair<int, int>,
755 unsigned int,
756 unsigned int,
759 unsigned int>>
761
765 std::vector<unsigned int> send_ranks;
766
772 std::vector<unsigned int> send_ptrs;
773
784 std::vector<std::tuple<unsigned int, unsigned int, unsigned int>>
786
790 std::vector<unsigned int> recv_ranks;
791
797 std::vector<unsigned int> recv_ptrs;
798 };
799
809 template <int dim, int spacedim>
813 const std::vector<Point<spacedim>> &points,
814 const std::vector<std::vector<BoundingBox<spacedim>>> &global_bboxes,
815 const std::vector<bool> &marked_vertices,
816 const double tolerance,
817 const bool perform_handshake,
818 const bool enforce_unique_mapping = false);
819
820
828 template <int structdim, int spacedim>
830 {
835 std::array<::Point<spacedim>, structdim + 1>;
836
845 std::vector<std::tuple<std::pair<int, int>,
846 unsigned int,
847 unsigned int,
850
859 std::vector<std::tuple<unsigned int, unsigned int, IntersectionType>>
861
865 std::vector<unsigned int> recv_ptrs;
866
887 template <int dim>
889 spacedim>
891 const unsigned int n_points_1D,
893 const Mapping<dim, spacedim> &mapping,
894 std::vector<Quadrature<spacedim>> *mapped_quadratures_recv_comp =
895 nullptr,
896 const bool consistent_numbering_of_sender_and_receiver = false) const;
897
898 private:
906 std::map<unsigned int, std::vector<unsigned int>>
908 const std::vector<std::tuple<unsigned int, unsigned int, unsigned int>>
909 &point_recv_components,
910 const MPI_Comm comm) const;
911 };
912
920 template <int structdim, int dim, int spacedim>
923 const Cache<dim, spacedim> &cache,
924 const std::vector<std::vector<Point<spacedim>>> &intersection_requests,
925 const std::vector<std::vector<BoundingBox<spacedim>>> &global_bboxes,
926 const std::vector<bool> &marked_vertices,
927 const double tolerance);
928
929 } // namespace internal
930
940 template <int spacedim>
941 unsigned int
942 find_closest_vertex(const std::map<unsigned int, Point<spacedim>> &vertices,
943 const Point<spacedim> &p);
944
971 template <int dim, template <int, int> class MeshType, int spacedim>
973 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
974 unsigned int find_closest_vertex(
975 const MeshType<dim, spacedim> &mesh,
976 const Point<spacedim> &p,
977 const std::vector<bool> &marked_vertices = {});
978
1005 template <int dim, template <int, int> class MeshType, int spacedim>
1007 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1008 unsigned int find_closest_vertex(
1009 const Mapping<dim, spacedim> &mapping,
1010 const MeshType<dim, spacedim> &mesh,
1011 const Point<spacedim> &p,
1012 const std::vector<bool> &marked_vertices = {});
1013
1014
1037 template <typename MeshType>
1039#ifndef _MSC_VER
1040 std::vector<typename MeshType::active_cell_iterator>
1041#else
1042 std::vector<
1043 typename ::internal::ActiveCellIterator<MeshType::dimension,
1044 MeshType::space_dimension,
1045 MeshType>::type>
1046#endif
1047 find_cells_adjacent_to_vertex(const MeshType &container,
1048 const unsigned int vertex_index);
1049
1115 template <int dim, template <int, int> class MeshType, int spacedim>
1117 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1118#ifndef _MSC_VER
1119 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator, Point<dim>>
1120#else
1121 std::pair<typename ::internal::
1122 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1123 Point<dim>>
1124#endif
1126 const MeshType<dim, spacedim> &mesh,
1127 const Point<spacedim> &p,
1128 const std::vector<bool> &marked_vertices = {},
1129 const double tolerance = 1.e-10);
1130
1141 template <int dim, template <int, int> class MeshType, int spacedim>
1143 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1144#ifndef _MSC_VER
1145 typename MeshType<dim, spacedim>::active_cell_iterator
1146#else
1147 typename ::internal::
1148 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type
1149#endif
1150 find_active_cell_around_point(const MeshType<dim, spacedim> &mesh,
1151 const Point<spacedim> &p,
1152 const std::vector<bool> &marked_vertices = {},
1153 const double tolerance = 1.e-10);
1154
1161 template <int dim, int spacedim>
1162 std::pair<typename DoFHandler<dim, spacedim>::active_cell_iterator,
1163 Point<dim>>
1166 const DoFHandler<dim, spacedim> &mesh,
1167 const Point<spacedim> &p,
1168 const double tolerance = 1.e-10);
1169
1221 template <int dim, int spacedim>
1222 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
1223 Point<dim>>
1225 const Cache<dim, spacedim> &cache,
1226 const Point<spacedim> &p,
1229 const std::vector<bool> &marked_vertices = {},
1230 const double tolerance = 1.e-10);
1231
1248 template <int dim, template <int, int> class MeshType, int spacedim>
1250 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1251#ifndef _MSC_VER
1252 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator, Point<dim>>
1253#else
1254 std::pair<typename ::internal::
1255 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1256 Point<dim>>
1257#endif
1259 const Mapping<dim, spacedim> &mapping,
1260 const MeshType<dim, spacedim> &mesh,
1261 const Point<spacedim> &p,
1262 const std::vector<
1263 std::set<typename MeshType<dim, spacedim>::active_cell_iterator>>
1265 const std::vector<std::vector<Tensor<1, spacedim>>>
1266 &vertex_to_cell_centers,
1267 const typename MeshType<dim, spacedim>::active_cell_iterator &cell_hint =
1268 typename MeshType<dim, spacedim>::active_cell_iterator(),
1269 const std::vector<bool> &marked_vertices = {},
1270 const RTree<std::pair<Point<spacedim>, unsigned int>> &
1271 used_vertices_rtree = RTree<std::pair<Point<spacedim>, unsigned int>>{},
1272 const double tolerance = 1.e-10,
1273 const RTree<
1274 std::pair<BoundingBox<spacedim>,
1276 *relevant_cell_bounding_boxes_rtree = nullptr);
1277
1307 template <int dim, template <int, int> class MeshType, int spacedim>
1309 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1310#ifndef _MSC_VER
1311 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1312 Point<dim>>>
1313#else
1314 std::vector<std::pair<
1315 typename ::internal::
1316 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1317 Point<dim>>>
1318#endif
1320 const Mapping<dim, spacedim> &mapping,
1321 const MeshType<dim, spacedim> &mesh,
1322 const Point<spacedim> &p,
1323 const double tolerance,
1324 const std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1325 Point<dim>> &first_cell,
1326 const std::vector<
1327 std::set<typename MeshType<dim, spacedim>::active_cell_iterator>>
1328 *vertex_to_cells = nullptr);
1329
1339 template <int dim, template <int, int> class MeshType, int spacedim>
1341 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1342#ifndef _MSC_VER
1343 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1344 Point<dim>>>
1345#else
1346 std::vector<std::pair<
1347 typename ::internal::
1348 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1349 Point<dim>>>
1350#endif
1352 const Mapping<dim, spacedim> &mapping,
1353 const MeshType<dim, spacedim> &mesh,
1354 const Point<spacedim> &p,
1355 const double tolerance = 1e-10,
1356 const std::vector<bool> &marked_vertices = {});
1357
1381 template <typename MeshType>
1383 std::vector<typename MeshType::active_cell_iterator> get_active_child_cells(
1384 const typename MeshType::cell_iterator &cell);
1385
1412 template <typename MeshType>
1413 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1415 const typename MeshType::active_cell_iterator &cell,
1416 std::vector<typename MeshType::active_cell_iterator> &active_neighbors);
1417
1469 template <typename MeshType>
1470 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1471 std::
1472 vector<typename MeshType::active_cell_iterator> compute_active_cell_halo_layer(
1473 const MeshType &mesh,
1474 const std::function<bool(const typename MeshType::active_cell_iterator &)>
1475 &predicate);
1476
1477
1487 template <typename MeshType>
1488 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1489 std::
1490 vector<typename MeshType::cell_iterator> compute_cell_halo_layer_on_level(
1491 const MeshType &mesh,
1492 const std::function<bool(const typename MeshType::cell_iterator &)>
1493 &predicate,
1494 const unsigned int level);
1495
1496
1511 template <typename MeshType>
1512 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1513 std::vector<
1514 typename MeshType::
1515 active_cell_iterator> compute_ghost_cell_halo_layer(const MeshType &mesh);
1516
1567 template <typename MeshType>
1568 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1569 std::
1570 vector<typename MeshType::active_cell_iterator> compute_active_cell_layer_within_distance(
1571 const MeshType &mesh,
1572 const std::function<bool(const typename MeshType::active_cell_iterator &)>
1573 &predicate,
1574 const double layer_thickness);
1575
1600 template <typename MeshType>
1601 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1602 std::
1603 vector<typename MeshType::active_cell_iterator> compute_ghost_cell_layer_within_distance(
1604 const MeshType &mesh,
1605 const double layer_thickness);
1606
1679 template <typename MeshType>
1680 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1681 std::
1682 vector<BoundingBox<MeshType::space_dimension>> compute_mesh_predicate_bounding_box(
1683 const MeshType &mesh,
1684 const std::function<bool(const typename MeshType::active_cell_iterator &)>
1685 &predicate,
1686 const unsigned int refinement_level = 0,
1687 const bool allow_merge = false,
1688 const unsigned int max_boxes = numbers::invalid_unsigned_int);
1689
1717 template <int spacedim>
1718#ifndef DOXYGEN
1719 std::tuple<std::vector<std::vector<unsigned int>>,
1720 std::map<unsigned int, unsigned int>,
1721 std::map<unsigned int, std::vector<unsigned int>>>
1722#else
1723 return_type
1724#endif
1726 const std::vector<std::vector<BoundingBox<spacedim>>> &global_bboxes,
1727 const std::vector<Point<spacedim>> &points);
1728
1729
1764 template <int spacedim>
1765#ifndef DOXYGEN
1766 std::tuple<std::map<unsigned int, std::vector<unsigned int>>,
1767 std::map<unsigned int, unsigned int>,
1768 std::map<unsigned int, std::vector<unsigned int>>>
1769#else
1770 return_type
1771#endif
1773 const RTree<std::pair<BoundingBox<spacedim>, unsigned int>> &covering_rtree,
1774 const std::vector<Point<spacedim>> &points);
1775
1788 template <int dim, int spacedim>
1789 std::vector<std::vector<Tensor<1, spacedim>>>
1791 const Triangulation<dim, spacedim> &mesh,
1792 const std::vector<
1794 &vertex_to_cells);
1795
1796
1804 template <int dim, int spacedim>
1805 unsigned int
1808 const Point<spacedim> &position,
1809 const Mapping<dim, spacedim> &mapping =
1810 (ReferenceCells::get_hypercube<dim>()
1811#ifndef _MSC_VER
1812 .template get_default_linear_mapping<spacedim>()
1813#else
1815#endif
1816 ));
1817
1829 template <int dim, int spacedim>
1830 std::map<unsigned int, types::global_vertex_index>
1832 const Triangulation<dim, spacedim> &triangulation);
1833
1862 template <int dim, int spacedim>
1863 std::vector<types::global_vertex_index>
1865 const Triangulation<dim, spacedim> &serial_tria,
1866 const Triangulation<dim, spacedim> &parallel_tria);
1867
1894 template <int dim, int spacedim>
1895 void
1896 partition_triangulation(const unsigned int n_partitions,
1897 Triangulation<dim, spacedim> &triangulation,
1898 const SparsityTools::Partitioner partitioner =
1900
1911 template <int dim, int spacedim>
1912 void
1913 partition_triangulation(const unsigned int n_partitions,
1914 const std::vector<unsigned int> &cell_weights,
1915 Triangulation<dim, spacedim> &triangulation,
1916 const SparsityTools::Partitioner partitioner =
1918
1964 template <int dim, int spacedim>
1965 void
1966 partition_triangulation(const unsigned int n_partitions,
1967 const SparsityPattern &cell_connection_graph,
1968 Triangulation<dim, spacedim> &triangulation,
1969 const SparsityTools::Partitioner partitioner =
1971
1982 template <int dim, int spacedim>
1983 void
1984 partition_triangulation(const unsigned int n_partitions,
1985 const std::vector<unsigned int> &cell_weights,
1986 const SparsityPattern &cell_connection_graph,
1987 Triangulation<dim, spacedim> &triangulation,
1988 const SparsityTools::Partitioner partitioner =
1990
2005 template <int dim, int spacedim>
2006 void
2007 partition_triangulation_zorder(const unsigned int n_partitions,
2008 Triangulation<dim, spacedim> &triangulation,
2009 const bool group_siblings = true);
2010
2022 template <int dim, int spacedim>
2023 void
2025
2033 template <int dim, int spacedim>
2034 std::vector<types::subdomain_id>
2036 const std::vector<CellId> &cell_ids);
2037
2048 template <int dim, int spacedim>
2049 void
2051 std::vector<types::subdomain_id> &subdomain);
2052
2067 template <int dim, int spacedim>
2068 unsigned int
2070 const Triangulation<dim, spacedim> &triangulation,
2071 const types::subdomain_id subdomain);
2072
2102 template <int dim, int spacedim>
2103 std::vector<bool>
2105
2155 template <typename MeshType>
2157 std::vector<typename MeshType::active_cell_iterator> get_patch_around_cell(
2158 const typename MeshType::active_cell_iterator &cell);
2159
2160
2182 template <class Container>
2183 std::vector<typename Container::cell_iterator>
2185 const std::vector<typename Container::active_cell_iterator> &patch_cells);
2186
2253 template <class Container>
2254 void
2256 const std::vector<typename Container::active_cell_iterator> &patch,
2258 &local_triangulation,
2259 std::map<
2260 typename Triangulation<Container::dimension,
2261 Container::space_dimension>::active_cell_iterator,
2262 typename Container::active_cell_iterator> &patch_to_global_tria_map);
2263
2295 template <int dim, int spacedim>
2296 std::map<
2298 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
2300
2301
2316 template <typename CellIterator>
2318 {
2322 CellIterator cell[2];
2323
2328 unsigned int face_idx[2];
2329
2336
2350
2354 std::size_t
2356 };
2357
2358
2382 template <typename FaceIterator>
2383 std::optional<types::geometric_orientation>
2385 const FaceIterator &face1,
2386 const FaceIterator &face2,
2387 const unsigned int direction,
2390 const FullMatrix<double> &matrix = FullMatrix<double>(),
2391 const double abs_tol = 1e-10);
2392
2452 template <typename MeshType>
2455 const MeshType &mesh,
2456 const types::boundary_id b_id1,
2457 const types::boundary_id b_id2,
2458 const unsigned int direction,
2460 &matched_pairs,
2463 const FullMatrix<double> &matrix = FullMatrix<double>(),
2464 const double abs_tol = 1e-10);
2465
2466
2487 template <typename MeshType>
2490 const MeshType &mesh,
2491 const types::boundary_id b_id,
2492 const unsigned int direction,
2493 std::vector<PeriodicFacePair<typename MeshType::cell_iterator>>
2494 &matched_pairs,
2495 const ::Tensor<1, MeshType::space_dimension> &offset =
2496 ::Tensor<1, MeshType::space_dimension>(),
2497 const FullMatrix<double> &matrix = FullMatrix<double>(),
2498 const double abs_tol = 1e-10);
2499
2526 template <int dim, int spacedim>
2527 void
2528 copy_boundary_to_manifold_id(Triangulation<dim, spacedim> &tria,
2529 const bool reset_boundary_ids = false);
2530
2552 template <int dim, int spacedim>
2553 void
2555 const std::vector<types::boundary_id> &src_boundary_ids,
2556 const std::vector<types::manifold_id> &dst_manifold_ids,
2557 Triangulation<dim, spacedim> &tria,
2558 const std::vector<types::boundary_id> &reset_boundary_ids = {});
2559
2589 template <int dim, int spacedim>
2590 void
2592 const bool compute_face_ids = false);
2593
2618 template <int dim, int spacedim>
2619 void
2622 const std::function<types::manifold_id(
2623 const std::set<types::manifold_id> &)> &disambiguation_function =
2624 [](const std::set<types::manifold_id> &manifold_ids) {
2625 if (manifold_ids.size() == 1)
2626 return *manifold_ids.begin();
2627 else
2629 },
2630 bool overwrite_only_flat_manifold_ids = true);
2719 template <typename DataType, typename MeshType>
2722 const MeshType &mesh,
2723 const std::function<std::optional<DataType>(
2724 const typename MeshType::active_cell_iterator &)> &pack,
2725 const std::function<void(const typename MeshType::active_cell_iterator &,
2726 const DataType &)> &unpack,
2727 const std::function<bool(const typename MeshType::active_cell_iterator &)>
2728 &cell_filter =
2729 always_return<typename MeshType::active_cell_iterator, bool>{true});
2730
2743 template <typename DataType, typename MeshType>
2746 const MeshType &mesh,
2747 const std::function<std::optional<DataType>(
2748 const typename MeshType::level_cell_iterator &)> &pack,
2749 const std::function<void(const typename MeshType::level_cell_iterator &,
2750 const DataType &)> &unpack,
2751 const std::function<bool(const typename MeshType::level_cell_iterator &)> &
2752 cell_filter = always_return<typename MeshType::level_cell_iterator, bool>{
2753 true});
2754
2755 /* Exchange with all processors of the MPI communicator @p mpi_communicator the vector of bounding
2756 * boxes @p local_bboxes.
2757 *
2758 * This function is meant to exchange bounding boxes describing the locally
2759 * owned cells in a distributed triangulation obtained with the function
2760 * GridTools::compute_mesh_predicate_bounding_box .
2761 *
2762 * The output vector's size is the number of processes of the MPI
2763 * communicator:
2764 * its i-th entry contains the vector @p local_bboxes of the i-th process.
2765 */
2766 template <int spacedim>
2767 std::vector<std::vector<BoundingBox<spacedim>>>
2769 const std::vector<BoundingBox<spacedim>> &local_bboxes,
2770 const MPI_Comm mpi_communicator);
2771
2804 template <int spacedim>
2807 const std::vector<BoundingBox<spacedim>> &local_description,
2808 const MPI_Comm mpi_communicator);
2809
2827 template <int dim, int spacedim>
2828 void
2830 const Triangulation<dim, spacedim> &tria,
2831 std::map<unsigned int, std::vector<unsigned int>> &coinciding_vertex_groups,
2832 std::map<unsigned int, unsigned int> &vertex_to_coinciding_vertex_group);
2833
2853 template <int dim, int spacedim>
2854 std::map<unsigned int, std::set<::types::subdomain_id>>
2856 const Triangulation<dim, spacedim> &tria);
2857
2878 template <int dim, typename VectorType>
2880 {
2881 public:
2885 using value_type = typename VectorType::value_type;
2886
2891 const FiniteElement<dim, dim> &fe,
2892 const unsigned int n_subdivisions = 1,
2893 const double tolerance = 1e-10);
2894
2905 void
2906 process(const DoFHandler<dim> &background_dof_handler,
2907 const VectorType &ls_vector,
2908 const double iso_level,
2909 std::vector<Point<dim>> &vertices,
2910 std::vector<CellData<dim == 1 ? 1 : dim - 1>> &cells) const;
2911
2916 void
2917 process(const DoFHandler<dim> &background_dof_handler,
2918 const VectorType &ls_vector,
2919 const double iso_level,
2920 std::vector<Point<dim>> &vertices) const;
2921
2931 void
2933 const VectorType &ls_vector,
2934 const double iso_level,
2935 std::vector<Point<dim>> &vertices,
2936 std::vector<CellData<dim == 1 ? 1 : dim - 1>> &cells) const;
2942 void
2944 const VectorType &ls_vector,
2945 const double iso_level,
2946 std::vector<Point<dim>> &vertices) const;
2947
2948 private:
2953 static Quadrature<dim>
2954 create_quadrature_rule(const unsigned int n_subdivisions);
2955
2959 void
2960 process_cell(std::vector<value_type> &ls_values,
2961 const std::vector<Point<dim>> &points,
2962 const double iso_level,
2963 std::vector<Point<dim>> &vertices,
2964 std::vector<CellData<dim == 1 ? 1 : dim - 1>> &cells,
2965 const bool write_back_cell_data = true) const;
2966
2970 void
2971 process_sub_cell(const std::vector<value_type> &,
2972 const std::vector<Point<1>> &,
2973 const std::vector<unsigned int> &,
2974 const double,
2975 std::vector<Point<1>> &,
2976 std::vector<CellData<1>> &,
2977 const bool) const
2978 {
2980 }
2981
2988 void
2989 process_sub_cell(const std::vector<value_type> &ls_values,
2990 const std::vector<Point<2>> &points,
2991 const std::vector<unsigned int> &mask,
2992 const double iso_level,
2993 std::vector<Point<2>> &vertices,
2994 std::vector<CellData<1>> &cells,
2995 const bool write_back_cell_data) const;
2996
3000 void
3001 process_sub_cell(const std::vector<value_type> &ls_values,
3002 const std::vector<Point<3>> &points,
3003 const std::vector<unsigned int> &mask,
3004 const double iso_level,
3005 std::vector<Point<3>> &vertices,
3006 std::vector<CellData<2>> &cells,
3007 const bool write_back_cell_data) const;
3008
3013 const unsigned int n_subdivisions;
3014
3019 const double tolerance;
3020
3026 };
3027
3028
3029
3039 int,
3040 << "The number of partitions you gave is " << arg1
3041 << ", but must be greater than zero.");
3046 int,
3047 << "The subdomain id " << arg1
3048 << " has no cells associated with it.");
3053
3058 double,
3059 << "The scaling factor must be positive, but it is " << arg1
3060 << '.');
3061
3066 unsigned int,
3067 << "The given vertex with index " << arg1
3068 << " is not used in the given triangulation.");
3069
3072} /*namespace GridTools*/
3073
3074/* ----------------- Template function --------------- */
3075
3076#ifndef DOXYGEN
3077
3078namespace GridTools
3079{
3080 template <int dim>
3081 double
3083 const std::vector<Point<dim>> &all_vertices,
3084 const unsigned int (&indices)[GeometryInfo<dim>::vertices_per_cell])
3085 {
3086 // We forward call to the ArrayView version:
3089 return cell_measure(all_vertices, view);
3090 }
3091
3092
3093
3094 template <int dim, typename Transformation, int spacedim>
3096 (std::invocable<Transformation, Point<spacedim>> &&
3097 std::assignable_from<
3099 std::invoke_result_t<Transformation, Point<spacedim>>>))
3100 void transform(const Transformation &transformation,
3101 Triangulation<dim, spacedim> &triangulation)
3102 {
3103 std::vector<bool> treated_vertices(triangulation.n_vertices(), false);
3104
3105 // loop over all active cells, and
3106 // transform those vertices that
3107 // have not yet been touched. note
3108 // that we get to all vertices in
3109 // the triangulation by only
3110 // visiting the active cells.
3112 cell = triangulation.begin_active(),
3113 endc = triangulation.end();
3114 for (; cell != endc; ++cell)
3115 for (const unsigned int v : cell->vertex_indices())
3116 if (treated_vertices[cell->vertex_index(v)] == false)
3117 {
3118 // transform this vertex
3119 cell->vertex(v) = transformation(cell->vertex(v));
3120 // and mark it as treated
3121 treated_vertices[cell->vertex_index(v)] = true;
3122 };
3123
3124
3125 // now fix any vertices on hanging nodes so that we don't create any holes
3126 if (dim == 2)
3127 {
3129 cell = triangulation.begin_active(),
3130 endc = triangulation.end();
3131 for (; cell != endc; ++cell)
3132 for (const unsigned int face : cell->face_indices())
3133 if (cell->face(face)->has_children() &&
3134 !cell->face(face)->at_boundary())
3135 {
3136 Assert(cell->reference_cell() ==
3137 ReferenceCells::get_hypercube<dim>(),
3139
3140 // this line has children
3141 cell->face(face)->child(0)->vertex(1) =
3142 (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) /
3143 2.0;
3144 }
3145 }
3146 else if (dim == 3)
3147 {
3149 cell = triangulation.begin_active(),
3150 endc = triangulation.end();
3151 for (; cell != endc; ++cell)
3152 for (const unsigned int face : cell->face_indices())
3153 if (cell->face(face)->has_children() &&
3154 !cell->face(face)->at_boundary())
3155 {
3156 if (static_cast<std::uint8_t>(
3157 cell->face(face)->refinement_case()) ==
3159 {
3160 Assert(cell->reference_cell() ==
3161 ReferenceCells::get_hypercube<dim>(),
3163
3164 // this face has hanging nodes
3165 cell->face(face)->child(0)->vertex(1) =
3166 (cell->face(face)->vertex(0) +
3167 cell->face(face)->vertex(1)) /
3168 2.0;
3169 cell->face(face)->child(0)->vertex(2) =
3170 (cell->face(face)->vertex(0) +
3171 cell->face(face)->vertex(2)) /
3172 2.0;
3173 cell->face(face)->child(1)->vertex(3) =
3174 (cell->face(face)->vertex(1) +
3175 cell->face(face)->vertex(3)) /
3176 2.0;
3177 cell->face(face)->child(2)->vertex(3) =
3178 (cell->face(face)->vertex(2) +
3179 cell->face(face)->vertex(3)) /
3180 2.0;
3181
3182 // center of the face
3183 cell->face(face)->child(0)->vertex(3) =
3184 (cell->face(face)->vertex(0) +
3185 cell->face(face)->vertex(1) +
3186 cell->face(face)->vertex(2) +
3187 cell->face(face)->vertex(3)) /
3188 4.0;
3189 }
3190 else
3191 {
3192 // Special case for anisotropic refinement
3193 for (unsigned int line = 0;
3194 line < GeometryInfo<dim - 1>::faces_per_cell;
3195 line++)
3196 if (cell->face(face)->line(line)->has_children())
3197 cell->face(face)->line(line)->child(0)->vertex(1) =
3198 (cell->face(face)->line(line)->vertex(0) +
3199 cell->face(face)->line(line)->vertex(1)) /
3200 2.0;
3201 }
3202 }
3203 }
3204
3205 // Make sure FEValues notices that the mesh has changed
3206 triangulation.signals.mesh_movement();
3207 }
3208
3209
3210
3211 template <typename MeshType>
3213 std::vector<typename MeshType::active_cell_iterator> get_active_child_cells(
3214 const typename MeshType::cell_iterator &cell)
3215 {
3216 std::vector<typename MeshType::active_cell_iterator> child_cells;
3217
3218 if (cell->has_children())
3219 {
3220 for (unsigned int child = 0; child < cell->n_children(); ++child)
3221 if (cell->child(child)->has_children())
3222 {
3223 const std::vector<typename MeshType::active_cell_iterator>
3224 children = get_active_child_cells<MeshType>(cell->child(child));
3225 child_cells.insert(child_cells.end(),
3226 children.begin(),
3227 children.end());
3228 }
3229 else
3230 child_cells.push_back(cell->child(child));
3231 }
3232
3233 return child_cells;
3234 }
3235
3236
3237
3238 template <typename MeshType>
3241 const typename MeshType::active_cell_iterator &cell,
3242 std::vector<typename MeshType::active_cell_iterator> &active_neighbors)
3243 {
3244 active_neighbors.clear();
3245 for (const unsigned int n : cell->face_indices())
3246 if (!cell->at_boundary(n))
3247 {
3248 if (MeshType::dimension == 1)
3249 {
3250 // check children of neighbor. note
3251 // that in 1d children of the neighbor
3252 // may be further refined. In 1d the
3253 // case is simple since we know what
3254 // children bound to the present cell
3255 typename MeshType::cell_iterator neighbor_child =
3256 cell->neighbor(n);
3257 if (!neighbor_child->is_active())
3258 {
3259 while (neighbor_child->has_children())
3260 neighbor_child = neighbor_child->child(n == 0 ? 1 : 0);
3261
3262 Assert(neighbor_child->neighbor(n == 0 ? 1 : 0) == cell,
3264 }
3265 active_neighbors.push_back(neighbor_child);
3266 }
3267 else
3268 {
3269 if (cell->face(n)->has_children())
3270 // this neighbor has children. find
3271 // out which border to the present
3272 // cell
3273 for (unsigned int c = 0;
3274 c < cell->face(n)->n_active_descendants();
3275 ++c)
3276 active_neighbors.push_back(
3277 cell->neighbor_child_on_subface(n, c));
3278 else
3279 {
3280 // the neighbor must be active
3281 // himself
3282 Assert(cell->neighbor(n)->is_active(), ExcInternalError());
3283 active_neighbors.push_back(cell->neighbor(n));
3284 }
3285 }
3286 }
3287 }
3288
3289
3290
3291 template <typename CellIterator>
3292 std::size_t
3294 {
3295 return sizeof(*this) + matrix.memory_consumption();
3296 }
3297
3298
3299
3300 namespace internal
3301 {
3302 template <typename DataType,
3303 typename MeshType,
3304 typename MeshCellIteratorType>
3306 inline void exchange_cell_data(
3307 const MeshType &mesh,
3308 const std::function<std::optional<DataType>(const MeshCellIteratorType &)>
3309 &pack,
3310 const std::function<void(const MeshCellIteratorType &, const DataType &)>
3311 &unpack,
3312 const std::function<bool(const MeshCellIteratorType &)> &cell_filter,
3313 const std::function<void(
3314 const std::function<void(const MeshCellIteratorType &,
3315 const types::subdomain_id)> &)> &process_cells,
3316 const std::function<std::set<types::subdomain_id>(
3317 const parallel::TriangulationBase<MeshType::dimension,
3318 MeshType::space_dimension> &)>
3319 &compute_ghost_owners)
3320 {
3321# ifndef DEAL_II_WITH_MPI
3322 (void)mesh;
3323 (void)pack;
3324 (void)unpack;
3325 (void)cell_filter;
3326 (void)process_cells;
3327 (void)compute_ghost_owners;
3328 Assert(false, ExcNeedsMPI());
3329# else
3330 constexpr int dim = MeshType::dimension;
3331 constexpr int spacedim = MeshType::space_dimension;
3332 auto tria =
3333 dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(
3334 &mesh.get_triangulation());
3335 Assert(
3336 tria != nullptr,
3337 ExcMessage(
3338 "The function exchange_cell_data_to_ghosts() only works with parallel triangulations."));
3339
3340 if (const auto tria = dynamic_cast<
3342 &mesh.get_triangulation()))
3343 {
3344 Assert(
3345 tria->with_artificial_cells(),
3346 ExcMessage(
3347 "The functions GridTools::exchange_cell_data_to_ghosts() and "
3348 "GridTools::exchange_cell_data_to_level_ghosts() can only "
3349 "operate on a single layer of ghost cells. However, you have "
3350 "given a Triangulation object of type "
3351 "parallel::shared::Triangulation without artificial cells "
3352 "resulting in an arbitrary number of ghost layers. "
3353 "To use this function for a Triangulation object of type "
3354 "parallel::shared::Triangulation, make sure to create the "
3355 "Triangulation object with allow_artificial_cells set to true. "
3356 "This results in a parallel::shared::Triangulation with only "
3357 "a single layer of ghost cells."));
3358 }
3359
3360 // build list of cells to request for each neighbor
3361 std::set<types::subdomain_id> ghost_owners = compute_ghost_owners(*tria);
3362 std::map<types::subdomain_id, std::vector<CellId::binary_type>>
3363 neighbor_cell_list;
3364
3365 for (const auto ghost_owner : ghost_owners)
3366 neighbor_cell_list[ghost_owner] = {};
3367
3368 process_cells([&](const auto &cell, const auto key) -> void {
3369 if (cell_filter(cell))
3370 {
3371 neighbor_cell_list[key].emplace_back(
3372 cell->id().template to_binary<spacedim>());
3373 }
3374 });
3375
3376 Assert(ghost_owners.size() == neighbor_cell_list.size(),
3378
3379
3380 // Before sending & receiving, make sure we protect this section with
3381 // a mutex:
3384 mutex, tria->get_mpi_communicator());
3385
3386 const int mpi_tag =
3388 const int mpi_tag_reply =
3390
3391 // send our requests
3392 std::vector<MPI_Request> requests(ghost_owners.size());
3393 {
3394 unsigned int idx = 0;
3395 for (const auto &it : neighbor_cell_list)
3396 {
3397 // send the data about the relevant cells
3398 const int ierr = MPI_Isend(it.second.data(),
3399 it.second.size() * sizeof(it.second[0]),
3400 MPI_BYTE,
3401 it.first,
3402 mpi_tag,
3403 tria->get_mpi_communicator(),
3404 &requests[idx]);
3405 AssertThrowMPI(ierr);
3406 ++idx;
3407 }
3408 }
3409
3410 // receive requests and reply with the results
3411 std::vector<MPI_Request> reply_requests(ghost_owners.size());
3412 std::vector<std::vector<char>> sendbuffers(ghost_owners.size());
3413
3414 for (unsigned int idx = 0; idx < ghost_owners.size(); ++idx)
3415 {
3416 MPI_Status status;
3417 int ierr = MPI_Probe(MPI_ANY_SOURCE,
3418 mpi_tag,
3419 tria->get_mpi_communicator(),
3420 &status);
3421 AssertThrowMPI(ierr);
3422
3423 int len;
3424 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3425 AssertThrowMPI(ierr);
3426 Assert(len % sizeof(typename CellId::binary_type) == 0,
3428
3429 const unsigned int n_cells = len / sizeof(CellId::binary_type);
3430 std::vector<CellId::binary_type> cells_with_requests(n_cells);
3431 std::vector<DataType> data_to_send;
3432 data_to_send.reserve(n_cells);
3433 std::vector<bool> cell_carries_data(n_cells, false);
3434
3435 ierr = MPI_Recv(cells_with_requests.data(),
3436 len,
3437 MPI_BYTE,
3438 status.MPI_SOURCE,
3439 status.MPI_TAG,
3440 tria->get_mpi_communicator(),
3441 &status);
3442 AssertThrowMPI(ierr);
3443
3444 // store data for each cell
3445 for (unsigned int c = 0; c < n_cells; ++c)
3446 {
3447 const auto cell =
3448 tria->create_cell_iterator(CellId(cells_with_requests[c]));
3449
3450 MeshCellIteratorType mesh_it(tria,
3451 cell->level(),
3452 cell->index(),
3453 &mesh);
3454
3455 std::optional<DataType> data = pack(mesh_it);
3456 if (data)
3457 {
3458 data_to_send.emplace_back(std::move(*data));
3459 cell_carries_data[c] = true;
3460 }
3461 }
3462
3463 // collect data for sending the reply in a buffer
3464
3465 // (a) make room for storing the local offsets in case we receive
3466 // other data
3467 sendbuffers[idx].resize(sizeof(std::size_t));
3468
3469 // (b) append the actual data and store how much memory it
3470 // corresponds to, which we then insert into the leading position of
3471 // the sendbuffer
3472 std::size_t size_of_send =
3473 Utilities::pack(data_to_send,
3474 sendbuffers[idx],
3475 /*enable_compression*/ false);
3476 std::memcpy(sendbuffers[idx].data(),
3477 &size_of_send,
3478 sizeof(std::size_t));
3479
3480 // (c) append information of certain cells that got left out in case
3481 // we need it
3482 if (data_to_send.size() < n_cells)
3483 Utilities::pack(cell_carries_data,
3484 sendbuffers[idx],
3485 /*enable_compression*/ false);
3486
3487 // send data
3488 ierr = MPI_Isend(sendbuffers[idx].data(),
3489 sendbuffers[idx].size(),
3490 MPI_BYTE,
3491 status.MPI_SOURCE,
3492 mpi_tag_reply,
3493 tria->get_mpi_communicator(),
3494 &reply_requests[idx]);
3495 AssertThrowMPI(ierr);
3496 }
3497
3498 // finally receive the replies
3499 std::vector<char> receive;
3500 for (unsigned int id = 0; id < neighbor_cell_list.size(); ++id)
3501 {
3502 MPI_Status status;
3503 int ierr = MPI_Probe(MPI_ANY_SOURCE,
3504 mpi_tag_reply,
3505 tria->get_mpi_communicator(),
3506 &status);
3507 AssertThrowMPI(ierr);
3508
3509 int len;
3510 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3511 AssertThrowMPI(ierr);
3512
3513 receive.resize(len);
3514
3515 ierr = MPI_Recv(receive.data(),
3516 len,
3517 MPI_BYTE,
3518 status.MPI_SOURCE,
3519 status.MPI_TAG,
3520 tria->get_mpi_communicator(),
3521 &status);
3522 AssertThrowMPI(ierr);
3523
3524 // (a) first determine the length of the data section in the
3525 // received buffer
3526 auto data_iterator = receive.begin();
3527 std::size_t size_of_received_data =
3528 Utilities::unpack<std::size_t>(data_iterator,
3529 data_iterator + sizeof(std::size_t));
3530 data_iterator += sizeof(std::size_t);
3531
3532 // (b) unpack the data section in the indicated region
3533 auto received_data = Utilities::unpack<std::vector<DataType>>(
3534 data_iterator,
3535 data_iterator + size_of_received_data,
3536 /*enable_compression*/ false);
3537 data_iterator += size_of_received_data;
3538
3539 // (c) check if the received data contained fewer entries than the
3540 // number of cells we identified in the beginning, in which case we
3541 // need to extract the boolean vector with the relevant information
3542 const std::vector<CellId::binary_type> &this_cell_list =
3543 neighbor_cell_list[status.MPI_SOURCE];
3544 AssertIndexRange(received_data.size(), this_cell_list.size() + 1);
3545 std::vector<bool> cells_with_data;
3546 if (received_data.size() < this_cell_list.size())
3547 {
3548 cells_with_data = Utilities::unpack<std::vector<bool>>(
3549 data_iterator, receive.end(), /*enable_compression*/ false);
3550 AssertDimension(cells_with_data.size(), this_cell_list.size());
3551 }
3552
3553 // (d) go through the received data and call the user-provided
3554 // unpack function
3555 auto received_data_iterator = received_data.begin();
3556 for (unsigned int c = 0; c < this_cell_list.size(); ++c)
3557 if (cells_with_data.empty() || cells_with_data[c])
3558 {
3560 tria_cell = tria->create_cell_iterator(this_cell_list[c]);
3561
3562 MeshCellIteratorType cell(tria,
3563 tria_cell->level(),
3564 tria_cell->index(),
3565 &mesh);
3566
3567 unpack(cell, *received_data_iterator);
3568 ++received_data_iterator;
3569 }
3570 }
3571
3572 // make sure that all communication is finished
3573 // when we leave this function.
3574 if (requests.size() > 0)
3575 {
3576 const int ierr =
3577 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
3578 AssertThrowMPI(ierr);
3579 }
3580 if (reply_requests.size() > 0)
3581 {
3582 const int ierr = MPI_Waitall(reply_requests.size(),
3583 reply_requests.data(),
3584 MPI_STATUSES_IGNORE);
3585 AssertThrowMPI(ierr);
3586 }
3587
3588
3589# endif // DEAL_II_WITH_MPI
3590 }
3591
3592 } // namespace internal
3593
3594 template <typename DataType, typename MeshType>
3596 inline void exchange_cell_data_to_ghosts(
3597 const MeshType &mesh,
3598 const std::function<std::optional<DataType>(
3599 const typename MeshType::active_cell_iterator &)> &pack,
3600 const std::function<void(const typename MeshType::active_cell_iterator &,
3601 const DataType &)> &unpack,
3602 const std::function<bool(const typename MeshType::active_cell_iterator &)>
3603 &cell_filter)
3604 {
3605# ifndef DEAL_II_WITH_MPI
3606 (void)mesh;
3607 (void)pack;
3608 (void)unpack;
3609 (void)cell_filter;
3610 Assert(false, ExcNeedsMPI());
3611# else
3612 internal::exchange_cell_data<DataType,
3613 MeshType,
3614 typename MeshType::active_cell_iterator>(
3615 mesh,
3616 pack,
3617 unpack,
3618 cell_filter,
3619 [&](const auto &process) {
3620 for (const auto &cell : mesh.active_cell_iterators())
3621 if (cell->is_ghost())
3622 process(cell, cell->subdomain_id());
3623 },
3624 [](const auto &tria) { return tria.ghost_owners(); });
3625# endif
3626 }
3627
3628
3629
3630 template <typename DataType, typename MeshType>
3633 const MeshType &mesh,
3634 const std::function<std::optional<DataType>(
3635 const typename MeshType::level_cell_iterator &)> &pack,
3636 const std::function<void(const typename MeshType::level_cell_iterator &,
3637 const DataType &)> &unpack,
3638 const std::function<bool(const typename MeshType::level_cell_iterator &)>
3639 &cell_filter)
3640 {
3641# ifndef DEAL_II_WITH_MPI
3642 (void)mesh;
3643 (void)pack;
3644 (void)unpack;
3645 (void)cell_filter;
3646 Assert(false, ExcNeedsMPI());
3647# else
3648 internal::exchange_cell_data<DataType,
3649 MeshType,
3650 typename MeshType::level_cell_iterator>(
3651 mesh,
3652 pack,
3653 unpack,
3654 cell_filter,
3655 [&](const auto &process) {
3656 for (const auto &cell : mesh.cell_iterators())
3657 if (cell->is_ghost_on_level())
3658 process(cell, cell->level_subdomain_id());
3659 },
3660 [](const auto &tria) { return tria.level_ghost_owners(); });
3661# endif
3662 }
3663} // namespace GridTools
3664
3665#endif // DOXYGEN
3666
3668
3669#endif
std::array< std::uint64_t, 3 > binary_type
Definition cell_id.h:71
typename VectorType::value_type value_type
const unsigned int n_subdivisions
static Quadrature< dim > create_quadrature_rule(const unsigned int n_subdivisions)
void process_cell(const typename DoFHandler< dim >::active_cell_iterator &cell, const VectorType &ls_vector, const double iso_level, std::vector< Point< dim > > &vertices, std::vector< CellData< dim==1 ? 1 :dim - 1 > > &cells) const
void process_sub_cell(const std::vector< value_type > &, const std::vector< Point< 1 > > &, const std::vector< unsigned int > &, const double, std::vector< Point< 1 > > &, std::vector< CellData< 1 > > &, const bool) const
void process(const DoFHandler< dim > &background_dof_handler, const VectorType &ls_vector, const double iso_level, std::vector< Point< dim > > &vertices, std::vector< CellData< dim==1 ? 1 :dim - 1 > > &cells) const
Abstract base class for mapping classes.
Definition mapping.h:318
Definition point.h:111
cell_iterator create_cell_iterator(const CellId &cell_id) const
virtual MPI_Comm get_mpi_communicator() const
typename MeshType::active_cell_iterator type
Definition grid_tools.h:104
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:249
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
unsigned int level
Definition grid_out.cc:4642
unsigned int vertex_indices[2]
#define DeclException0(Exception0)
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcNeedsMPI()
static ::ExceptionBase & ExcNonExistentSubdomain(int arg1)
#define Assert(cond, exc)
static ::ExceptionBase & ExcVertexNotUsed(unsigned int arg1)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcTriangulationHasBeenRefined()
#define DeclException1(Exception1, type1, outsequence)
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
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={})
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)
std::vector< index_type > data
Definition mpi.cc:734
std::size_t size
Definition mpi.cc:733
const MPI_Comm comm
Definition mpi.cc:912
DistributedComputePointLocationsInternal< dim, spacedim > distributed_compute_point_locations(const GridTools::Cache< dim, spacedim > &cache, const std::vector< Point< spacedim > > &points, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bboxes, const std::vector< bool > &marked_vertices, const double tolerance, const bool perform_handshake, const bool enforce_unique_mapping=false)
DistributedComputeIntersectionLocationsInternal< structdim, spacedim > distributed_compute_intersection_locations(const Cache< dim, spacedim > &cache, const std::vector< std::vector< Point< spacedim > > > &intersection_requests, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bboxes, const std::vector< bool > &marked_vertices, const double tolerance)
std::vector< BoundingBox< MeshType::space_dimension > > compute_mesh_predicate_bounding_box(const MeshType &mesh, const std::function< bool(const typename MeshType::active_cell_iterator &)> &predicate, const unsigned int refinement_level=0, const bool allow_merge=false, const unsigned int max_boxes=numbers::invalid_unsigned_int)
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
RTree< std::pair< BoundingBox< spacedim >, unsigned int > > build_global_description_tree(const std::vector< BoundingBox< spacedim > > &local_description, const MPI_Comm mpi_communicator)
std::vector< typename MeshType::active_cell_iterator > get_active_child_cells(const typename MeshType::cell_iterator &cell)
void partition_triangulation_zorder(const unsigned int n_partitions, Triangulation< dim, spacedim > &triangulation, const bool group_siblings=true)
std::vector< typename Container::cell_iterator > get_cells_at_coarsest_common_level(const std::vector< typename Container::active_cell_iterator > &patch_cells)
void rotate(const double angle, Triangulation< dim, spacedim > &triangulation)
return_type compute_point_locations(const Cache< dim, spacedim > &cache, const std::vector< Point< spacedim > > &points, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell_hint=typename Triangulation< dim, spacedim >::active_cell_iterator())
void collect_periodic_faces(const MeshType &mesh, const types::boundary_id b_id1, const types::boundary_id b_id2, const unsigned int direction, std::vector< PeriodicFacePair< typename MeshType::cell_iterator > > &matched_pairs, const Tensor< 1, MeshType::space_dimension > &offset=::Tensor< 1, MeshType::space_dimension >(), const FullMatrix< double > &matrix=FullMatrix< double >(), const double abs_tol=1e-10)
unsigned int find_closest_vertex(const std::map< unsigned int, Point< spacedim > > &vertices, const Point< spacedim > &p)
void transform(const Transformation &transformation, Triangulation< dim, spacedim > &triangulation)
std::pair< typename MeshType< dim, spacedim >::active_cell_iterator, Point< dim > > find_active_cell_around_point(const Mapping< dim, spacedim > &mapping, const MeshType< dim, spacedim > &mesh, const Point< spacedim > &p, const std::vector< bool > &marked_vertices={}, const double tolerance=1.e-10)
void get_active_neighbors(const typename MeshType::active_cell_iterator &cell, std::vector< typename MeshType::active_cell_iterator > &active_neighbors)
std::vector< bool > get_locally_owned_vertices(const Triangulation< dim, spacedim > &triangulation)
std::vector< types::global_vertex_index > parallel_to_serial_vertex_indices(const Triangulation< dim, spacedim > &serial_tria, const Triangulation< dim, spacedim > &parallel_tria)
void regularize_corner_cells(Triangulation< dim, spacedim > &tria, const double limit_angle_fraction=.75)
void shift(const Tensor< 1, spacedim > &shift_vector, Triangulation< dim, spacedim > &triangulation)
std::vector< typename MeshType::active_cell_iterator > find_cells_adjacent_to_vertex(const MeshType &container, const unsigned int vertex_index)
std::vector< typename MeshType::active_cell_iterator > compute_active_cell_halo_layer(const MeshType &mesh, const std::function< bool(const typename MeshType::active_cell_iterator &)> &predicate)
void exchange_cell_data_to_level_ghosts(const MeshType &mesh, const std::function< std::optional< DataType >(const typename MeshType::level_cell_iterator &)> &pack, const std::function< void(const typename MeshType::level_cell_iterator &, const DataType &)> &unpack, const std::function< bool(const typename MeshType::level_cell_iterator &)> &cell_filter=always_return< typename MeshType::level_cell_iterator, bool >{ true})
std::vector< typename MeshType::active_cell_iterator > compute_active_cell_layer_within_distance(const MeshType &mesh, const std::function< bool(const typename MeshType::active_cell_iterator &)> &predicate, const double layer_thickness)
std::map< unsigned int, types::global_vertex_index > compute_local_to_global_vertex_index_map(const Triangulation< dim, spacedim > &triangulation)
std::vector< typename MeshType::active_cell_iterator > compute_ghost_cell_halo_layer(const MeshType &mesh)
void exchange_cell_data_to_ghosts(const MeshType &mesh, const std::function< std::optional< DataType >(const typename MeshType::active_cell_iterator &)> &pack, const std::function< void(const typename MeshType::active_cell_iterator &, const DataType &)> &unpack, const std::function< bool(const typename MeshType::active_cell_iterator &)> &cell_filter=always_return< typename MeshType::active_cell_iterator, bool >{true})
void laplace_transform(const std::map< unsigned int, Point< dim > > &new_points, Triangulation< dim > &tria, const Function< dim, double > *coefficient=nullptr, const bool solve_for_absolute_positions=false)
void partition_multigrid_levels(Triangulation< dim, spacedim > &triangulation)
unsigned int find_closest_vertex_of_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell, const Point< spacedim > &position, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< spacedim >()))
std::map< unsigned int, std::set<::types::subdomain_id > > compute_vertices_with_ghost_neighbors(const Triangulation< dim, spacedim > &tria)
void collect_coinciding_vertices(const Triangulation< dim, spacedim > &tria, std::map< unsigned int, std::vector< unsigned int > > &coinciding_vertex_groups, std::map< unsigned int, unsigned int > &vertex_to_coinciding_vertex_group)
unsigned int count_cells_with_subdomain_association(const Triangulation< dim, spacedim > &triangulation, const types::subdomain_id subdomain)
return_type guess_point_owner(const std::vector< std::vector< BoundingBox< spacedim > > > &global_bboxes, const std::vector< Point< spacedim > > &points)
std::map< types::global_dof_index, std::vector< typename DoFHandler< dim, spacedim >::active_cell_iterator > > get_dof_to_support_patch_map(DoFHandler< dim, spacedim > &dof_handler)
std::vector< typename MeshType::cell_iterator > compute_cell_halo_layer_on_level(const MeshType &mesh, const std::function< bool(const typename MeshType::cell_iterator &)> &predicate, const unsigned int level)
void partition_triangulation(const unsigned int n_partitions, Triangulation< dim, spacedim > &triangulation, const SparsityTools::Partitioner partitioner=SparsityTools::Partitioner::metis)
std::vector< std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > > vertex_to_cell_map(const Triangulation< dim, spacedim > &triangulation)
std::vector< typename MeshType::active_cell_iterator > compute_ghost_cell_layer_within_distance(const MeshType &mesh, const double layer_thickness)
return_type compute_point_locations_try_all(const Cache< dim, spacedim > &cache, const std::vector< Point< spacedim > > &points, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell_hint=typename Triangulation< dim, spacedim >::active_cell_iterator())
std::vector< typename MeshType::active_cell_iterator > get_patch_around_cell(const typename MeshType::active_cell_iterator &cell)
std::vector< types::subdomain_id > get_subdomain_association(const Triangulation< dim, spacedim > &triangulation, const std::vector< CellId > &cell_ids)
void distort_random(const double factor, Triangulation< dim, spacedim > &triangulation, const bool keep_boundary=true, const unsigned int seed=boost::random::mt19937::default_seed)
std::vector< std::vector< Tensor< 1, spacedim > > > vertex_to_cell_centers_directions(const Triangulation< dim, spacedim > &mesh, const std::vector< std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > > &vertex_to_cells)
std::vector< std::pair< typename MeshType< dim, spacedim >::active_cell_iterator, Point< dim > > > find_all_active_cells_around_point(const Mapping< dim, spacedim > &mapping, const MeshType< dim, spacedim > &mesh, const Point< spacedim > &p, const double tolerance, const std::pair< typename MeshType< dim, spacedim >::active_cell_iterator, Point< dim > > &first_cell, const std::vector< std::set< typename MeshType< dim, spacedim >::active_cell_iterator > > *vertex_to_cells=nullptr)
void build_triangulation_from_patch(const std::vector< typename Container::active_cell_iterator > &patch, Triangulation< Container::dimension, Container::space_dimension > &local_triangulation, std::map< typename Triangulation< Container::dimension, Container::space_dimension >::active_cell_iterator, typename Container::active_cell_iterator > &patch_to_global_tria_map)
std::optional< types::geometric_orientation > orthogonal_equality(const FaceIterator &face1, const FaceIterator &face2, const unsigned int direction, const Tensor< 1, FaceIterator::AccessorType::space_dimension > &offset=Tensor< 1, FaceIterator::AccessorType::space_dimension >(), const FullMatrix< double > &matrix=FullMatrix< double >(), const double abs_tol=1e-10)
std::vector< std::vector< BoundingBox< spacedim > > > exchange_local_bounding_boxes(const std::vector< BoundingBox< spacedim > > &local_bboxes, const MPI_Comm mpi_communicator)
double cell_measure(const std::vector< Point< dim > > &all_vertices, const ArrayView< const unsigned int > &vertex_indices)
return_type distributed_compute_point_locations(const GridTools::Cache< dim, spacedim > &cache, const std::vector< Point< spacedim > > &local_points, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bboxes, const double tolerance=1e-10, const std::vector< bool > &marked_vertices={}, const bool enforce_unique_mapping=true)
@ matrix
Contents is actually a matrix.
*  *  if(update_pressure &update_flags) *  compute_pressure(constitutive_request
@ exchange_cell_data_request
grid_tools.h: exchange_cell_ghosts()
Definition mpi_tags.h:64
@ exchange_cell_data_reply
grid_tools.h: exchange_cell_ghosts()
Definition mpi_tags.h:67
std::size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
Definition utilities.h:1352
T unpack(const std::vector< char > &buffer, const bool allow_compression=true)
Definition utilities.h:1509
Definition hp.h:115
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
Definition tria.cc:15808
constexpr types::manifold_id flat_manifold_id
Definition types.h:332
STL namespace.
Definition types.h:30
unsigned int global_dof_index
Definition types.h:92
unsigned int subdomain_id
Definition types.h:50
std::uint8_t geometric_orientation
Definition types.h:38
boost::geometry::index::rtree< LeafType, IndexType, IndexableGetter > RTree
Definition rtree.h:159
std::size_t memory_consumption() const
FullMatrix< double > matrix
types::geometric_orientation orientation
std::map< unsigned int, std::vector< unsigned int > > communicate_indices(const std::vector< std::tuple< unsigned int, unsigned int, unsigned int > > &point_recv_components, const MPI_Comm comm) const
GridTools::internal::DistributedComputePointLocationsInternal< dim, spacedim > convert_to_distributed_compute_point_locations_internal(const unsigned int n_points_1D, const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping, std::vector< Quadrature< spacedim > > *mapped_quadratures_recv_comp=nullptr, const bool consistent_numbering_of_sender_and_receiver=false) const
std::vector< std::tuple< std::pair< int, int >, unsigned int, unsigned int, IntersectionType > > send_components
Definition grid_tools.h:849
std::vector< std::tuple< unsigned int, unsigned int, IntersectionType > > recv_components
Definition grid_tools.h:860
std::array<::Point< spacedim >, structdim+1 > IntersectionType
Definition grid_tools.h:835
std::vector< std::tuple< unsigned int, unsigned int, unsigned int > > recv_components
Definition grid_tools.h:785
std::vector< std::tuple< std::pair< int, int >, unsigned int, unsigned int, Point< dim >, Point< spacedim >, unsigned int > > send_components
Definition grid_tools.h:760