Reference documentation for deal.II version 9.0.0
grid_tools.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2001 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_grid_tools_h
17 #define dealii_grid_tools_h
18 
19 
20 #include <deal.II/base/bounding_box.h>
21 #include <deal.II/base/config.h>
22 #include <deal.II/base/geometry_info.h>
23 #include <deal.II/dofs/dof_handler.h>
24 #include <deal.II/fe/mapping.h>
25 #include <deal.II/fe/mapping_q1.h>
26 #include <deal.II/grid/manifold.h>
27 #include <deal.II/grid/tria.h>
28 #include <deal.II/grid/tria_accessor.h>
29 #include <deal.II/grid/tria_iterator.h>
30 #include <deal.II/hp/dof_handler.h>
31 #include <deal.II/lac/sparsity_tools.h>
32 
33 #include <boost/optional.hpp>
34 #include <boost/archive/binary_oarchive.hpp>
35 #include <boost/archive/binary_iarchive.hpp>
36 #include <boost/serialization/vector.hpp>
37 #include <boost/serialization/array.hpp>
38 
39 #ifdef DEAL_II_WITH_ZLIB
40 # include <boost/iostreams/stream.hpp>
41 # include <boost/iostreams/filtering_stream.hpp>
42 # include <boost/iostreams/device/back_inserter.hpp>
43 # include <boost/iostreams/filter/gzip.hpp>
44 #endif
45 
46 
47 #include <bitset>
48 #include <list>
49 #include <set>
50 
51 DEAL_II_NAMESPACE_OPEN
52 
53 namespace parallel
54 {
55  namespace distributed
56  {
57  template <int, int> class Triangulation;
58  }
59 }
60 
61 namespace hp
62 {
63  template <int, int> class MappingCollection;
64 }
65 
66 class SparsityPattern;
67 
68 namespace internal
69 {
70  template <int dim, int spacedim, class MeshType>
71  class ActiveCellIterator
72  {
73  public:
74 #ifndef _MSC_VER
75  typedef typename MeshType::active_cell_iterator type;
76 #else
78 #endif
79  };
80 
81 #ifdef _MSC_VER
82  template <int dim, int spacedim>
83  class ActiveCellIterator<dim, spacedim, ::DoFHandler<dim, spacedim> >
84  {
85  public:
87  };
88 
89  template <int dim, int spacedim>
90  class ActiveCellIterator<dim, spacedim, ::hp::DoFHandler<dim, spacedim> >
91  {
92  public:
94  };
95 #endif
96 }
97 
106 namespace GridTools
107 {
108  template <int dim, int spacedim>
109  class Cache;
110 
115 
122  template <int dim, int spacedim>
123  double diameter (const Triangulation<dim, spacedim> &tria);
124 
151  template <int dim, int spacedim>
152  double volume (const Triangulation<dim,spacedim> &tria,
154 
165  template <int dim, int spacedim>
166  double
169 
180  template <int dim, int spacedim>
181  double
184 
194  template <int dim>
195  double cell_measure (const std::vector<Point<dim> > &all_vertices,
196  const unsigned int (&vertex_indices)[GeometryInfo<dim>::vertices_per_cell]);
197 
203  template <int dim, typename T>
204  double cell_measure (const T &, ...);
205 
219  template <int dim, int spacedim>
221 
241  template <typename Iterator>
243  project_to_object(const Iterator &object,
245 
251 
268  template <int dim, int spacedim>
269  void delete_unused_vertices (std::vector<Point<spacedim> > &vertices,
270  std::vector<CellData<dim> > &cells,
271  SubCellData &subcelldata);
272 
288  template <int dim, int spacedim>
289  void delete_duplicated_vertices (std::vector<Point<spacedim> > &all_vertices,
290  std::vector<CellData<dim> > &cells,
291  SubCellData &subcelldata,
292  std::vector<unsigned int> &considered_vertices,
293  const double tol=1e-12);
294 
300 
324  template <int dim, typename Transformation, int spacedim>
325  void transform (const Transformation &transformation,
326  Triangulation<dim,spacedim> &triangulation);
327 
333  template <int dim, int spacedim>
334  void shift (const Tensor<1,spacedim> &shift_vector,
335  Triangulation<dim,spacedim> &triangulation);
336 
337 
345  void rotate (const double angle,
346  Triangulation<2> &triangulation);
347 
360  template <int dim>
361  void
362  rotate (const double angle,
363  const unsigned int axis,
364  Triangulation<dim,3> &triangulation);
365 
424  template <int dim>
425  void laplace_transform (const std::map<unsigned int,Point<dim> > &new_points,
426  Triangulation<dim> &tria,
427  const Function<dim,double> *coefficient = nullptr,
428  const bool solve_for_absolute_positions = false);
429 
435  template <int dim, int spacedim>
436  std::map<unsigned int,Point<spacedim> >
438 
446  template <int dim, int spacedim>
447  void scale (const double scaling_factor,
448  Triangulation<dim, spacedim> &triangulation);
449 
460  template <int dim, int spacedim>
461  void distort_random (const double factor,
462  Triangulation<dim, spacedim> &triangulation,
463  const bool keep_boundary=true);
464 
500  template <int dim, int spacedim>
501  void
503  const bool isotropic = false,
504  const unsigned int max_iterations = 100);
505 
531  template <int dim, int spacedim>
532  void
534  const double max_ratio = 1.6180339887,
535  const unsigned int max_iterations = 5);
536 
625  template <int dim, int spacedim>
626  void
628  const double limit_angle_fraction=.75);
629 
635 
674  template <int dim, int spacedim>
675 #ifndef DOXYGEN
676  std::tuple<
677  std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator >,
678  std::vector< std::vector< Point<dim> > >,
679  std::vector< std::vector<unsigned int> > >
680 #else
681  return_type
682 #endif
684  const std::vector<Point<spacedim> > &points,
687 
749  template <int dim, int spacedim>
750 #ifndef DOXYGEN
751  std::tuple<
752  std::vector< typename Triangulation<dim, spacedim>::active_cell_iterator >,
753  std::vector< std::vector< Point<dim> > >,
754  std::vector< std::vector< unsigned int > >,
755  std::vector< std::vector< Point<spacedim> > >,
756  std::vector< std::vector< unsigned int > >
757  >
758 #else
759  return_type
760 #endif
762  (const GridTools::Cache<dim,spacedim> &cache,
763  const std::vector<Point<spacedim> > &local_points,
764  const std::vector< std::vector< BoundingBox<spacedim> > > &global_bboxes);
765 
794  template <int dim, int spacedim>
795  std::map<unsigned int,Point<spacedim>> extract_used_vertices (
796  const Triangulation<dim,spacedim> &container,
798 
810  template<int spacedim>
811  unsigned int
812  find_closest_vertex (const std::map<unsigned int,Point<spacedim>> &vertices,
813  const Point<spacedim> &p);
814 
841  template <int dim, template <int, int> class MeshType, int spacedim>
842  unsigned int
843  find_closest_vertex (const MeshType<dim, spacedim> &mesh,
844  const Point<spacedim> &p,
845  const std::vector<bool> &marked_vertices = std::vector<bool>());
846 
872  template <int dim, template <int, int> class MeshType, int spacedim>
873  unsigned int
875  const MeshType<dim, spacedim> &mesh,
876  const Point<spacedim> &p,
877  const std::vector<bool> &marked_vertices = std::vector<bool>());
878 
879 
904  template <int dim, template <int, int> class MeshType, int spacedim>
905 #ifndef _MSC_VER
906  std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
907 #else
908  std::vector<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type>
909 #endif
910  find_cells_adjacent_to_vertex (const MeshType<dim,spacedim> &container,
911  const unsigned int vertex_index);
912 
913 
938  template <int dim, template <int,int> class MeshType, int spacedim>
939 #ifndef _MSC_VER
940  typename MeshType<dim,spacedim>::active_cell_iterator
941 #else
942  typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type
943 #endif
944  find_active_cell_around_point (const MeshType<dim,spacedim> &mesh,
945  const Point<spacedim> &p,
946  const std::vector<bool> &marked_vertices = std::vector<bool>());
947 
1032  template <int dim, template <int, int> class MeshType, int spacedim>
1033 #ifndef _MSC_VER
1034  std::pair<typename MeshType<dim, spacedim>::active_cell_iterator, Point<dim> >
1035 #else
1036  std::pair<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type, Point<dim> >
1037 #endif
1039  const MeshType<dim,spacedim> &mesh,
1040  const Point<spacedim> &p,
1041  const std::vector<bool> &marked_vertices = std::vector<bool>());
1042 
1051  template <int dim, template <int, int> class MeshType, int spacedim>
1052 #ifndef _MSC_VER
1053  std::pair<typename MeshType<dim, spacedim>::active_cell_iterator, Point<dim> >
1054 #else
1055  std::pair<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type, Point<dim> >
1056 #endif
1058  const MeshType<dim,spacedim> &mesh,
1059  const Point<spacedim> &p,
1060  const std::vector<std::set<typename MeshType<dim,spacedim>::active_cell_iterator > > &vertex_to_cell_map,
1061  const std::vector<std::vector<Tensor<1,spacedim> > > &vertex_to_cell_centers,
1062  const typename MeshType<dim, spacedim>::active_cell_iterator &cell_hint=typename MeshType<dim, spacedim>::active_cell_iterator(),
1063  const std::vector<bool> &marked_vertices = std::vector<bool>());
1064 
1086  template <int dim, int spacedim>
1087  std::pair<typename hp::DoFHandler<dim, spacedim>::active_cell_iterator, Point<dim> >
1089  const hp::DoFHandler<dim,spacedim> &mesh,
1090  const Point<spacedim> &p);
1091 
1098  template <int dim, int spacedim>
1099  std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator, Point<dim> >
1101  const Point<spacedim> &p,
1103  const std::vector<bool> &marked_vertices = std::vector<bool>());
1104 
1126  template <class MeshType>
1127  std::vector<typename MeshType::active_cell_iterator>
1128  get_active_child_cells (const typename MeshType::cell_iterator &cell);
1129 
1140  template <class MeshType>
1141  void
1142  get_active_neighbors (const typename MeshType::active_cell_iterator &cell,
1143  std::vector<typename MeshType::active_cell_iterator> &active_neighbors);
1144 
1196  template <class MeshType>
1197  std::vector<typename MeshType::active_cell_iterator>
1199  (const MeshType &mesh,
1200  const std::function<bool (const typename MeshType::active_cell_iterator &)> &predicate);
1201 
1202 
1210  template <class MeshType>
1211  std::vector<typename MeshType::cell_iterator>
1213  (const MeshType &mesh,
1214  const std::function<bool (const typename MeshType::cell_iterator &)> &predicate,
1215  const unsigned int level);
1216 
1217 
1233  template <class MeshType>
1234  std::vector<typename MeshType::active_cell_iterator>
1235  compute_ghost_cell_halo_layer (const MeshType &mesh);
1236 
1288  template <class MeshType>
1289  std::vector<typename MeshType::active_cell_iterator>
1291  (const MeshType &mesh,
1292  const std::function<bool (const typename MeshType::active_cell_iterator &)> &predicate,
1293  const double layer_thickness);
1294 
1320  template <class MeshType>
1321  std::vector<typename MeshType::active_cell_iterator>
1322  compute_ghost_cell_layer_within_distance ( const MeshType &mesh,
1323  const double layer_thickness);
1324 
1340  template <class MeshType>
1341  std::pair< Point<MeshType::space_dimension>, Point<MeshType::space_dimension> >
1343  ( const MeshType &mesh,
1344  const std::function<bool (const typename MeshType::active_cell_iterator &)> &predicate );
1345 
1389  template < class MeshType >
1390  std::vector< BoundingBox< MeshType::space_dimension > >
1392  ( const MeshType &mesh,
1393  const std::function<bool (const typename MeshType::active_cell_iterator &)> &predicate,
1394  const unsigned int refinement_level = 0,
1395  const bool allow_merge = false,
1396  const unsigned int max_boxes = numbers::invalid_unsigned_int);
1397 
1426  template <int spacedim>
1427 #ifndef DOXYGEN
1428  std::tuple< std::vector< std::vector< unsigned int > >,
1429  std::map< unsigned int, unsigned int>,
1430  std::map< unsigned int, std::vector< unsigned int > > >
1431 #else
1432  return_type
1433 #endif
1434  guess_point_owner (const std::vector< std::vector< BoundingBox<spacedim> > >
1435  &global_bboxes,
1436  const std::vector< Point<spacedim> > &points);
1437 
1438 
1447  template <int dim, int spacedim>
1448  std::vector<std::set<typename Triangulation<dim,spacedim>::active_cell_iterator> >
1449  vertex_to_cell_map(const Triangulation<dim,spacedim> &triangulation);
1450 
1465  template <int dim, int spacedim>
1466  std::vector<std::vector<Tensor<1,spacedim> > >
1468  const std::vector<std::set<typename Triangulation<dim,spacedim>::active_cell_iterator> > &vertex_to_cells);
1469 
1470 
1477  template <int dim, int spacedim>
1478  unsigned int
1480  const Point<spacedim> &position);
1481 
1493  template <int dim, int spacedim>
1494  std::map<unsigned int, types::global_vertex_index>
1497 
1511  template <int dim, int spacedim>
1512  std::pair<unsigned int, double>
1514 
1520 
1529  template <int dim, int spacedim>
1530  void
1532  DynamicSparsityPattern &connectivity);
1533 
1542  template <int dim, int spacedim>
1543  void
1545  DynamicSparsityPattern &connectivity);
1546 
1555  template <int dim, int spacedim>
1556  void
1558  const unsigned int level,
1559  DynamicSparsityPattern &connectivity);
1560 
1579  template <int dim, int spacedim>
1580  void
1581  partition_triangulation (const unsigned int n_partitions,
1582  Triangulation<dim, spacedim> &triangulation,
1584  );
1585 
1596  template <int dim, int spacedim>
1597  void
1598  partition_triangulation (const unsigned int n_partitions,
1599  const std::vector<unsigned int> &cell_weights,
1600  Triangulation<dim, spacedim> &triangulation,
1602  );
1603 
1649  template <int dim, int spacedim>
1650  void
1651  partition_triangulation (const unsigned int n_partitions,
1652  const SparsityPattern &cell_connection_graph,
1653  Triangulation<dim,spacedim> &triangulation,
1655  );
1656 
1667  template <int dim, int spacedim>
1668  void
1669  partition_triangulation (const unsigned int n_partitions,
1670  const std::vector<unsigned int> &cell_weights,
1671  const SparsityPattern &cell_connection_graph,
1672  Triangulation<dim,spacedim> &triangulation,
1674  );
1675 
1683  template <int dim, int spacedim>
1684  void
1685  partition_triangulation_zorder (const unsigned int n_partitions,
1686  Triangulation<dim,spacedim> &triangulation);
1687 
1697  template <int dim, int spacedim>
1698  void
1700 
1711  template <int dim, int spacedim>
1712  void
1714  std::vector<types::subdomain_id> &subdomain);
1715 
1730  template <int dim, int spacedim>
1731  unsigned int
1733  const types::subdomain_id subdomain);
1734 
1735 
1765  template <int dim, int spacedim>
1766  std::vector<bool>
1768 
1774 
1803  template <typename MeshType>
1804  std::list<std::pair<typename MeshType::cell_iterator,
1805  typename MeshType::cell_iterator> >
1806  get_finest_common_cells (const MeshType &mesh_1,
1807  const MeshType &mesh_2);
1808 
1818  template <int dim, int spacedim>
1819  bool
1821  const Triangulation<dim, spacedim> &mesh_2);
1822 
1832  template <typename MeshType>
1833  bool
1834  have_same_coarse_mesh (const MeshType &mesh_1,
1835  const MeshType &mesh_2);
1836 
1842 
1858  template <int dim, int spacedim>
1861  Triangulation<dim,spacedim> &triangulation);
1862 
1863 
1864 
1865 
1872 
1873 
1913  template <class MeshType>
1914  std::vector<typename MeshType::active_cell_iterator>
1915  get_patch_around_cell(const typename MeshType::active_cell_iterator &cell);
1916 
1917 
1941  template <class Container>
1942  std::vector<typename Container::cell_iterator>
1943  get_cells_at_coarsest_common_level(const std::vector<typename Container::active_cell_iterator> &patch_cells);
1944 
2013  template <class Container>
2014  void
2016  const std::vector<typename Container::active_cell_iterator> &patch,
2019  typename Container::active_cell_iterator> &patch_to_global_tria_map);
2020 
2057  template <class DoFHandlerType>
2058  std::map< types::global_dof_index,std::vector<typename DoFHandlerType::active_cell_iterator> >
2059  get_dof_to_support_patch_map(DoFHandlerType &dof_handler);
2060 
2061 
2068 
2074  template <typename CellIterator>
2075  struct PeriodicFacePair
2076  {
2080  CellIterator cell[2];
2081 
2086  unsigned int face_idx[2];
2087 
2093  std::bitset<3> orientation;
2094 
2108  };
2109 
2110 
2176  template <typename FaceIterator>
2177  bool
2178  orthogonal_equality (std::bitset<3> &orientation,
2179  const FaceIterator &face1,
2180  const FaceIterator &face2,
2181  const int direction,
2184  const FullMatrix<double> &matrix = FullMatrix<double>());
2185 
2186 
2190  template <typename FaceIterator>
2191  bool
2192  orthogonal_equality (const FaceIterator &face1,
2193  const FaceIterator &face2,
2194  const int direction,
2197  const FullMatrix<double> &matrix = FullMatrix<double>());
2198 
2199 
2258  template <typename MeshType>
2259  void
2261  (const MeshType &mesh,
2262  const types::boundary_id b_id1,
2263  const types::boundary_id b_id2,
2264  const int direction,
2265  std::vector<PeriodicFacePair<typename MeshType::cell_iterator> > &matched_pairs,
2267  const FullMatrix<double> &matrix = FullMatrix<double>());
2268 
2269 
2292  template <typename MeshType>
2293  void
2295  (const MeshType &mesh,
2296  const types::boundary_id b_id,
2297  const int direction,
2298  std::vector<PeriodicFacePair<typename MeshType::cell_iterator> > &matched_pairs,
2299  const ::Tensor<1,MeshType::space_dimension> &offset = ::Tensor<1,MeshType::space_dimension>(),
2300  const FullMatrix<double> &matrix = FullMatrix<double>());
2301 
2307 
2330  template <int dim, int spacedim>
2332  const bool reset_boundary_ids=false);
2333 
2357  template <int dim, int spacedim>
2358  void map_boundary_to_manifold_ids(const std::vector<types::boundary_id> &src_boundary_ids,
2359  const std::vector<types::manifold_id> &dst_manifold_ids,
2361  const std::vector<types::boundary_id> &reset_boundary_ids = {});
2362 
2394  template <int dim, int spacedim>
2396  const bool compute_face_ids=false);
2397 
2398 
2481  template <typename DataType, typename MeshType>
2482  void
2483  exchange_cell_data_to_ghosts (const MeshType &mesh,
2484  const std::function<boost::optional<DataType> (const typename MeshType::active_cell_iterator &)> &pack,
2485  const std::function<void (const typename MeshType::active_cell_iterator &, const DataType &)> &unpack);
2486 
2487  /* Exchange with all processors of the MPI communicator @p mpi_communicator the vector of bounding
2488  * boxes @p local_bboxes.
2489  *
2490  * This function is meant to exchange bounding boxes describing the locally owned
2491  * cells in a distributed triangulation obtained with the function
2492  * GridTools::compute_mesh_predicate_bounding_box .
2493  *
2494  * The output vector's size is the number of processes of the MPI communicator:
2495  * its i-th entry contains the vector @p local_bboxes of the i-th process.
2496  */
2497  template<int spacedim>
2498  std::vector< std::vector< BoundingBox<spacedim> > >
2499  exchange_local_bounding_boxes(const std::vector< BoundingBox<spacedim> > &local_bboxes,
2500  MPI_Comm mpi_communicator);
2501 
2514  template <int dim, typename T>
2516  {
2520  std::vector<CellId> cell_ids;
2521 
2525  std::vector<T> data;
2526 
2534  template <class Archive>
2535  void save (Archive &ar,
2536  const unsigned int version) const;
2537 
2542  template <class Archive>
2543  void load (Archive &ar,
2544  const unsigned int version);
2545 
2546  BOOST_SERIALIZATION_SPLIT_MEMBER()
2547  };
2548 
2553 
2558  int,
2559  << "The number of partitions you gave is " << arg1
2560  << ", but must be greater than zero.");
2565  int,
2566  << "The subdomain id " << arg1
2567  << " has no cells associated with it.");
2572 
2577  double,
2578  << "The scaling factor must be positive, but it is " << arg1 << ".");
2582  template <int N>
2584  Point<N>,
2585  << "The point <" << arg1
2586  << "> could not be found inside any of the "
2587  << "coarse grid cells.");
2591  template <int N>
2593  Point<N>,
2594  << "The point <" << arg1
2595  << "> could not be found inside any of the "
2596  << "subcells of a coarse grid cell.");
2597 
2602  unsigned int,
2603  << "The given vertex with index " << arg1
2604  << " is not used in the given triangulation.");
2605 
2606 
2609 } /*namespace GridTools*/
2610 
2611 
2612 
2613 /* ----------------- Template function --------------- */
2614 
2615 #ifndef DOXYGEN
2616 
2617 namespace GridTools
2618 {
2619  template <int dim, typename T>
2620  double cell_measure (const T &, ...)
2621  {
2622  Assert(false, ExcNotImplemented());
2623  return std::numeric_limits<double>::quiet_NaN();
2624  }
2625 
2626  template <int dim, typename Predicate, int spacedim>
2627  void transform (const Predicate &predicate,
2628  Triangulation<dim, spacedim> &triangulation)
2629  {
2630  std::vector<bool> treated_vertices (triangulation.n_vertices(),
2631  false);
2632 
2633  // loop over all active cells, and
2634  // transform those vertices that
2635  // have not yet been touched. note
2636  // that we get to all vertices in
2637  // the triangulation by only
2638  // visiting the active cells.
2640  cell = triangulation.begin_active (),
2641  endc = triangulation.end ();
2642  for (; cell!=endc; ++cell)
2643  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
2644  if (treated_vertices[cell->vertex_index(v)] == false)
2645  {
2646  // transform this vertex
2647  cell->vertex(v) = predicate(cell->vertex(v));
2648  // and mark it as treated
2649  treated_vertices[cell->vertex_index(v)] = true;
2650  };
2651 
2652 
2653  // now fix any vertices on hanging nodes so that we don't create any holes
2654  if (dim==2)
2655  {
2657  cell = triangulation.begin_active(),
2658  endc = triangulation.end();
2659  for (; cell!=endc; ++cell)
2660  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
2661  if (cell->face(face)->has_children() &&
2662  !cell->face(face)->at_boundary())
2663  {
2664  // this line has children
2665  cell->face(face)->child(0)->vertex(1)
2666  = (cell->face(face)->vertex(0) +
2667  cell->face(face)->vertex(1)) / 2;
2668  }
2669  }
2670  else if (dim==3)
2671  {
2673  cell = triangulation.begin_active(),
2674  endc = triangulation.end();
2675  for (; cell!=endc; ++cell)
2676  for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
2677  if (cell->face(face)->has_children() &&
2678  !cell->face(face)->at_boundary())
2679  {
2680  // this face has hanging nodes
2681  cell->face(face)->child(0)->vertex(1)
2682  = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) / 2.0;
2683  cell->face(face)->child(0)->vertex(2)
2684  = (cell->face(face)->vertex(0) + cell->face(face)->vertex(2)) / 2.0;
2685  cell->face(face)->child(1)->vertex(3)
2686  = (cell->face(face)->vertex(1) + cell->face(face)->vertex(3)) / 2.0;
2687  cell->face(face)->child(2)->vertex(3)
2688  = (cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 2.0;
2689 
2690  // center of the face
2691  cell->face(face)->child(0)->vertex(3)
2692  = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)
2693  + cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 4.0;
2694  }
2695  }
2696 
2697  // Make sure FEValues notices that the mesh has changed
2698  triangulation.signals.mesh_movement();
2699  }
2700 
2701 
2702 
2703  template <class MeshType>
2704  std::vector<typename MeshType::active_cell_iterator>
2705  get_active_child_cells (const typename MeshType::cell_iterator &cell)
2706  {
2707  std::vector<typename MeshType::active_cell_iterator> child_cells;
2708 
2709  if (cell->has_children())
2710  {
2711  for (unsigned int child=0;
2712  child<cell->n_children(); ++child)
2713  if (cell->child (child)->has_children())
2714  {
2715  const std::vector<typename MeshType::active_cell_iterator>
2716  children = get_active_child_cells<MeshType> (cell->child(child));
2717  child_cells.insert (child_cells.end(),
2718  children.begin(), children.end());
2719  }
2720  else
2721  child_cells.push_back (cell->child(child));
2722  }
2723 
2724  return child_cells;
2725  }
2726 
2727 
2728 
2729  template <class MeshType>
2730  void
2731  get_active_neighbors(const typename MeshType::active_cell_iterator &cell,
2732  std::vector<typename MeshType::active_cell_iterator> &active_neighbors)
2733  {
2734  active_neighbors.clear ();
2735  for (unsigned int n=0; n<GeometryInfo<MeshType::dimension>::faces_per_cell; ++n)
2736  if (! cell->at_boundary(n))
2737  {
2738  if (MeshType::dimension == 1)
2739  {
2740  // check children of neighbor. note
2741  // that in 1d children of the neighbor
2742  // may be further refined. In 1d the
2743  // case is simple since we know what
2744  // children bound to the present cell
2745  typename MeshType::cell_iterator
2746  neighbor_child = cell->neighbor(n);
2747  if (!neighbor_child->active())
2748  {
2749  while (neighbor_child->has_children())
2750  neighbor_child = neighbor_child->child (n==0 ? 1 : 0);
2751 
2752  Assert (neighbor_child->neighbor(n==0 ? 1 : 0)==cell,
2753  ExcInternalError());
2754  }
2755  active_neighbors.push_back (neighbor_child);
2756  }
2757  else
2758  {
2759  if (cell->face(n)->has_children())
2760  // this neighbor has children. find
2761  // out which border to the present
2762  // cell
2763  for (unsigned int c=0; c<cell->face(n)->number_of_children(); ++c)
2764  active_neighbors.push_back (cell->neighbor_child_on_subface(n,c));
2765  else
2766  {
2767  // the neighbor must be active
2768  // himself
2769  Assert(cell->neighbor(n)->active(), ExcInternalError());
2770  active_neighbors.push_back(cell->neighbor(n));
2771  }
2772  }
2773  }
2774  }
2775 
2776 
2777 
2778  namespace internal
2779  {
2780  namespace ProjectToObject
2781  {
2794  struct CrossDerivative
2795  {
2796  const unsigned int direction_0;
2797  const unsigned int direction_1;
2798 
2799  CrossDerivative(const unsigned int d0, const unsigned int d1);
2800  };
2801 
2802  inline
2803  CrossDerivative::CrossDerivative(const unsigned int d0, const unsigned int d1)
2804  :
2805  direction_0 (d0),
2806  direction_1 (d1)
2807  {}
2808 
2809 
2810 
2815  template <typename F>
2816  inline
2817  auto
2818  centered_first_difference(const double center,
2819  const double step,
2820  const F &f)
2821  -> decltype(f(center) - f(center))
2822  {
2823  return (f(center + step) - f(center - step))/(2.0*step);
2824  }
2825 
2826 
2827 
2832  template <typename F>
2833  inline
2834  auto
2835  centered_second_difference(const double center,
2836  const double step,
2837  const F &f)
2838  -> decltype(f(center) - f(center))
2839  {
2840  return (f(center + step) - 2.0*f(center) + f(center - step))/(step*step);
2841  }
2842 
2843 
2844 
2854  template <int structdim, typename F>
2855  inline
2856  auto
2857  cross_stencil
2858  (const CrossDerivative cross_derivative,
2860  const double step,
2861  const F &f)
2862  -> decltype(f(center) - f(center))
2863  {
2865  simplex_vector[cross_derivative.direction_0] = 0.5*step;
2866  simplex_vector[cross_derivative.direction_1] = -0.5*step;
2867  return (- 4.0 *f(center)
2868  - 1.0 *f(center + simplex_vector)
2869  - 1.0/3.0 *f(center - simplex_vector)
2870  + 16.0/3.0*f(center + 0.5*simplex_vector)
2871  )/step;
2872  }
2873 
2874 
2875 
2882  template <int spacedim, int structdim, typename F>
2883  inline
2884  double
2885  gradient_entry
2886  (const unsigned int row_n,
2887  const unsigned int dependent_direction,
2888  const Point<spacedim> &p0,
2890  const double step,
2891  const F &f)
2892  {
2894  dependent_direction < GeometryInfo<structdim>::vertices_per_cell,
2895  ExcMessage("This function assumes that the last weight is a "
2896  "dependent variable (and hence we cannot take its "
2897  "derivative directly)."));
2898  Assert(row_n != dependent_direction,
2899  ExcMessage("We cannot differentiate with respect to the variable "
2900  "that is assumed to be dependent."));
2901 
2902  const Point<spacedim> manifold_point = f(center);
2903  const Tensor<1, spacedim> stencil_value = cross_stencil<structdim>
2904  ({row_n, dependent_direction},
2905  center,
2906  step,
2907  f);
2908  double entry = 0.0;
2909  for (unsigned int dim_n = 0; dim_n < spacedim; ++dim_n)
2910  entry += -2.0*(p0[dim_n] - manifold_point[dim_n])*stencil_value[dim_n];
2911  return entry;
2912  }
2913 
2919  template <typename Iterator, int spacedim, int structdim>
2921  project_to_d_linear_object (const Iterator &object,
2922  const Point<spacedim> &trial_point)
2923  {
2924  // let's look at this for simplicity for a quad (structdim==2) in a space with
2925  // spacedim>2 (notate trial_point by y): all points on the surface are
2926  // given by
2927  // x(\xi) = sum_i v_i phi_x(\xi)
2928  // where v_i are the vertices of the quad, and \xi=(\xi_1,\xi_2) are the
2929  // reference coordinates of the quad. so what we are trying to do is find
2930  // a point x on the surface that is closest to the point y. there are
2931  // different ways to solve this problem, but in the end it's a nonlinear
2932  // problem and we have to find reference coordinates \xi so that J(\xi) =
2933  // 1/2 || x(\xi)-y ||^2 is minimal. x(\xi) is a function that is
2934  // structdim-linear in \xi, so J(\xi) is a polynomial of degree 2*structdim that we'd
2935  // like to minimize. unless structdim==1, we'll have to use a Newton method to
2936  // find the answer. This leads to the following formulation of Newton
2937  // steps:
2938  //
2939  // Given \xi_k, find \delta\xi_k so that
2940  // H_k \delta\xi_k = - F_k
2941  // where H_k is an approximation to the second derivatives of J at \xi_k,
2942  // and F_k is the first derivative of J. We'll iterate this a number of
2943  // times until the right hand side is small enough. As a stopping
2944  // criterion, we terminate if ||\delta\xi||<eps.
2945  //
2946  // As for the Hessian, the best choice would be
2947  // H_k = J''(\xi_k)
2948  // but we'll opt for the simpler Gauss-Newton form
2949  // H_k = A^T A
2950  // i.e.
2951  // (H_k)_{nm} = \sum_{i,j} v_i*v_j *
2952  // \partial_n phi_i *
2953  // \partial_m phi_j
2954  // we start at xi=(0.5, 0.5).
2955  Point<structdim> xi;
2956  for (unsigned int d=0; d<structdim; ++d)
2957  xi[d] = 0.5;
2958 
2959  Point<spacedim> x_k;
2960  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2961  x_k += object->vertex(i) *
2963 
2964  do
2965  {
2966  Tensor<1,structdim> F_k;
2967  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2968  F_k += (x_k-trial_point)*object->vertex(i) *
2970 
2971  Tensor<2,structdim> H_k;
2972  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2973  for (unsigned int j=0; j<GeometryInfo<structdim>::vertices_per_cell; ++j)
2974  {
2978  H_k += (object->vertex(i) * object->vertex(j)) * tmp;
2979  }
2980 
2981  const Tensor<1,structdim> delta_xi = - invert(H_k) * F_k;
2982  xi += delta_xi;
2983 
2984  x_k = Point<spacedim>();
2985  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2986  x_k += object->vertex(i) *
2988 
2989  if (delta_xi.norm() < 1e-7)
2990  break;
2991  }
2992  while (true);
2993 
2994  return x_k;
2995  }
2996  }
2997  }
2998 
2999 
3000 
3001  namespace internal
3002  {
3003  // We hit an internal compiler error in ICC 15 if we define this as a lambda
3004  // inside the project_to_object function below.
3005  template <int structdim>
3006  inline
3007  bool weights_are_ok (const Tensor<1, GeometryInfo<structdim>::vertices_per_cell> &v)
3008  {
3009  // clang has trouble figuring out structdim here, so define it
3010  // again:
3011  static const std::size_t n_vertices_per_cell
3012  = Tensor<1, GeometryInfo<structdim>::vertices_per_cell>::n_independent_components;
3013  std::array<double, n_vertices_per_cell> copied_weights;
3014  for (unsigned int i = 0; i < n_vertices_per_cell; ++i)
3015  {
3016  copied_weights[i] = v[i];
3017  if (v[i] < 0.0 || v[i] > 1.0)
3018  return false;
3019  }
3020 
3021  // check the sum: try to avoid some roundoff errors by summing in order
3022  std::sort(copied_weights.begin(), copied_weights.end());
3023  const double sum = std::accumulate(copied_weights.begin(), copied_weights.end(), 0.0);
3024  return std::abs(sum - 1.0) < 1e-10; // same tolerance used in manifold.cc
3025  }
3026  }
3027 
3028  template <typename Iterator>
3030  project_to_object(const Iterator &object,
3032  {
3033  const int spacedim = Iterator::AccessorType::space_dimension;
3034  const int structdim = Iterator::AccessorType::structure_dimension;
3035 
3036  Point<spacedim> projected_point = trial_point;
3037 
3038  if (structdim >= spacedim)
3039  return projected_point;
3040  else if (structdim == 1 || structdim == 2)
3041  {
3042  using namespace internal::ProjectToObject;
3043  // Try to use the special flat algorithm for quads (this is better
3044  // than the general algorithm in 3D). This does not take into account
3045  // whether projected_point is outside the quad, but we optimize along
3046  // lines below anyway:
3047  const int dim = Iterator::AccessorType::dimension;
3048  const Manifold<dim, spacedim> &manifold = object->get_manifold();
3049  if (structdim == 2 &&
3050  dynamic_cast<const FlatManifold<dim,spacedim> *>(&manifold)
3051  != nullptr)
3052  {
3053  projected_point = project_to_d_linear_object<Iterator, spacedim, structdim>(object, trial_point);
3054  }
3055  else
3056  {
3057  // We want to find a point on the convex hull (defined by the
3058  // vertices of the object and the manifold description) that is
3059  // relatively close to the trial point. This has a few issues:
3060  //
3061  // 1. For a general convex hull we are not guaranteed that a unique
3062  // minimum exists.
3063  // 2. The independent variables in the optimization process are the
3064  // weights given to Manifold::get_new_point, which must sum to 1,
3065  // so we cannot use standard finite differences to approximate a
3066  // gradient.
3067  //
3068  // There is not much we can do about 1., but for 2. we can derive
3069  // finite difference stencils that work on a structdim-dimensional
3070  // simplex and rewrite the optimization problem to use those
3071  // instead. Consider the structdim 2 case and let
3072  //
3073  // F(c0, c1, c2, c3) = Manifold::get_new_point(vertices, {c0, c1, c2, c3})
3074  //
3075  // where {c0, c1, c2, c3} are the weights for the four vertices on
3076  // the quadrilateral. We seek to minimize the Euclidean distance
3077  // between F(...) and trial_point. We can solve for c3 in terms of
3078  // the other weights and get, for one coordinate direction
3079  //
3080  // d/dc0 ((x0 - F(c0, c1, c2, 1 - c0 - c1 - c2))^2)
3081  // = -2(x0 - F(...)) (d/dc0 F(...) - d/dc3 F(...))
3082  //
3083  // where we substitute back in for c3 after taking the
3084  // derivative. We can compute a stencil for the cross derivative
3085  // d/dc0 - d/dc3: this is exactly what cross_stencil approximates
3086  // (and gradient_entry computes the sum over the independent
3087  // variables). Below, we somewhat arbitrarily pick the last
3088  // component as the dependent one.
3089  //
3090  // Since we can now calculate derivatives of the objective
3091  // function we can use gradient descent to minimize it.
3092  //
3093  // Of course, this is much simpler in the structdim = 1 case (we
3094  // could rewrite the projection as a 1D optimization problem), but
3095  // to reduce the potential for bugs we use the same code in both
3096  // cases.
3097  const double step_size = object->diameter()/64.0;
3098 
3099  constexpr unsigned int n_vertices_per_cell = GeometryInfo<structdim>::vertices_per_cell;
3100 
3101  std::array<Point<spacedim>, n_vertices_per_cell> vertices;
3102  for (unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
3103  ++vertex_n)
3104  vertices[vertex_n] = object->vertex(vertex_n);
3105 
3106  auto get_point_from_weights =
3107  [&](const Tensor<1, n_vertices_per_cell> &weights)
3108  -> Point<spacedim>
3109  {
3110  return object->get_manifold().get_new_point
3111  (make_array_view(vertices.begin(), vertices.end()),
3112  make_array_view(&weights[0],
3113  &weights[n_vertices_per_cell - 1] + 1));
3114  };
3115 
3116  // pick the initial weights as (normalized) inverse distances from
3117  // the trial point:
3118  Tensor<1, n_vertices_per_cell> guess_weights;
3119  double guess_weights_sum = 0.0;
3120  for (unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
3121  ++vertex_n)
3122  {
3123  const double distance = vertices[vertex_n].distance(trial_point);
3124  if (distance == 0.0)
3125  {
3126  guess_weights = 0.0;
3127  guess_weights[vertex_n] = 1.0;
3128  guess_weights_sum = 1.0;
3129  break;
3130  }
3131  else
3132  {
3133  guess_weights[vertex_n] = 1.0/distance;
3134  guess_weights_sum += guess_weights[vertex_n];
3135  }
3136  }
3137  guess_weights /= guess_weights_sum;
3138  Assert(internal::weights_are_ok<structdim>(guess_weights), ExcInternalError());
3139 
3140  // The optimization algorithm consists of two parts:
3141  //
3142  // 1. An outer loop where we apply the gradient descent algorithm.
3143  // 2. An inner loop where we do a line search to find the optimal
3144  // length of the step one should take in the gradient direction.
3145  //
3146  for (unsigned int outer_n = 0; outer_n < 40; ++outer_n)
3147  {
3148  const unsigned int dependent_direction = n_vertices_per_cell - 1;
3149  Tensor<1, n_vertices_per_cell> current_gradient;
3150  for (unsigned int row_n = 0;
3151  row_n < n_vertices_per_cell;
3152  ++row_n)
3153  {
3154  if (row_n != dependent_direction)
3155  {
3156  current_gradient[row_n] = gradient_entry<spacedim, structdim>
3157  (row_n,
3158  dependent_direction,
3159  trial_point,
3160  guess_weights,
3161  step_size,
3162  get_point_from_weights);
3163 
3164  current_gradient[dependent_direction] -= current_gradient[row_n];
3165  }
3166  }
3167 
3168  // We need to travel in the -gradient direction, as noted
3169  // above, but we may not want to take a full step in that
3170  // direction; instead, guess that we will go -0.5*gradient and
3171  // do quasi-Newton iteration to pick the best multiplier. The
3172  // goal is to find a scalar alpha such that
3173  //
3174  // F(x - alpha g)
3175  //
3176  // is minimized, where g is the gradient and F is the
3177  // objective function. To find the optimal value we find roots
3178  // of the derivative of the objective function with respect to
3179  // alpha by Newton iteration, where we approximate the first
3180  // and second derivatives of F(x - alpha g) with centered
3181  // finite differences.
3182  double gradient_weight = -0.5;
3183  auto gradient_weight_objective_function = [&](const double gradient_weight_guess)
3184  -> double
3185  {
3186  return (trial_point -
3187  get_point_from_weights(guess_weights +
3188  gradient_weight_guess*current_gradient)).norm_square();
3189  };
3190 
3191  for (unsigned int inner_n = 0; inner_n < 10; ++inner_n)
3192  {
3193  const double update_numerator = centered_first_difference
3194  (gradient_weight, step_size, gradient_weight_objective_function);
3195  const double update_denominator = centered_second_difference
3196  (gradient_weight, step_size, gradient_weight_objective_function);
3197 
3198  // avoid division by zero. Note that we limit the gradient weight below
3199  if (std::abs(update_denominator) == 0.0)
3200  break;
3201  gradient_weight = gradient_weight - update_numerator/update_denominator;
3202 
3203  // Put a fairly lenient bound on the largest possible
3204  // gradient (things tend to be locally flat, so the gradient
3205  // itself is usually small)
3206  if (std::abs(gradient_weight) > 10)
3207  {
3208  gradient_weight = -10.0;
3209  break;
3210  }
3211  }
3212 
3213  // It only makes sense to take convex combinations with weights
3214  // between zero and one. If the update takes us outside of this
3215  // region then rescale the update to stay within the region and
3216  // try again
3217  Tensor<1, n_vertices_per_cell> tentative_weights =
3218  guess_weights + gradient_weight*current_gradient;
3219 
3220  double new_gradient_weight = gradient_weight;
3221  for (unsigned int iteration_count = 0; iteration_count < 40; ++iteration_count)
3222  {
3223  if (internal::weights_are_ok<structdim>(tentative_weights))
3224  break;
3225 
3226  for (unsigned int i = 0; i < n_vertices_per_cell; ++i)
3227  {
3228  if (tentative_weights[i] < 0.0)
3229  {
3230  tentative_weights -= (tentative_weights[i]/current_gradient[i])
3231  *current_gradient;
3232  }
3233  if (tentative_weights[i] < 0.0 || 1.0 < tentative_weights[i])
3234  {
3235  new_gradient_weight /= 2.0;
3236  tentative_weights = guess_weights + new_gradient_weight*current_gradient;
3237  }
3238  }
3239  }
3240 
3241  // the update might still send us outside the valid region, so
3242  // check again and quit if the update is still not valid
3243  if (!internal::weights_are_ok<structdim>(tentative_weights))
3244  break;
3245 
3246  // if we cannot get closer by traveling in the gradient direction then quit
3247  if (get_point_from_weights(tentative_weights).distance(trial_point) <
3248  get_point_from_weights(guess_weights).distance(trial_point))
3249  guess_weights = tentative_weights;
3250  else
3251  break;
3252  Assert(internal::weights_are_ok<structdim>(guess_weights), ExcInternalError());
3253  }
3254  Assert(internal::weights_are_ok<structdim>(guess_weights), ExcInternalError());
3255  projected_point = get_point_from_weights(guess_weights);
3256  }
3257 
3258  // if structdim == 2 and the optimal point is not on the interior then
3259  // we may be able to get a more accurate result by projecting onto the
3260  // lines.
3261  if (structdim == 2)
3262  {
3263  std::array<Point<spacedim>, GeometryInfo<structdim>::lines_per_cell>
3264  line_projections;
3265  for (unsigned int line_n = 0; line_n < GeometryInfo<structdim>::lines_per_cell;
3266  ++line_n)
3267  {
3268  line_projections[line_n] = project_to_object(object->line(line_n),
3269  trial_point);
3270  }
3271  std::sort(line_projections.begin(), line_projections.end(),
3272  [&](const Point<spacedim> &a, const Point<spacedim> &b)
3273  {
3274  return a.distance(trial_point) < b.distance(trial_point);
3275  });
3276  if (line_projections[0].distance(trial_point)
3277  < projected_point.distance(trial_point))
3278  projected_point = line_projections[0];
3279  }
3280  }
3281  else
3282  {
3283  Assert(false, ExcNotImplemented());
3284  return projected_point;
3285  }
3286 
3287  return projected_point;
3288  }
3289 
3290 
3291 
3292  template <int dim, typename T>
3293  template <class Archive>
3294  void
3295  CellDataTransferBuffer<dim,T>::save (Archive &ar,
3296  const unsigned int /*version*/) const
3297  {
3298  Assert(cell_ids.size() == data.size(),
3299  ExcDimensionMismatch(cell_ids.size(), data.size()));
3300  // archive the cellids in an efficient binary format
3301  const size_t n_cells = cell_ids.size();
3302  ar &n_cells;
3303  for (auto &it : cell_ids)
3304  {
3305  CellId::binary_type binary_cell_id = it.template to_binary<dim>();
3306  ar &binary_cell_id;
3307  }
3308 
3309  ar &data;
3310  }
3311 
3312 
3313 
3314  template <int dim, typename T>
3315  template <class Archive>
3316  void
3317  CellDataTransferBuffer<dim,T>::load (Archive &ar,
3318  const unsigned int /*version*/)
3319  {
3320  size_t n_cells;
3321  ar &n_cells;
3322  cell_ids.clear();
3323  cell_ids.reserve(n_cells);
3324  for (unsigned int c=0; c<n_cells; ++c)
3325  {
3326  CellId::binary_type value;
3327  ar &value;
3328  cell_ids.emplace_back(value);
3329  }
3330  ar &data;
3331  }
3332 
3333 
3334 
3335  template <typename DataType, typename MeshType>
3336  void
3337  exchange_cell_data_to_ghosts (const MeshType &mesh,
3338  const std::function<boost::optional<DataType> (const typename MeshType::active_cell_iterator &)> &pack,
3339  const std::function<void (const typename MeshType::active_cell_iterator &, const DataType &)> &unpack)
3340  {
3341 #ifndef DEAL_II_WITH_MPI
3342  (void)mesh;
3343  (void)pack;
3344  (void)unpack;
3345  Assert(false, ExcMessage("GridTools::exchange_cell_data_to_ghosts() requires MPI."));
3346 #else
3347  constexpr int dim = MeshType::dimension;
3348  constexpr int spacedim = MeshType::space_dimension;
3349  auto tria =
3350  static_cast<const parallel::Triangulation<dim, spacedim>*>(&mesh.get_triangulation());
3351  Assert (tria != nullptr,
3352  ExcMessage("The function exchange_cell_data_to_ghosts() only works with parallel triangulations."));
3353 
3354  // map neighbor_id -> data_buffer where we accumulate the data to send
3355  typedef std::map<::types::subdomain_id, CellDataTransferBuffer<dim, DataType> >
3356  DestinationToBufferMap;
3357  DestinationToBufferMap destination_to_data_buffer_map;
3358 
3359  std::map<unsigned int, std::set<::types::subdomain_id> >
3360  vertices_with_ghost_neighbors = tria->compute_vertices_with_ghost_neighbors();
3361 
3362  for (auto cell : tria->active_cell_iterators())
3363  if (cell->is_locally_owned())
3364  {
3365  std::set<::types::subdomain_id> send_to;
3366  for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
3367  {
3368  const std::map<unsigned int, std::set<::types::subdomain_id> >::const_iterator
3369  neighbor_subdomains_of_vertex
3370  = vertices_with_ghost_neighbors.find (cell->vertex_index(v));
3371 
3372  if (neighbor_subdomains_of_vertex ==
3373  vertices_with_ghost_neighbors.end())
3374  continue;
3375 
3376  Assert(neighbor_subdomains_of_vertex->second.size()!=0,
3377  ExcInternalError());
3378 
3379  send_to.insert(neighbor_subdomains_of_vertex->second.begin(),
3380  neighbor_subdomains_of_vertex->second.end());
3381  }
3382 
3383  if (send_to.size() > 0)
3384  {
3385  // this cell's data needs to be sent to someone
3386  typename MeshType::active_cell_iterator
3387  mesh_it (tria, cell->level(), cell->index(), &mesh);
3388 
3389  const boost::optional<DataType> data = pack(mesh_it);
3390 
3391  if (data)
3392  {
3393  const CellId cellid = cell->id();
3394 
3395  for (auto it : send_to)
3396  {
3397  const ::types::subdomain_id subdomain = it;
3398 
3399  // find the data buffer for proc "subdomain" if it exists
3400  // or create an empty one otherwise
3401  typename DestinationToBufferMap::iterator p
3402  = destination_to_data_buffer_map.insert (std::make_pair(subdomain,
3403  CellDataTransferBuffer<dim, DataType>()))
3404  .first;
3405 
3406  p->second.cell_ids.emplace_back(cellid);
3407  p->second.data.emplace_back(data.get());
3408  }
3409  }
3410  }
3411  }
3412 
3413 
3414  // 2. send our messages
3415  std::set<::types::subdomain_id> ghost_owners = tria->ghost_owners();
3416  const unsigned int n_ghost_owners = ghost_owners.size();
3417  std::vector<std::vector<char> > sendbuffers (n_ghost_owners);
3418  std::vector<MPI_Request> requests (n_ghost_owners);
3419 
3420  unsigned int idx=0;
3421  for (auto it = ghost_owners.begin();
3422  it!=ghost_owners.end();
3423  ++it, ++idx)
3424  {
3425  CellDataTransferBuffer<dim, DataType> &data = destination_to_data_buffer_map[*it];
3426 
3427  // pack all the data into the buffer for this recipient and send it.
3428  // keep data around till we can make sure that the packet has been
3429  // received
3430  sendbuffers[idx] = Utilities::pack(data);
3431  const int ierr = MPI_Isend(sendbuffers[idx].data(), sendbuffers[idx].size(),
3432  MPI_BYTE, *it,
3433  786, tria->get_communicator(), &requests[idx]);
3434  AssertThrowMPI(ierr);
3435  }
3436 
3437  // 3. receive messages
3438  std::vector<char> receive;
3439  for (unsigned int idx=0; idx<n_ghost_owners; ++idx)
3440  {
3441  MPI_Status status;
3442  int len;
3443  int ierr = MPI_Probe(MPI_ANY_SOURCE, 786, tria->get_communicator(), &status);
3444  AssertThrowMPI(ierr);
3445  ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3446  AssertThrowMPI(ierr);
3447 
3448  receive.resize(len);
3449 
3450  char *ptr = receive.data();
3451  ierr = MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
3452  tria->get_communicator(), &status);
3453  AssertThrowMPI(ierr);
3454 
3455  auto cellinfo = Utilities::unpack<CellDataTransferBuffer<dim, DataType> >(receive);
3456 
3457  DataType *data = cellinfo.data.data();
3458  for (unsigned int c=0; c<cellinfo.cell_ids.size(); ++c, ++data)
3459  {
3461  tria_cell = cellinfo.cell_ids[c].to_cell(*tria);
3462 
3463  const typename MeshType::active_cell_iterator
3464  cell (tria, tria_cell->level(), tria_cell->index(), &mesh);
3465 
3466  unpack(cell, *data);
3467  }
3468  }
3469 
3470  // make sure that all communication is finished
3471  // when we leave this function.
3472  if (requests.size())
3473  {
3474  const int ierr = MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
3475  AssertThrowMPI(ierr);
3476  }
3477 #endif // DEAL_II_WITH_MPI
3478  }
3479 }
3480 
3481 #endif
3482 
3483 DEAL_II_NAMESPACE_CLOSE
3484 
3485 /*---------------------------- grid_tools.h ---------------------------*/
3486 /* end of #ifndef dealii_grid_tools_h */
3487 #endif
3488 /*---------------------------- grid_tools.h ---------------------------*/
void remove_hanging_nodes(Triangulation< dim, spacedim > &tria, const bool isotropic=false, const unsigned int max_iterations=100)
Definition: grid_tools.cc:3469
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={})
Definition: grid_tools.cc:3351
static ::ExceptionBase & ExcScalingFactorNotPositive(double arg1)
static const unsigned int invalid_unsigned_int
Definition: types.h:173
std::map< unsigned int, Point< spacedim > > get_all_vertices_at_boundary(const Triangulation< dim, spacedim > &tria)
Definition: grid_tools.cc:826
void copy_boundary_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool reset_boundary_ids=false)
Definition: grid_tools.cc:3331
double diameter(const Triangulation< dim, spacedim > &tria)
Definition: grid_tools.cc:76
void distort_random(const double factor, Triangulation< dim, spacedim > &triangulation, const bool keep_boundary=true)
Definition: grid_tools.cc:858
void delete_duplicated_vertices(std::vector< Point< spacedim > > &all_vertices, std::vector< CellData< dim > > &cells, SubCellData &subcelldata, std::vector< unsigned int > &considered_vertices, const double tol=1e-12)
Definition: grid_tools.cc:491
static ::ExceptionBase & ExcPointNotFoundInCoarseGrid(Point< N > arg1)
std::map< unsigned int, Point< spacedim > > extract_used_vertices(const Triangulation< dim, spacedim > &container, const Mapping< dim, spacedim > &mapping=StaticMappingQ1< dim, spacedim >::mapping)
Definition: grid_tools.cc:4543
bool have_same_coarse_mesh(const Triangulation< dim, spacedim > &mesh_1, const Triangulation< dim, spacedim > &mesh_2)
MeshType< dim, spacedim >::active_cell_iterator find_active_cell_around_point(const MeshType< dim, spacedim > &mesh, const Point< spacedim > &p, const std::vector< bool > &marked_vertices=std::vector< bool >())
Definition: grid_tools.cc:1421
std::pair< unsigned int, double > get_longest_direction(typename Triangulation< dim, spacedim >::active_cell_iterator cell)
Definition: grid_tools.cc:3439
BoundingBox< spacedim > compute_bounding_box(const Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:380
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
unsigned int find_closest_vertex_of_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell, const Point< spacedim > &position)
Definition: grid_tools.cc:1731
void load(Archive &ar, const unsigned int version)
std::vector< typename MeshType::active_cell_iterator > compute_ghost_cell_layer_within_distance(const MeshType &mesh, const double layer_thickness)
void regularize_corner_cells(Triangulation< dim, spacedim > &tria, const double limit_angle_fraction=.75)
Definition: grid_tools.cc:3534
bool orthogonal_equality(std::bitset< 3 > &orientation, const FaceIterator &face1, const FaceIterator &face2, const int direction, const Tensor< 1, FaceIterator::AccessorType::space_dimension > &offset=Tensor< 1, FaceIterator::AccessorType::space_dimension >(), const FullMatrix< double > &matrix=FullMatrix< double >())
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:680
double volume(const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping=(StaticMappingQ1< dim, spacedim >::mapping))
Definition: grid_tools.cc:131
IteratorRange< active_cell_iterator > active_cell_iterators() const
Definition: tria.cc:10632
unsigned int boundary_id
Definition: types.h:110
std::vector< std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > > vertex_to_cell_map(const Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:1978
SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
static ::ExceptionBase & ExcNonExistentSubdomain(int arg1)
std::vector< typename MeshType::active_cell_iterator > get_active_child_cells(const typename MeshType::cell_iterator &cell)
T unpack(const std::vector< char > &buffer)
Definition: utilities.h:1123
std::map< unsigned int, types::global_vertex_index > compute_local_to_global_vertex_index_map(const parallel::distributed::Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2022
numbers::NumberTraits< Number >::real_type norm() const
Definition: tensor.h:1273
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)
double maximal_cell_diameter(const Triangulation< dim, spacedim > &triangulation, const Mapping< dim, spacedim > &mapping=(StaticMappingQ1< dim, spacedim >::mapping))
Definition: grid_tools.cc:2830
std::bitset< 3 > orientation
Definition: grid_tools.h:2093
void partition_multigrid_levels(Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2691
double minimal_cell_diameter(const Triangulation< dim, spacedim > &triangulation, const Mapping< dim, spacedim > &mapping=(StaticMappingQ1< dim, spacedim >::mapping))
Definition: grid_tools.cc:2804
void partition_triangulation_zorder(const unsigned int n_partitions, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2592
static Tensor< 1, dim > d_linear_shape_function_gradient(const Point< dim > &xi, const unsigned int i)
void partition_triangulation(const unsigned int n_partitions, Triangulation< dim, spacedim > &triangulation, const SparsityTools::Partitioner partitioner=SparsityTools::Partitioner::metis)
Definition: grid_tools.cc:2406
SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
void get_vertex_connectivity_of_cells(const Triangulation< dim, spacedim > &triangulation, DynamicSparsityPattern &connectivity)
Definition: grid_tools.cc:2354
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)
static ::ExceptionBase & ExcTriangulationHasBeenRefined()
Definition: tria.h:76
static ::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
return_type guess_point_owner(const std::vector< std::vector< BoundingBox< spacedim > > > &global_bboxes, const std::vector< Point< spacedim > > &points)
Definition: grid_tools.cc:1928
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)
double cell_measure(const std::vector< Point< dim > > &all_vertices, const unsigned int(&vertex_indices)[GeometryInfo< dim >::vertices_per_cell])
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:346
T sum(const T &t, const MPI_Comm &mpi_communicator)
void get_vertex_connectivity_of_cells_on_level(const Triangulation< dim, spacedim > &triangulation, const unsigned int level, DynamicSparsityPattern &connectivity)
Definition: grid_tools.cc:2379
#define Assert(cond, exc)
Definition: exceptions.h:1142
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::vector< CellId > cell_ids
Definition: grid_tools.h:2520
Abstract base class for mapping classes.
Definition: dof_tools.h:46
void get_active_neighbors(const typename MeshType::active_cell_iterator &cell, std::vector< typename MeshType::active_cell_iterator > &active_neighbors)
void collect_periodic_faces(const MeshType &mesh, const types::boundary_id b_id1, const types::boundary_id b_id2, const 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 >())
#define DeclException0(Exception0)
Definition: exceptions.h:323
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)
Definition: grid_tools.cc:1808
unsigned int face_idx[2]
Definition: grid_tools.h:2086
void save(Archive &ar, const unsigned int version) const
void remove_anisotropy(Triangulation< dim, spacedim > &tria, const double max_ratio=1.6180339887, const unsigned int max_iterations=5)
Definition: grid_tools.cc:3504
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)
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)
Definition: grid_tools.cc:4316
void copy_material_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool compute_face_ids=false)
Definition: grid_tools.cc:3413
void rotate(const double angle, Triangulation< 2 > &triangulation)
Definition: grid_tools.cc:661
Triangulation< dim, spacedim >::DistortedCellList fix_up_distorted_child_cells(const typename Triangulation< dim, spacedim >::DistortedCellList &distorted_cells, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:3298
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())
Definition: grid_tools.cc:3841
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)
Definition: grid_tools.cc:1557
unsigned int subdomain_id
Definition: types.h:42
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
Definition: hp.h:102
std::vector< typename MeshType::active_cell_iterator > compute_ghost_cell_halo_layer(const MeshType &mesh)
Definition: cell_id.h:61
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
Point< Iterator::AccessorType::space_dimension > project_to_object(const Iterator &object, const Point< Iterator::AccessorType::space_dimension > &trial_point)
#define AssertThrowMPI(error_code)
Definition: exceptions.h:1314
std::map< types::global_dof_index, std::vector< typename DoFHandlerType::active_cell_iterator > > get_dof_to_support_patch_map(DoFHandlerType &dof_handler)
static double d_linear_shape_function(const Point< dim > &xi, const unsigned int i)
void transform(const Transformation &transformation, Triangulation< dim, spacedim > &triangulation)
size_t pack(const T &object, std::vector< char > &dest_buffer)
Definition: utilities.h:1003
std::vector< typename MeshType< dim, spacedim >::active_cell_iterator > find_cells_adjacent_to_vertex(const MeshType< dim, spacedim > &container, const unsigned int vertex_index)
Definition: grid_tools.cc:1223
void get_subdomain_association(const Triangulation< dim, spacedim > &triangulation, std::vector< types::subdomain_id > &subdomain)
Definition: grid_tools.cc:2716
void get_face_connectivity_of_cells(const Triangulation< dim, spacedim > &triangulation, DynamicSparsityPattern &connectivity)
Definition: grid_tools.cc:2307
void delete_unused_vertices(std::vector< Point< spacedim > > &vertices, std::vector< CellData< dim > > &cells, SubCellData &subcelldata)
Definition: grid_tools.cc:395
std::array< unsigned int, 4 > binary_type
Definition: cell_id.h:71
FullMatrix< double > matrix
Definition: grid_tools.h:2107
static ::ExceptionBase & ExcNotImplemented()
std::vector< bool > get_locally_owned_vertices(const Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:2748
void exchange_cell_data_to_ghosts(const MeshType &mesh, const std::function< boost::optional< DataType >(const typename MeshType::active_cell_iterator &)> &pack, const std::function< void(const typename MeshType::active_cell_iterator &, const DataType &)> &unpack)
std::vector< typename Container::cell_iterator > get_cells_at_coarsest_common_level(const std::vector< typename Container::active_cell_iterator > &patch_cells)
static ::ExceptionBase & ExcVertexNotUsed(unsigned int arg1)
std::list< std::pair< typename MeshType::cell_iterator, typename MeshType::cell_iterator > > get_finest_common_cells(const MeshType &mesh_1, const MeshType &mesh_2)
static ::ExceptionBase & ExcPointNotFound(Point< N > arg1)
void shift(const Tensor< 1, spacedim > &shift_vector, Triangulation< dim, spacedim > &triangulation)
Definition: grid_tools.cc:652
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)
unsigned int count_cells_with_subdomain_association(const Triangulation< dim, spacedim > &triangulation, const types::subdomain_id subdomain)
Definition: grid_tools.cc:2731
unsigned int find_closest_vertex(const std::map< unsigned int, Point< spacedim >> &vertices, const Point< spacedim > &p)
std::vector< typename MeshType::active_cell_iterator > get_patch_around_cell(const typename MeshType::active_cell_iterator &cell)
static ::ExceptionBase & ExcInternalError()