deal.II version 9.8.0
\(\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>
76 DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
77 class Triangulation;
78 }
79} // namespace parallel
80
81namespace hp
82{
83 template <int, int>
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>
99 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<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{
135
217 template <int dim, typename Transformation, int spacedim>
219 (std::invocable<Transformation, Point<spacedim>> &&
220 std::assignable_from<
221 Point<spacedim> &,
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
482
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
685 template <int dim, int spacedim>
686#ifndef DOXYGEN
687 std::tuple<
688 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
689 std::vector<std::vector<Point<dim>>>,
690 std::vector<std::vector<unsigned int>>,
691 std::vector<std::vector<Point<spacedim>>>,
692 std::vector<std::vector<unsigned int>>>
693#else
694 return_type
695#endif
698 const std::vector<Point<spacedim>> &local_points,
699 const std::vector<std::vector<BoundingBox<spacedim>>> &global_bboxes,
700 const double tolerance = 1e-10,
701 const std::vector<bool> &marked_vertices = {},
702 const bool enforce_unique_mapping = true);
703
704 namespace internal
705 {
720 template <int dim, int spacedim>
722 {
724
731 void
733
737 unsigned int n_searched_points;
738
745 std::vector<std::tuple<std::pair<int, int>,
746 unsigned int,
747 unsigned int,
750 unsigned int>>
752
756 std::vector<unsigned int> send_ranks;
757
763 std::vector<unsigned int> send_ptrs;
764
775 std::vector<std::tuple<unsigned int, unsigned int, unsigned int>>
777
781 std::vector<unsigned int> recv_ranks;
782
788 std::vector<unsigned int> recv_ptrs;
789 };
790
800 template <int dim, int spacedim>
804 const std::vector<Point<spacedim>> &points,
805 const std::vector<std::vector<BoundingBox<spacedim>>> &global_bboxes,
806 const std::vector<bool> &marked_vertices,
807 const double tolerance,
808 const bool perform_handshake,
809 const bool enforce_unique_mapping = false);
810
811
819 template <int structdim, int spacedim>
821 {
826 std::array<::Point<spacedim>, structdim + 1>;
827
836 std::vector<std::tuple<std::pair<int, int>,
837 unsigned int,
838 unsigned int,
841
850 std::vector<std::tuple<unsigned int, unsigned int, IntersectionType>>
852
856 std::vector<unsigned int> recv_ptrs;
857
878 template <int dim>
880 spacedim>
882 const unsigned int n_points_1D,
885 std::vector<Quadrature<spacedim>> *mapped_quadratures_recv_comp =
886 nullptr,
887 const bool consistent_numbering_of_sender_and_receiver = false) const;
888
889 private:
897 std::map<unsigned int, std::vector<unsigned int>>
899 const std::vector<std::tuple<unsigned int, unsigned int, unsigned int>>
900 &point_recv_components,
901 const MPI_Comm comm) const;
902 };
903
911 template <int structdim, int dim, int spacedim>
914 const Cache<dim, spacedim> &cache,
915 const std::vector<std::vector<Point<spacedim>>> &intersection_requests,
916 const std::vector<std::vector<BoundingBox<spacedim>>> &global_bboxes,
917 const std::vector<bool> &marked_vertices,
918 const double tolerance);
919
920 } // namespace internal
921
931 template <int spacedim>
932 unsigned int
933 find_closest_vertex(const std::map<unsigned int, Point<spacedim>> &vertices,
934 const Point<spacedim> &p);
935
962 template <int dim, template <int, int> class MeshType, int spacedim>
964 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
965 unsigned int find_closest_vertex(
966 const MeshType<dim, spacedim> &mesh,
967 const Point<spacedim> &p,
968 const std::vector<bool> &marked_vertices = {});
969
996 template <int dim, template <int, int> class MeshType, int spacedim>
998 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
999 unsigned int find_closest_vertex(
1000 const Mapping<dim, spacedim> &mapping,
1001 const MeshType<dim, spacedim> &mesh,
1002 const Point<spacedim> &p,
1003 const std::vector<bool> &marked_vertices = {});
1004
1005
1028 template <typename MeshType>
1029 DEAL_II_CXX20_REQUIRES((concepts::is_triangulation_or_dof_handler<MeshType>))
1030#ifndef _MSC_VER
1031 std::vector<typename MeshType::active_cell_iterator>
1032#else
1033 std::vector<
1034 typename ::internal::ActiveCellIterator<MeshType::dimension,
1035 MeshType::space_dimension,
1036 MeshType>::type>
1037#endif
1038 find_cells_adjacent_to_vertex(const MeshType &container,
1039 const unsigned int vertex_index);
1040
1106 template <int dim, template <int, int> class MeshType, int spacedim>
1108 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1109#ifndef _MSC_VER
1110 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator, Point<dim>>
1111#else
1112 std::pair<typename ::internal::
1113 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1114 Point<dim>>
1115#endif
1116 find_active_cell_around_point(const Mapping<dim, spacedim> &mapping,
1117 const MeshType<dim, spacedim> &mesh,
1118 const Point<spacedim> &p,
1119 const std::vector<bool> &marked_vertices = {},
1120 const double tolerance = 1.e-10);
1121
1132 template <int dim, template <int, int> class MeshType, int spacedim>
1134 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1135#ifndef _MSC_VER
1136 typename MeshType<dim, spacedim>::active_cell_iterator
1137#else
1138 typename ::internal::
1139 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type
1140#endif
1141 find_active_cell_around_point(const MeshType<dim, spacedim> &mesh,
1142 const Point<spacedim> &p,
1143 const std::vector<bool> &marked_vertices = {},
1144 const double tolerance = 1.e-10);
1145
1152 template <int dim, int spacedim>
1153 std::pair<typename DoFHandler<dim, spacedim>::active_cell_iterator,
1154 Point<dim>>
1156 const hp::MappingCollection<dim, spacedim> &mapping,
1157 const DoFHandler<dim, spacedim> &mesh,
1158 const Point<spacedim> &p,
1159 const double tolerance = 1.e-10);
1160
1212 template <int dim, int spacedim>
1213 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
1214 Point<dim>>
1216 const Cache<dim, spacedim> &cache,
1217 const Point<spacedim> &p,
1220 const std::vector<bool> &marked_vertices = {},
1221 const double tolerance = 1.e-10);
1222
1239 template <int dim, template <int, int> class MeshType, int spacedim>
1241 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1242#ifndef _MSC_VER
1243 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator, Point<dim>>
1244#else
1245 std::pair<typename ::internal::
1246 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1247 Point<dim>>
1248#endif
1250 const Mapping<dim, spacedim> &mapping,
1251 const MeshType<dim, spacedim> &mesh,
1252 const Point<spacedim> &p,
1253 const std::vector<
1254 std::set<typename MeshType<dim, spacedim>::active_cell_iterator>>
1256 const std::vector<std::vector<Tensor<1, spacedim>>>
1257 &vertex_to_cell_centers,
1258 const typename MeshType<dim, spacedim>::active_cell_iterator &cell_hint =
1259 typename MeshType<dim, spacedim>::active_cell_iterator(),
1260 const std::vector<bool> &marked_vertices = {},
1261 const RTree<std::pair<Point<spacedim>, unsigned int>> &
1262 used_vertices_rtree = RTree<std::pair<Point<spacedim>, unsigned int>>{},
1263 const double tolerance = 1.e-10,
1264 const RTree<
1265 std::pair<BoundingBox<spacedim>,
1267 *relevant_cell_bounding_boxes_rtree = nullptr);
1268
1298 template <int dim, template <int, int> class MeshType, int spacedim>
1300 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1301#ifndef _MSC_VER
1302 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1303 Point<dim>>>
1304#else
1305 std::vector<std::pair<
1306 typename ::internal::
1307 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1308 Point<dim>>>
1309#endif
1311 const Mapping<dim, spacedim> &mapping,
1312 const MeshType<dim, spacedim> &mesh,
1313 const Point<spacedim> &p,
1314 const double tolerance,
1315 const std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1316 Point<dim>> &first_cell,
1317 const std::vector<
1318 std::set<typename MeshType<dim, spacedim>::active_cell_iterator>>
1319 *vertex_to_cells = nullptr);
1320
1330 template <int dim, template <int, int> class MeshType, int spacedim>
1332 (concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
1333#ifndef _MSC_VER
1334 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1335 Point<dim>>>
1336#else
1337 std::vector<std::pair<
1338 typename ::internal::
1339 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1340 Point<dim>>>
1341#endif
1343 const Mapping<dim, spacedim> &mapping,
1344 const MeshType<dim, spacedim> &mesh,
1345 const Point<spacedim> &p,
1346 const double tolerance = 1e-10,
1347 const std::vector<bool> &marked_vertices = {});
1348
1372 template <typename MeshType>
1373 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1374 std::vector<typename MeshType::active_cell_iterator> get_active_child_cells(
1375 const typename MeshType::cell_iterator &cell);
1376
1403 template <typename MeshType>
1404 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1406 const typename MeshType::active_cell_iterator &cell,
1407 std::vector<typename MeshType::active_cell_iterator> &active_neighbors);
1408
1460 template <typename MeshType>
1461 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1462 std::
1463 vector<typename MeshType::active_cell_iterator> compute_active_cell_halo_layer(
1464 const MeshType &mesh,
1465 const std::function<bool(const typename MeshType::active_cell_iterator &)>
1466 &predicate);
1467
1468
1478 template <typename MeshType>
1479 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1480 std::
1481 vector<typename MeshType::cell_iterator> compute_cell_halo_layer_on_level(
1482 const MeshType &mesh,
1483 const std::function<bool(const typename MeshType::cell_iterator &)>
1484 &predicate,
1485 const unsigned int level);
1486
1487
1502 template <typename MeshType>
1503 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1504 std::vector<
1505 typename MeshType::
1506 active_cell_iterator> compute_ghost_cell_halo_layer(const MeshType &mesh);
1507
1558 template <typename MeshType>
1559 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1560 std::
1561 vector<typename MeshType::active_cell_iterator> compute_active_cell_layer_within_distance(
1562 const MeshType &mesh,
1563 const std::function<bool(const typename MeshType::active_cell_iterator &)>
1564 &predicate,
1565 const double layer_thickness);
1566
1591 template <typename MeshType>
1592 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1593 std::
1594 vector<typename MeshType::active_cell_iterator> compute_ghost_cell_layer_within_distance(
1595 const MeshType &mesh,
1596 const double layer_thickness);
1597
1670 template <typename MeshType>
1671 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
1672 std::
1674 const MeshType &mesh,
1675 const std::function<bool(const typename MeshType::active_cell_iterator &)>
1676 &predicate,
1677 const unsigned int refinement_level = 0,
1678 const bool allow_merge = false,
1679 const unsigned int max_boxes = numbers::invalid_unsigned_int);
1680
1708 template <int spacedim>
1709#ifndef DOXYGEN
1710 std::tuple<std::vector<std::vector<unsigned int>>,
1711 std::map<unsigned int, unsigned int>,
1712 std::map<unsigned int, std::vector<unsigned int>>>
1713#else
1714 return_type
1715#endif
1717 const std::vector<std::vector<BoundingBox<spacedim>>> &global_bboxes,
1718 const std::vector<Point<spacedim>> &points);
1719
1720
1755 template <int spacedim>
1756#ifndef DOXYGEN
1757 std::tuple<std::map<unsigned int, std::vector<unsigned int>>,
1758 std::map<unsigned int, unsigned int>,
1759 std::map<unsigned int, std::vector<unsigned int>>>
1760#else
1761 return_type
1762#endif
1764 const RTree<std::pair<BoundingBox<spacedim>, unsigned int>> &covering_rtree,
1765 const std::vector<Point<spacedim>> &points);
1766
1779 template <int dim, int spacedim>
1780 std::vector<std::vector<Tensor<1, spacedim>>>
1782 const Triangulation<dim, spacedim> &mesh,
1783 const std::vector<
1785 &vertex_to_cells);
1786
1787
1795 template <int dim, int spacedim>
1796 unsigned int
1799 const Point<spacedim> &position,
1802#ifndef _MSC_VER
1804#else
1806#endif
1807 ));
1808
1820 template <int dim, int spacedim>
1821 std::map<unsigned int, types::global_vertex_index>
1823 const Triangulation<dim, spacedim> &triangulation);
1824
1853 template <int dim, int spacedim>
1854 std::vector<types::global_vertex_index>
1856 const Triangulation<dim, spacedim> &serial_tria,
1857 const Triangulation<dim, spacedim> &parallel_tria);
1858
1864
1885 template <int dim, int spacedim>
1886 void
1887 partition_triangulation(const unsigned int n_partitions,
1888 Triangulation<dim, spacedim> &triangulation,
1889 const SparsityTools::Partitioner partitioner =
1891
1902 template <int dim, int spacedim>
1903 void
1904 partition_triangulation(const unsigned int n_partitions,
1905 const std::vector<unsigned int> &cell_weights,
1906 Triangulation<dim, spacedim> &triangulation,
1907 const SparsityTools::Partitioner partitioner =
1909
1955 template <int dim, int spacedim>
1956 void
1957 partition_triangulation(const unsigned int n_partitions,
1958 const SparsityPattern &cell_connection_graph,
1959 Triangulation<dim, spacedim> &triangulation,
1960 const SparsityTools::Partitioner partitioner =
1962
1973 template <int dim, int spacedim>
1974 void
1975 partition_triangulation(const unsigned int n_partitions,
1976 const std::vector<unsigned int> &cell_weights,
1977 const SparsityPattern &cell_connection_graph,
1978 Triangulation<dim, spacedim> &triangulation,
1979 const SparsityTools::Partitioner partitioner =
1981
1996 template <int dim, int spacedim>
1997 void
1998 partition_triangulation_zorder(const unsigned int n_partitions,
1999 Triangulation<dim, spacedim> &triangulation,
2000 const bool group_siblings = true);
2001
2013 template <int dim, int spacedim>
2014 void
2016
2024 template <int dim, int spacedim>
2025 std::vector<types::subdomain_id>
2027 const std::vector<CellId> &cell_ids);
2028
2039 template <int dim, int spacedim>
2040 void
2042 std::vector<types::subdomain_id> &subdomain);
2043
2058 template <int dim, int spacedim>
2059 unsigned int
2061 const Triangulation<dim, spacedim> &triangulation,
2062 const types::subdomain_id subdomain);
2063
2093 template <int dim, int spacedim>
2094 std::vector<bool>
2096
2105
2106
2146 template <typename MeshType>
2148 std::vector<typename MeshType::active_cell_iterator> get_patch_around_cell(
2149 const typename MeshType::active_cell_iterator &cell);
2150
2151
2173 template <class Container>
2174 std::vector<typename Container::cell_iterator>
2176 const std::vector<typename Container::active_cell_iterator> &patch_cells);
2177
2244 template <class Container>
2245 void
2247 const std::vector<typename Container::active_cell_iterator> &patch,
2249 &local_triangulation,
2250 std::map<
2251 typename Triangulation<Container::dimension,
2252 Container::space_dimension>::active_cell_iterator,
2253 typename Container::active_cell_iterator> &patch_to_global_tria_map);
2254
2286 template <int dim, int spacedim>
2287 std::map<
2289 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
2291
2292
2294
2299
2307 template <typename CellIterator>
2309 {
2313 CellIterator cell[2];
2314
2319 unsigned int face_idx[2];
2320
2327
2341
2345 std::size_t
2347 };
2348
2349
2373 template <typename FaceIterator>
2374 std::optional<types::geometric_orientation>
2376 const FaceIterator &face1,
2377 const FaceIterator &face2,
2378 const unsigned int direction,
2381 const FullMatrix<double> &matrix = FullMatrix<double>(),
2382 const double abs_tol = 1e-10);
2383
2443 template <typename MeshType>
2446 const MeshType &mesh,
2447 const types::boundary_id b_id1,
2448 const types::boundary_id b_id2,
2449 const unsigned int direction,
2451 &matched_pairs,
2454 const FullMatrix<double> &matrix = FullMatrix<double>(),
2455 const double abs_tol = 1e-10);
2456
2457
2478 template <typename MeshType>
2481 const MeshType &mesh,
2482 const types::boundary_id b_id,
2483 const unsigned int direction,
2484 std::vector<PeriodicFacePair<typename MeshType::cell_iterator>>
2485 &matched_pairs,
2486 const ::Tensor<1, MeshType::space_dimension> &offset =
2487 ::Tensor<1, MeshType::space_dimension>(),
2488 const FullMatrix<double> &matrix = FullMatrix<double>(),
2489 const double abs_tol = 1e-10);
2490
2496
2517 template <int dim, int spacedim>
2518 void
2519 copy_boundary_to_manifold_id(Triangulation<dim, spacedim> &tria,
2520 const bool reset_boundary_ids = false);
2521
2543 template <int dim, int spacedim>
2544 void
2546 const std::vector<types::boundary_id> &src_boundary_ids,
2547 const std::vector<types::manifold_id> &dst_manifold_ids,
2548 Triangulation<dim, spacedim> &tria,
2549 const std::vector<types::boundary_id> &reset_boundary_ids = {});
2550
2580 template <int dim, int spacedim>
2581 void
2583 const bool compute_face_ids = false);
2584
2609 template <int dim, int spacedim>
2610 void
2613 const std::function<types::manifold_id(
2614 const std::set<types::manifold_id> &)> &disambiguation_function =
2615 [](const std::set<types::manifold_id> &manifold_ids) {
2616 if (manifold_ids.size() == 1)
2617 return *manifold_ids.begin();
2618 else
2620 },
2621 bool overwrite_only_flat_manifold_ids = true);
2623
2710 template <typename DataType, typename MeshType>
2711 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
2713 const MeshType &mesh,
2714 const std::function<std::optional<DataType>(
2715 const typename MeshType::active_cell_iterator &)> &pack,
2716 const std::function<void(const typename MeshType::active_cell_iterator &,
2717 const DataType &)> &unpack,
2718 const std::function<bool(const typename MeshType::active_cell_iterator &)>
2719 &cell_filter =
2720 always_return<typename MeshType::active_cell_iterator, bool>{true});
2721
2734 template <typename DataType, typename MeshType>
2737 const MeshType &mesh,
2738 const std::function<std::optional<DataType>(
2739 const typename MeshType::level_cell_iterator &)> &pack,
2740 const std::function<void(const typename MeshType::level_cell_iterator &,
2741 const DataType &)> &unpack,
2742 const std::function<bool(const typename MeshType::level_cell_iterator &)> &
2743 cell_filter = always_return<typename MeshType::level_cell_iterator, bool>{
2744 true});
2745
2746 /* Exchange with all processors of the MPI communicator @p mpi_communicator the vector of bounding
2747 * boxes @p local_bboxes.
2748 *
2749 * This function is meant to exchange bounding boxes describing the locally
2750 * owned cells in a distributed triangulation obtained with the function
2751 * GridTools::compute_mesh_predicate_bounding_box .
2752 *
2753 * The output vector's size is the number of processes of the MPI
2754 * communicator:
2755 * its i-th entry contains the vector @p local_bboxes of the i-th process.
2756 */
2757 template <int spacedim>
2758 std::vector<std::vector<BoundingBox<spacedim>>>
2760 const std::vector<BoundingBox<spacedim>> &local_bboxes,
2761 const MPI_Comm mpi_communicator);
2762
2795 template <int spacedim>
2798 const std::vector<BoundingBox<spacedim>> &local_description,
2799 const MPI_Comm mpi_communicator);
2800
2818 template <int dim, int spacedim>
2819 void
2821 const Triangulation<dim, spacedim> &tria,
2822 std::map<unsigned int, std::vector<unsigned int>> &coinciding_vertex_groups,
2823 std::map<unsigned int, unsigned int> &vertex_to_coinciding_vertex_group);
2824
2844 template <int dim, int spacedim>
2845 std::map<unsigned int, std::set<::types::subdomain_id>>
2847 const Triangulation<dim, spacedim> &tria);
2848
2869 template <int dim, typename VectorType>
2871 {
2872 public:
2876 using value_type = typename VectorType::value_type;
2877
2882 const FiniteElement<dim, dim> &fe,
2883 const unsigned int n_subdivisions = 1,
2884 const double tolerance = 1e-10);
2885
2896 void
2897 process(const DoFHandler<dim> &background_dof_handler,
2898 const VectorType &ls_vector,
2899 const double iso_level,
2900 std::vector<Point<dim>> &vertices,
2901 std::vector<CellData<dim == 1 ? 1 : dim - 1>> &cells) const;
2902
2907 void
2908 process(const DoFHandler<dim> &background_dof_handler,
2909 const VectorType &ls_vector,
2910 const double iso_level,
2911 std::vector<Point<dim>> &vertices) const;
2912
2922 void
2924 const VectorType &ls_vector,
2925 const double iso_level,
2926 std::vector<Point<dim>> &vertices,
2927 std::vector<CellData<dim == 1 ? 1 : dim - 1>> &cells) const;
2933 void
2935 const VectorType &ls_vector,
2936 const double iso_level,
2937 std::vector<Point<dim>> &vertices) const;
2938
2939 private:
2944 static Quadrature<dim>
2945 create_quadrature_rule(const unsigned int n_subdivisions);
2946
2950 void
2951 process_cell(std::vector<value_type> &ls_values,
2952 const std::vector<Point<dim>> &points,
2953 const double iso_level,
2954 std::vector<Point<dim>> &vertices,
2955 std::vector<CellData<dim == 1 ? 1 : dim - 1>> &cells,
2956 const bool write_back_cell_data = true) const;
2957
2961 void
2962 process_sub_cell(const std::vector<value_type> &,
2963 const std::vector<Point<1>> &,
2964 const std::vector<unsigned int> &,
2965 const double,
2966 std::vector<Point<1>> &,
2967 std::vector<CellData<1>> &,
2968 const bool) const
2969 {
2971 }
2972
2979 void
2980 process_sub_cell(const std::vector<value_type> &ls_values,
2981 const std::vector<Point<2>> &points,
2982 const std::vector<unsigned int> &mask,
2983 const double iso_level,
2984 std::vector<Point<2>> &vertices,
2985 std::vector<CellData<1>> &cells,
2986 const bool write_back_cell_data) const;
2987
2991 void
2992 process_sub_cell(const std::vector<value_type> &ls_values,
2993 const std::vector<Point<3>> &points,
2994 const std::vector<unsigned int> &mask,
2995 const double iso_level,
2996 std::vector<Point<3>> &vertices,
2997 std::vector<CellData<2>> &cells,
2998 const bool write_back_cell_data) const;
2999
3004 const unsigned int n_subdivisions;
3005
3010 const double tolerance;
3011
3017 };
3018
3019
3020
3025
3030 int,
3031 << "The number of partitions you gave is " << arg1
3032 << ", but must be greater than zero.");
3037 int,
3038 << "The subdomain id " << arg1
3039 << " has no cells associated with it.");
3044
3049 double,
3050 << "The scaling factor must be positive, but it is " << arg1
3051 << '.');
3052
3057 unsigned int,
3058 << "The given vertex with index " << arg1
3059 << " is not used in the given triangulation.");
3060
3062
3063} /*namespace GridTools*/
3064
3065/* ----------------- Template function --------------- */
3066
3067#ifndef DOXYGEN
3068
3069namespace GridTools
3070{
3071 template <int dim>
3072 double
3074 const std::vector<Point<dim>> &all_vertices,
3075 const unsigned int (&indices)[GeometryInfo<dim>::vertices_per_cell])
3076 {
3077 // We forward call to the ArrayView version:
3080 return cell_measure(all_vertices, view);
3081 }
3082
3083
3084
3085 template <int dim, typename Transformation, int spacedim>
3087 (std::invocable<Transformation, Point<spacedim>> &&
3088 std::assignable_from<
3089 Point<spacedim> &,
3090 std::invoke_result_t<Transformation, Point<spacedim>>>))
3091 void transform(const Transformation &transformation,
3092 Triangulation<dim, spacedim> &triangulation)
3093 {
3094 std::vector<bool> treated_vertices(triangulation.n_vertices(), false);
3095
3096 // loop over all active cells, and
3097 // transform those vertices that
3098 // have not yet been touched. note
3099 // that we get to all vertices in
3100 // the triangulation by only
3101 // visiting the active cells.
3103 cell = triangulation.begin_active(),
3104 endc = triangulation.end();
3105 for (; cell != endc; ++cell)
3106 for (const unsigned int v : cell->vertex_indices())
3107 if (treated_vertices[cell->vertex_index(v)] == false)
3108 {
3109 // transform this vertex
3110 cell->vertex(v) = transformation(cell->vertex(v));
3111 // and mark it as treated
3112 treated_vertices[cell->vertex_index(v)] = true;
3113 };
3114
3115
3116 // now fix any vertices on hanging nodes so that we don't create any holes
3117 if (dim == 2)
3118 {
3120 cell = triangulation.begin_active(),
3121 endc = triangulation.end();
3122 for (; cell != endc; ++cell)
3123 for (const unsigned int face : cell->face_indices())
3124 if (cell->face(face)->has_children() &&
3125 !cell->face(face)->at_boundary())
3126 {
3127 Assert(cell->reference_cell() ==
3130
3131 // this line has children
3132 cell->face(face)->child(0)->vertex(1) =
3133 (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) /
3134 2.0;
3135 }
3136 }
3137 else if (dim == 3)
3138 {
3140 cell = triangulation.begin_active(),
3141 endc = triangulation.end();
3142 for (; cell != endc; ++cell)
3143 for (const unsigned int face : cell->face_indices())
3144 if (cell->face(face)->has_children() &&
3145 !cell->face(face)->at_boundary())
3146 {
3147 if (static_cast<std::uint8_t>(
3148 cell->face(face)->refinement_case()) ==
3150 {
3151 Assert(cell->reference_cell() ==
3154
3155 // this face has hanging nodes
3156 cell->face(face)->child(0)->vertex(1) =
3157 (cell->face(face)->vertex(0) +
3158 cell->face(face)->vertex(1)) /
3159 2.0;
3160 cell->face(face)->child(0)->vertex(2) =
3161 (cell->face(face)->vertex(0) +
3162 cell->face(face)->vertex(2)) /
3163 2.0;
3164 cell->face(face)->child(1)->vertex(3) =
3165 (cell->face(face)->vertex(1) +
3166 cell->face(face)->vertex(3)) /
3167 2.0;
3168 cell->face(face)->child(2)->vertex(3) =
3169 (cell->face(face)->vertex(2) +
3170 cell->face(face)->vertex(3)) /
3171 2.0;
3172
3173 // center of the face
3174 cell->face(face)->child(0)->vertex(3) =
3175 (cell->face(face)->vertex(0) +
3176 cell->face(face)->vertex(1) +
3177 cell->face(face)->vertex(2) +
3178 cell->face(face)->vertex(3)) /
3179 4.0;
3180 }
3181 else
3182 {
3183 // Special case for anisotropic refinement
3184 for (unsigned int line = 0;
3185 line < GeometryInfo<dim - 1>::faces_per_cell;
3186 line++)
3187 if (cell->face(face)->line(line)->has_children())
3188 cell->face(face)->line(line)->child(0)->vertex(1) =
3189 (cell->face(face)->line(line)->vertex(0) +
3190 cell->face(face)->line(line)->vertex(1)) /
3191 2.0;
3192 }
3193 }
3194 }
3195
3196 // Make sure FEValues notices that the mesh has changed
3197 triangulation.signals.mesh_movement();
3198 }
3199
3200
3201
3202 template <typename MeshType>
3203 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
3204 std::vector<typename MeshType::active_cell_iterator> get_active_child_cells(
3205 const typename MeshType::cell_iterator &cell)
3206 {
3207 std::vector<typename MeshType::active_cell_iterator> child_cells;
3208
3209 if (cell->has_children())
3210 {
3211 for (unsigned int child = 0; child < cell->n_children(); ++child)
3212 if (cell->child(child)->has_children())
3213 {
3214 const std::vector<typename MeshType::active_cell_iterator>
3215 children = get_active_child_cells<MeshType>(cell->child(child));
3216 child_cells.insert(child_cells.end(),
3217 children.begin(),
3218 children.end());
3219 }
3220 else
3221 child_cells.push_back(cell->child(child));
3222 }
3223
3224 return child_cells;
3225 }
3226
3227
3228
3229 template <typename MeshType>
3230 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
3232 const typename MeshType::active_cell_iterator &cell,
3233 std::vector<typename MeshType::active_cell_iterator> &active_neighbors)
3234 {
3235 active_neighbors.clear();
3236 for (const unsigned int n : cell->face_indices())
3237 if (!cell->at_boundary(n))
3238 {
3239 if (MeshType::dimension == 1)
3240 {
3241 // check children of neighbor. note
3242 // that in 1d children of the neighbor
3243 // may be further refined. In 1d the
3244 // case is simple since we know what
3245 // children bound to the present cell
3246 typename MeshType::cell_iterator neighbor_child =
3247 cell->neighbor(n);
3248 if (!neighbor_child->is_active())
3249 {
3250 while (neighbor_child->has_children())
3251 neighbor_child = neighbor_child->child(n == 0 ? 1 : 0);
3252
3253 Assert(neighbor_child->neighbor(n == 0 ? 1 : 0) == cell,
3255 }
3256 active_neighbors.push_back(neighbor_child);
3257 }
3258 else
3259 {
3260 if (cell->face(n)->has_children())
3261 // this neighbor has children. find
3262 // out which border to the present
3263 // cell
3264 for (unsigned int c = 0;
3265 c < cell->face(n)->n_active_descendants();
3266 ++c)
3267 active_neighbors.push_back(
3268 cell->neighbor_child_on_subface(n, c));
3269 else
3270 {
3271 // the neighbor must be active
3272 // himself
3273 Assert(cell->neighbor(n)->is_active(), ExcInternalError());
3274 active_neighbors.push_back(cell->neighbor(n));
3275 }
3276 }
3277 }
3278 }
3279
3280
3281
3282 template <typename CellIterator>
3283 std::size_t
3285 {
3286 return sizeof(*this) + matrix.memory_consumption();
3287 }
3288
3289
3290
3291 namespace internal
3292 {
3293 template <typename DataType,
3294 typename MeshType,
3295 typename MeshCellIteratorType>
3296 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
3297 inline void exchange_cell_data(
3298 const MeshType &mesh,
3299 const std::function<std::optional<DataType>(const MeshCellIteratorType &)>
3300 &pack,
3301 const std::function<void(const MeshCellIteratorType &, const DataType &)>
3302 &unpack,
3303 const std::function<bool(const MeshCellIteratorType &)> &cell_filter,
3304 const std::function<void(
3305 const std::function<void(const MeshCellIteratorType &,
3306 const types::subdomain_id)> &)> &process_cells,
3307 const std::function<std::set<types::subdomain_id>(
3308 const parallel::TriangulationBase<MeshType::dimension,
3309 MeshType::space_dimension> &)>
3310 &compute_ghost_owners)
3311 {
3312# ifndef DEAL_II_WITH_MPI
3313 (void)mesh;
3314 (void)pack;
3315 (void)unpack;
3316 (void)cell_filter;
3317 (void)process_cells;
3318 (void)compute_ghost_owners;
3319 Assert(false, ExcNeedsMPI());
3320# else
3321 constexpr int dim = MeshType::dimension;
3322 constexpr int spacedim = MeshType::space_dimension;
3323 auto tria =
3324 dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(
3325 &mesh.get_triangulation());
3326 Assert(
3327 tria != nullptr,
3328 ExcMessage(
3329 "The function exchange_cell_data_to_ghosts() only works with parallel triangulations."));
3330
3331 if (const auto tria = dynamic_cast<
3332 const parallel::shared::Triangulation<dim, spacedim> *>(
3333 &mesh.get_triangulation()))
3334 {
3335 Assert(
3336 tria->with_artificial_cells(),
3337 ExcMessage(
3338 "The functions GridTools::exchange_cell_data_to_ghosts() and "
3339 "GridTools::exchange_cell_data_to_level_ghosts() can only "
3340 "operate on a single layer of ghost cells. However, you have "
3341 "given a Triangulation object of type "
3342 "parallel::shared::Triangulation without artificial cells "
3343 "resulting in an arbitrary number of ghost layers. "
3344 "To use this function for a Triangulation object of type "
3345 "parallel::shared::Triangulation, make sure to create the "
3346 "Triangulation object with allow_artificial_cells set to true. "
3347 "This results in a parallel::shared::Triangulation with only "
3348 "a single layer of ghost cells."));
3349 }
3350
3351 // build list of cells to request for each neighbor
3352 std::set<types::subdomain_id> ghost_owners = compute_ghost_owners(*tria);
3353 std::map<types::subdomain_id, std::vector<CellId::binary_type>>
3354 neighbor_cell_list;
3355
3356 for (const auto ghost_owner : ghost_owners)
3357 neighbor_cell_list[ghost_owner] = {};
3358
3359 process_cells([&](const auto &cell, const auto key) -> void {
3360 if (cell_filter(cell))
3361 {
3362 neighbor_cell_list[key].emplace_back(
3363 cell->id().template to_binary<spacedim>());
3364 }
3365 });
3366
3367 Assert(ghost_owners.size() == neighbor_cell_list.size(),
3369
3370
3371 // Before sending & receiving, make sure we protect this section with
3372 // a mutex:
3373 static Utilities::MPI::CollectiveMutex mutex;
3374 Utilities::MPI::CollectiveMutex::ScopedLock lock(
3375 mutex, tria->get_mpi_communicator());
3376
3377 const int mpi_tag =
3379 const int mpi_tag_reply =
3381
3382 // send our requests
3383 std::vector<MPI_Request> requests(ghost_owners.size());
3384 {
3385 unsigned int idx = 0;
3386 for (const auto &it : neighbor_cell_list)
3387 {
3388 // send the data about the relevant cells
3389 const int ierr = MPI_Isend(it.second.data(),
3390 it.second.size() * sizeof(it.second[0]),
3391 MPI_BYTE,
3392 it.first,
3393 mpi_tag,
3394 tria->get_mpi_communicator(),
3395 &requests[idx]);
3396 AssertThrowMPI(ierr);
3397 ++idx;
3398 }
3399 }
3400
3401 // receive requests and reply with the results
3402 std::vector<MPI_Request> reply_requests(ghost_owners.size());
3403 std::vector<std::vector<char>> sendbuffers(ghost_owners.size());
3404
3405 for (unsigned int idx = 0; idx < ghost_owners.size(); ++idx)
3406 {
3407 MPI_Status status;
3408 int ierr = MPI_Probe(MPI_ANY_SOURCE,
3409 mpi_tag,
3410 tria->get_mpi_communicator(),
3411 &status);
3412 AssertThrowMPI(ierr);
3413
3414 int len;
3415 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3416 AssertThrowMPI(ierr);
3417 Assert(len % sizeof(typename CellId::binary_type) == 0,
3419
3420 const unsigned int n_cells = len / sizeof(CellId::binary_type);
3421 std::vector<CellId::binary_type> cells_with_requests(n_cells);
3422 std::vector<DataType> data_to_send;
3423 data_to_send.reserve(n_cells);
3424 std::vector<bool> cell_carries_data(n_cells, false);
3425
3426 ierr = MPI_Recv(cells_with_requests.data(),
3427 len,
3428 MPI_BYTE,
3429 status.MPI_SOURCE,
3430 status.MPI_TAG,
3431 tria->get_mpi_communicator(),
3432 &status);
3433 AssertThrowMPI(ierr);
3434
3435 // store data for each cell
3436 for (unsigned int c = 0; c < n_cells; ++c)
3437 {
3438 const auto cell =
3439 tria->create_cell_iterator(CellId(cells_with_requests[c]));
3440
3441 MeshCellIteratorType mesh_it(tria,
3442 cell->level(),
3443 cell->index(),
3444 &mesh);
3445
3446 std::optional<DataType> data = pack(mesh_it);
3447 if (data)
3448 {
3449 data_to_send.emplace_back(std::move(*data));
3450 cell_carries_data[c] = true;
3451 }
3452 }
3453
3454 // collect data for sending the reply in a buffer
3455
3456 // (a) make room for storing the local offsets in case we receive
3457 // other data
3458 sendbuffers[idx].resize(sizeof(std::size_t));
3459
3460 // (b) append the actual data and store how much memory it
3461 // corresponds to, which we then insert into the leading position of
3462 // the sendbuffer
3463 std::size_t size_of_send =
3464 Utilities::pack(data_to_send,
3465 sendbuffers[idx],
3466 /*enable_compression*/ false);
3467 std::memcpy(sendbuffers[idx].data(),
3468 &size_of_send,
3469 sizeof(std::size_t));
3470
3471 // (c) append information of certain cells that got left out in case
3472 // we need it
3473 if (data_to_send.size() < n_cells)
3474 Utilities::pack(cell_carries_data,
3475 sendbuffers[idx],
3476 /*enable_compression*/ false);
3477
3478 // send data
3479 ierr = MPI_Isend(sendbuffers[idx].data(),
3480 sendbuffers[idx].size(),
3481 MPI_BYTE,
3482 status.MPI_SOURCE,
3483 mpi_tag_reply,
3484 tria->get_mpi_communicator(),
3485 &reply_requests[idx]);
3486 AssertThrowMPI(ierr);
3487 }
3488
3489 // finally receive the replies
3490 std::vector<char> receive;
3491 for (unsigned int id = 0; id < neighbor_cell_list.size(); ++id)
3492 {
3493 MPI_Status status;
3494 int ierr = MPI_Probe(MPI_ANY_SOURCE,
3495 mpi_tag_reply,
3496 tria->get_mpi_communicator(),
3497 &status);
3498 AssertThrowMPI(ierr);
3499
3500 int len;
3501 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3502 AssertThrowMPI(ierr);
3503
3504 receive.resize(len);
3505
3506 ierr = MPI_Recv(receive.data(),
3507 len,
3508 MPI_BYTE,
3509 status.MPI_SOURCE,
3510 status.MPI_TAG,
3511 tria->get_mpi_communicator(),
3512 &status);
3513 AssertThrowMPI(ierr);
3514
3515 // (a) first determine the length of the data section in the
3516 // received buffer
3517 auto data_iterator = receive.begin();
3518 std::size_t size_of_received_data =
3519 Utilities::unpack<std::size_t>(data_iterator,
3520 data_iterator + sizeof(std::size_t));
3521 data_iterator += sizeof(std::size_t);
3522
3523 // (b) unpack the data section in the indicated region
3524 auto received_data = Utilities::unpack<std::vector<DataType>>(
3525 data_iterator,
3526 data_iterator + size_of_received_data,
3527 /*enable_compression*/ false);
3528 data_iterator += size_of_received_data;
3529
3530 // (c) check if the received data contained fewer entries than the
3531 // number of cells we identified in the beginning, in which case we
3532 // need to extract the boolean vector with the relevant information
3533 const std::vector<CellId::binary_type> &this_cell_list =
3534 neighbor_cell_list[status.MPI_SOURCE];
3535 AssertIndexRange(received_data.size(), this_cell_list.size() + 1);
3536 std::vector<bool> cells_with_data;
3537 if (received_data.size() < this_cell_list.size())
3538 {
3539 cells_with_data = Utilities::unpack<std::vector<bool>>(
3540 data_iterator, receive.end(), /*enable_compression*/ false);
3541 AssertDimension(cells_with_data.size(), this_cell_list.size());
3542 }
3543
3544 // (d) go through the received data and call the user-provided
3545 // unpack function
3546 auto received_data_iterator = received_data.begin();
3547 for (unsigned int c = 0; c < this_cell_list.size(); ++c)
3548 if (cells_with_data.empty() || cells_with_data[c])
3549 {
3551 tria_cell = tria->create_cell_iterator(this_cell_list[c]);
3552
3553 MeshCellIteratorType cell(tria,
3554 tria_cell->level(),
3555 tria_cell->index(),
3556 &mesh);
3557
3558 unpack(cell, *received_data_iterator);
3559 ++received_data_iterator;
3560 }
3561 }
3562
3563 // make sure that all communication is finished
3564 // when we leave this function.
3565 if (requests.size() > 0)
3566 {
3567 const int ierr =
3568 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
3569 AssertThrowMPI(ierr);
3570 }
3571 if (reply_requests.size() > 0)
3572 {
3573 const int ierr = MPI_Waitall(reply_requests.size(),
3574 reply_requests.data(),
3575 MPI_STATUSES_IGNORE);
3576 AssertThrowMPI(ierr);
3577 }
3578
3579
3580# endif // DEAL_II_WITH_MPI
3581 }
3582
3583 } // namespace internal
3584
3585 template <typename DataType, typename MeshType>
3586 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
3587 inline void exchange_cell_data_to_ghosts(
3588 const MeshType &mesh,
3589 const std::function<std::optional<DataType>(
3590 const typename MeshType::active_cell_iterator &)> &pack,
3591 const std::function<void(const typename MeshType::active_cell_iterator &,
3592 const DataType &)> &unpack,
3593 const std::function<bool(const typename MeshType::active_cell_iterator &)>
3594 &cell_filter)
3595 {
3596# ifndef DEAL_II_WITH_MPI
3597 (void)mesh;
3598 (void)pack;
3599 (void)unpack;
3600 (void)cell_filter;
3601 Assert(false, ExcNeedsMPI());
3602# else
3603 internal::exchange_cell_data<DataType,
3604 MeshType,
3605 typename MeshType::active_cell_iterator>(
3606 mesh,
3607 pack,
3608 unpack,
3609 cell_filter,
3610 [&](const auto &process) {
3611 for (const auto &cell : mesh.active_cell_iterators())
3612 if (cell->is_ghost())
3613 process(cell, cell->subdomain_id());
3614 },
3615 [](const auto &tria) { return tria.ghost_owners(); });
3616# endif
3617 }
3618
3619
3620
3621 template <typename DataType, typename MeshType>
3622 DEAL_II_CXX20_REQUIRES(concepts::is_triangulation_or_dof_handler<MeshType>)
3624 const MeshType &mesh,
3625 const std::function<std::optional<DataType>(
3626 const typename MeshType::level_cell_iterator &)> &pack,
3627 const std::function<void(const typename MeshType::level_cell_iterator &,
3628 const DataType &)> &unpack,
3629 const std::function<bool(const typename MeshType::level_cell_iterator &)>
3630 &cell_filter)
3631 {
3632# ifndef DEAL_II_WITH_MPI
3633 (void)mesh;
3634 (void)pack;
3635 (void)unpack;
3636 (void)cell_filter;
3637 Assert(false, ExcNeedsMPI());
3638# else
3639 internal::exchange_cell_data<DataType,
3640 MeshType,
3641 typename MeshType::level_cell_iterator>(
3642 mesh,
3643 pack,
3644 unpack,
3645 cell_filter,
3646 [&](const auto &process) {
3647 for (const auto &cell : mesh.cell_iterators())
3648 if (cell->is_ghost_on_level())
3649 process(cell, cell->level_subdomain_id());
3650 },
3651 [](const auto &tria) { return tria.level_ghost_owners(); });
3652# endif
3653 }
3654} // namespace GridTools
3655
3656#endif // DOXYGEN
3657
3659
3660#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
MarchingCubeAlgorithm(const Mapping< dim, dim > &mapping, const FiniteElement< dim, dim > &fe, const unsigned int n_subdivisions=1, const double tolerance=1e-10)
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
const Mapping< dim, spacedim > & get_default_linear_mapping() const
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:246
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
const unsigned int DoFAccessor< structdim, dim, spacedim, level_dof_access >::space_dimension
constexpr unsigned int GeometryInfo< dim >::faces_per_cell
#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)
TriaActiveIterator< CellAccessor< dim, spacedim > > active_cell_iterator
Definition tria.h:1648
typename ActiveSelector::active_cell_iterator active_cell_iterator
TriaIterator< CellAccessor< dim, spacedim > > cell_iterator
Definition tria.h:1624
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)
const Mapping< dim, spacedim > & get_default_linear_mapping(const Triangulation< dim, spacedim > &triangulation)
Definition mapping.cc:314
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
Definition mapping_q1.h:101
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.
constexpr const ReferenceCell< dim > & get_hypercube()
@ 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:15817
constexpr types::manifold_id flat_manifold_id
Definition types.h:340
STL namespace.
Definition types.h:30
unsigned int boundary_id
Definition types.h:159
unsigned int subdomain_id
Definition types.h:50
unsigned int global_dof_index
Definition types.h:92
unsigned int manifold_id
Definition types.h:171
std::uint8_t geometric_orientation
Definition types.h:38
*braid_SplitCommworld & comm
boost::geometry::index::rtree< LeafType, IndexType, IndexableGetter > RTree
Definition rtree.h:158
static constexpr unsigned int vertices_per_cell
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::array<::Point< spacedim >, structdim+1 > IntersectionType
Definition grid_tools.h:825
std::vector< std::tuple< std::pair< int, int >, unsigned int, unsigned int, IntersectionType > > send_components
Definition grid_tools.h:840
std::vector< std::tuple< unsigned int, unsigned int, IntersectionType > > recv_components
Definition grid_tools.h:851
std::vector< std::tuple< unsigned int, unsigned int, unsigned int > > recv_components
Definition grid_tools.h:776
std::vector< std::tuple< std::pair< int, int >, unsigned int, unsigned int, Point< dim >, Point< spacedim >, unsigned int > > send_components
Definition grid_tools.h:751