16 #ifndef dealii_grid_tools_h 17 #define dealii_grid_tools_h 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> 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> 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> 51 DEAL_II_NAMESPACE_OPEN
63 template <
int,
int>
class MappingCollection;
70 template <
int dim,
int spacedim,
class MeshType>
71 class ActiveCellIterator
75 typedef typename MeshType::active_cell_iterator type;
82 template <
int dim,
int spacedim>
83 class ActiveCellIterator<dim, spacedim, ::
DoFHandler<dim, spacedim> >
89 template <
int dim,
int spacedim>
90 class ActiveCellIterator<dim, spacedim, ::
hp::DoFHandler<dim, spacedim> >
108 template <
int dim,
int spacedim>
122 template <
int dim,
int spacedim>
151 template <
int dim,
int spacedim>
165 template <
int dim,
int spacedim>
180 template <
int dim,
int spacedim>
203 template <
int dim,
typename T>
219 template <
int dim,
int spacedim>
241 template <
typename Iterator>
268 template <
int dim,
int spacedim>
288 template <
int dim,
int spacedim>
292 std::vector<unsigned int> &considered_vertices,
293 const double tol=1e-12);
324 template <
int dim,
typename Transformation,
int spacedim>
325 void transform (
const Transformation &transformation,
333 template <
int dim,
int spacedim>
345 void rotate (
const double angle,
362 rotate (
const double angle,
363 const unsigned int axis,
428 const bool solve_for_absolute_positions =
false);
435 template <
int dim,
int spacedim>
436 std::map<unsigned int,Point<spacedim> >
446 template <
int dim,
int spacedim>
447 void scale (
const double scaling_factor,
460 template <
int dim,
int spacedim>
463 const bool keep_boundary=
true);
500 template <
int dim,
int spacedim>
503 const bool isotropic =
false,
504 const unsigned int max_iterations = 100);
531 template <
int dim,
int spacedim>
534 const double max_ratio = 1.6180339887,
535 const unsigned int max_iterations = 5);
625 template <
int dim,
int spacedim>
628 const double limit_angle_fraction=.75);
674 template <
int dim,
int spacedim>
677 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator >,
678 std::vector< std::vector< Point<dim> > >,
679 std::vector< std::vector<unsigned int> > >
749 template <
int dim,
int spacedim>
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 > >
794 template <
int dim,
int spacedim>
810 template<
int spacedim>
841 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
845 const std::vector<bool> &marked_vertices = std::vector<bool>());
872 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
875 const MeshType<dim, spacedim> &mesh,
877 const std::vector<bool> &marked_vertices = std::vector<bool>());
904 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
906 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
908 std::vector<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type>
911 const unsigned int vertex_index);
938 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
940 typename MeshType<dim,spacedim>::active_cell_iterator
942 typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type
946 const std::vector<bool> &marked_vertices = std::vector<bool>());
1032 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1034 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim> >
1036 std::pair<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type,
Point<dim> >
1039 const MeshType<dim,spacedim> &mesh,
1041 const std::vector<bool> &marked_vertices = std::vector<bool>());
1051 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1053 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim> >
1055 std::pair<typename ::internal::ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim> >::type,
Point<dim> >
1058 const MeshType<dim,spacedim> &mesh,
1060 const std::vector<std::set<
typename MeshType<dim,spacedim>::active_cell_iterator > > &
vertex_to_cell_map,
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>());
1086 template <
int dim,
int spacedim>
1087 std::pair<typename hp::DoFHandler<dim, spacedim>::active_cell_iterator,
Point<dim> >
1098 template <
int dim,
int spacedim>
1099 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
Point<dim> >
1103 const std::vector<bool> &marked_vertices = std::vector<bool>());
1126 template <
class MeshType>
1127 std::vector<typename MeshType::active_cell_iterator>
1140 template <
class MeshType>
1143 std::vector<typename MeshType::active_cell_iterator> &active_neighbors);
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);
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);
1233 template <
class MeshType>
1234 std::vector<typename MeshType::active_cell_iterator>
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);
1320 template <
class MeshType>
1321 std::vector<typename MeshType::active_cell_iterator>
1323 const double layer_thickness);
1340 template <
class MeshType>
1343 (
const MeshType &mesh,
1344 const std::function<
bool (
const typename MeshType::active_cell_iterator &)> &predicate );
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,
1426 template <
int spacedim>
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 > > >
1447 template <
int dim,
int spacedim>
1448 std::vector<std::set<typename Triangulation<dim,spacedim>::active_cell_iterator> >
1465 template <
int dim,
int spacedim>
1466 std::vector<std::vector<Tensor<1,spacedim> > >
1477 template <
int dim,
int spacedim>
1493 template <
int dim,
int spacedim>
1494 std::map<unsigned int, types::global_vertex_index>
1511 template <
int dim,
int spacedim>
1512 std::pair<unsigned int, double>
1529 template <
int dim,
int spacedim>
1542 template <
int dim,
int spacedim>
1555 template <
int dim,
int spacedim>
1558 const unsigned int level,
1579 template <
int dim,
int spacedim>
1596 template <
int dim,
int spacedim>
1599 const std::vector<unsigned int> &cell_weights,
1649 template <
int dim,
int spacedim>
1667 template <
int dim,
int spacedim>
1670 const std::vector<unsigned int> &cell_weights,
1683 template <
int dim,
int spacedim>
1697 template <
int dim,
int spacedim>
1711 template <
int dim,
int spacedim>
1714 std::vector<types::subdomain_id> &subdomain);
1730 template <
int dim,
int spacedim>
1765 template <
int dim,
int spacedim>
1803 template <
typename MeshType>
1804 std::list<std::pair<
typename MeshType::cell_iterator,
1805 typename MeshType::cell_iterator> >
1807 const MeshType &mesh_2);
1818 template <
int dim,
int spacedim>
1832 template <
typename MeshType>
1835 const MeshType &mesh_2);
1858 template <
int dim,
int spacedim>
1913 template <
class MeshType>
1914 std::vector<typename MeshType::active_cell_iterator>
1941 template <
class Container>
1942 std::vector<typename Container::cell_iterator>
2013 template <
class Container>
2016 const std::vector<typename Container::active_cell_iterator> &patch,
2019 typename Container::active_cell_iterator> &patch_to_global_tria_map);
2057 template <
class DoFHandlerType>
2058 std::map< types::global_dof_index,std::vector<typename DoFHandlerType::active_cell_iterator> >
2074 template <
typename CellIterator>
2176 template <
typename FaceIterator>
2179 const FaceIterator &face1,
2180 const FaceIterator &face2,
2181 const int direction,
2190 template <
typename FaceIterator>
2193 const FaceIterator &face2,
2194 const int direction,
2258 template <
typename MeshType>
2261 (
const MeshType &mesh,
2264 const int direction,
2292 template <
typename MeshType>
2295 (
const MeshType &mesh,
2297 const int direction,
2330 template <
int dim,
int spacedim>
2332 const bool reset_boundary_ids=
false);
2357 template <
int dim,
int spacedim>
2359 const std::vector<types::manifold_id> &dst_manifold_ids,
2361 const std::vector<types::boundary_id> &reset_boundary_ids = {});
2394 template <
int dim,
int spacedim>
2396 const bool compute_face_ids=
false);
2481 template <
typename DataType,
typename MeshType>
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);
2497 template<
int spacedim>
2498 std::vector< std::vector< BoundingBox<spacedim> > >
2500 MPI_Comm mpi_communicator);
2514 template <
int dim,
typename T>
2534 template <
class Archive>
2535 void save (Archive &ar,
2536 const unsigned int version)
const;
2542 template <
class Archive>
2543 void load (Archive &ar,
2544 const unsigned int version);
2546 BOOST_SERIALIZATION_SPLIT_MEMBER()
2559 <<
"The number of partitions you gave is " << arg1
2560 <<
", but must be greater than zero.");
2566 <<
"The subdomain id " << arg1
2567 <<
" has no cells associated with it.");
2578 <<
"The scaling factor must be positive, but it is " << arg1 <<
".");
2585 <<
"The point <" << arg1
2586 <<
"> could not be found inside any of the " 2587 <<
"coarse grid cells.");
2594 <<
"The point <" << arg1
2595 <<
"> could not be found inside any of the " 2596 <<
"subcells of a coarse grid cell.");
2603 <<
"The given vertex with index " << arg1
2604 <<
" is not used in the given triangulation.");
2619 template <
int dim,
typename T>
2623 return std::numeric_limits<double>::quiet_NaN();
2626 template <
int dim,
typename Predicate,
int spacedim>
2627 void transform (
const Predicate &predicate,
2630 std::vector<bool> treated_vertices (triangulation.n_vertices(),
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)
2647 cell->vertex(v) = predicate(cell->vertex(v));
2649 treated_vertices[cell->vertex_index(v)] =
true;
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())
2665 cell->face(face)->child(0)->vertex(1)
2666 = (cell->face(face)->vertex(0) +
2667 cell->face(face)->vertex(1)) / 2;
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())
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;
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;
2698 triangulation.signals.mesh_movement();
2703 template <
class MeshType>
2704 std::vector<typename MeshType::active_cell_iterator>
2707 std::vector<typename MeshType::active_cell_iterator> child_cells;
2709 if (cell->has_children())
2711 for (
unsigned int child=0;
2712 child<cell->n_children(); ++child)
2713 if (cell->child (child)->has_children())
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());
2721 child_cells.push_back (cell->child(child));
2729 template <
class MeshType>
2732 std::vector<typename MeshType::active_cell_iterator> &active_neighbors)
2734 active_neighbors.clear ();
2735 for (
unsigned int n=0; n<GeometryInfo<MeshType::dimension>::faces_per_cell; ++n)
2736 if (! cell->at_boundary(n))
2738 if (MeshType::dimension == 1)
2745 typename MeshType::cell_iterator
2746 neighbor_child = cell->neighbor(n);
2747 if (!neighbor_child->active())
2749 while (neighbor_child->has_children())
2750 neighbor_child = neighbor_child->child (n==0 ? 1 : 0);
2752 Assert (neighbor_child->neighbor(n==0 ? 1 : 0)==cell,
2755 active_neighbors.push_back (neighbor_child);
2759 if (cell->face(n)->has_children())
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));
2770 active_neighbors.push_back(cell->neighbor(n));
2780 namespace ProjectToObject
2794 struct CrossDerivative
2796 const unsigned int direction_0;
2797 const unsigned int direction_1;
2799 CrossDerivative(
const unsigned int d0,
const unsigned int d1);
2803 CrossDerivative::CrossDerivative(
const unsigned int d0,
const unsigned int d1)
2815 template <
typename F>
2818 centered_first_difference(
const double center,
2821 -> decltype(f(center) - f(center))
2823 return (f(center + step) - f(center - step))/(2.0*step);
2832 template <
typename F>
2835 centered_second_difference(
const double center,
2838 -> decltype(f(center) - f(center))
2840 return (f(center + step) - 2.0*f(center) + f(center - step))/(step*step);
2854 template <
int structdim,
typename F>
2858 (
const CrossDerivative cross_derivative,
2862 -> decltype(f(center) - f(center))
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)
2882 template <
int spacedim,
int structdim,
typename F>
2886 (
const unsigned int row_n,
2887 const unsigned int dependent_direction,
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."));
2904 ({row_n, dependent_direction},
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];
2919 template <
typename Iterator,
int spacedim,
int structdim>
2921 project_to_d_linear_object (
const Iterator &
object,
2956 for (
unsigned int d=0;
d<structdim; ++
d)
2960 for (
unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2961 x_k += object->vertex(i) *
2967 for (
unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2968 F_k += (x_k-trial_point)*
object->vertex(i) *
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)
2978 H_k += (
object->vertex(i) *
object->vertex(j)) * tmp;
2985 for (
unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
2986 x_k += object->vertex(i) *
2989 if (delta_xi.
norm() < 1
e-7)
3005 template <
int structdim>
3011 static const std::size_t n_vertices_per_cell
3013 std::array<double, n_vertices_per_cell> copied_weights;
3014 for (
unsigned int i = 0; i < n_vertices_per_cell; ++i)
3016 copied_weights[i] = v[i];
3017 if (v[i] < 0.0 || v[i] > 1.0)
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) < 1
e-10;
3028 template <
typename Iterator>
3033 const int spacedim = Iterator::AccessorType::space_dimension;
3034 const int structdim = Iterator::AccessorType::structure_dimension;
3038 if (structdim >= spacedim)
3039 return projected_point;
3040 else if (structdim == 1 || structdim == 2)
3042 using namespace internal::ProjectToObject;
3047 const int dim = Iterator::AccessorType::dimension;
3049 if (structdim == 2 &&
3053 projected_point = project_to_d_linear_object<Iterator, spacedim, structdim>(object, trial_point);
3097 const double step_size =
object->diameter()/64.0;
3101 std::array<Point<spacedim>, n_vertices_per_cell> vertices;
3102 for (
unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
3104 vertices[vertex_n] = object->vertex(vertex_n);
3106 auto get_point_from_weights =
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));
3119 double guess_weights_sum = 0.0;
3120 for (
unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
3123 const double distance = vertices[vertex_n].
distance(trial_point);
3124 if (distance == 0.0)
3126 guess_weights = 0.0;
3127 guess_weights[vertex_n] = 1.0;
3128 guess_weights_sum = 1.0;
3133 guess_weights[vertex_n] = 1.0/distance;
3134 guess_weights_sum += guess_weights[vertex_n];
3137 guess_weights /= guess_weights_sum;
3146 for (
unsigned int outer_n = 0; outer_n < 40; ++outer_n)
3148 const unsigned int dependent_direction = n_vertices_per_cell - 1;
3150 for (
unsigned int row_n = 0;
3151 row_n < n_vertices_per_cell;
3154 if (row_n != dependent_direction)
3156 current_gradient[row_n] = gradient_entry<spacedim, structdim>
3158 dependent_direction,
3162 get_point_from_weights);
3164 current_gradient[dependent_direction] -= current_gradient[row_n];
3182 double gradient_weight = -0.5;
3183 auto gradient_weight_objective_function = [&](
const double gradient_weight_guess)
3186 return (trial_point -
3187 get_point_from_weights(guess_weights +
3188 gradient_weight_guess*current_gradient)).norm_square();
3191 for (
unsigned int inner_n = 0; inner_n < 10; ++inner_n)
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);
3199 if (std::abs(update_denominator) == 0.0)
3201 gradient_weight = gradient_weight - update_numerator/update_denominator;
3206 if (std::abs(gradient_weight) > 10)
3208 gradient_weight = -10.0;
3218 guess_weights + gradient_weight*current_gradient;
3220 double new_gradient_weight = gradient_weight;
3221 for (
unsigned int iteration_count = 0; iteration_count < 40; ++iteration_count)
3223 if (internal::weights_are_ok<structdim>(tentative_weights))
3226 for (
unsigned int i = 0; i < n_vertices_per_cell; ++i)
3228 if (tentative_weights[i] < 0.0)
3230 tentative_weights -= (tentative_weights[i]/current_gradient[i])
3233 if (tentative_weights[i] < 0.0 || 1.0 < tentative_weights[i])
3235 new_gradient_weight /= 2.0;
3236 tentative_weights = guess_weights + new_gradient_weight*current_gradient;
3243 if (!internal::weights_are_ok<structdim>(tentative_weights))
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;
3255 projected_point = get_point_from_weights(guess_weights);
3265 for (
unsigned int line_n = 0; line_n < GeometryInfo<structdim>::lines_per_cell;
3271 std::sort(line_projections.begin(), line_projections.end(),
3274 return a.
distance(trial_point) <
b.distance(trial_point);
3276 if (line_projections[0].distance(trial_point)
3277 < projected_point.
distance(trial_point))
3278 projected_point = line_projections[0];
3284 return projected_point;
3287 return projected_point;
3292 template <
int dim,
typename T>
3293 template <
class Archive>
3295 CellDataTransferBuffer<dim,T>::save (Archive &ar,
3296 const unsigned int )
const 3298 Assert(cell_ids.size() == data.size(),
3301 const size_t n_cells = cell_ids.size();
3303 for (
auto &it : cell_ids)
3314 template <
int dim,
typename T>
3315 template <
class Archive>
3317 CellDataTransferBuffer<dim,T>::load (Archive &ar,
3318 const unsigned int )
3323 cell_ids.reserve(n_cells);
3324 for (
unsigned int c=0; c<n_cells; ++c)
3328 cell_ids.emplace_back(value);
3335 template <
typename DataType,
typename MeshType>
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)
3341 #ifndef DEAL_II_WITH_MPI 3345 Assert(
false,
ExcMessage(
"GridTools::exchange_cell_data_to_ghosts() requires MPI."));
3347 constexpr
int dim = MeshType::dimension;
3348 constexpr
int spacedim = MeshType::space_dimension;
3352 ExcMessage(
"The function exchange_cell_data_to_ghosts() only works with parallel triangulations."));
3355 typedef std::map<::types::subdomain_id, CellDataTransferBuffer<dim, DataType> >
3356 DestinationToBufferMap;
3357 DestinationToBufferMap destination_to_data_buffer_map;
3359 std::map<unsigned int, std::set<::types::subdomain_id> >
3360 vertices_with_ghost_neighbors = tria->compute_vertices_with_ghost_neighbors();
3363 if (cell->is_locally_owned())
3365 std::set<::types::subdomain_id> send_to;
3366 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
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));
3372 if (neighbor_subdomains_of_vertex ==
3373 vertices_with_ghost_neighbors.end())
3376 Assert(neighbor_subdomains_of_vertex->second.size()!=0,
3379 send_to.insert(neighbor_subdomains_of_vertex->second.begin(),
3380 neighbor_subdomains_of_vertex->second.end());
3383 if (send_to.size() > 0)
3386 typename MeshType::active_cell_iterator
3387 mesh_it (tria, cell->level(), cell->index(), &mesh);
3389 const boost::optional<DataType> data =
pack(mesh_it);
3393 const CellId cellid = cell->id();
3395 for (
auto it : send_to)
3397 const ::types::subdomain_id subdomain = it;
3401 typename DestinationToBufferMap::iterator p
3402 = destination_to_data_buffer_map.insert (std::make_pair(subdomain,
3403 CellDataTransferBuffer<dim, DataType>()))
3406 p->second.cell_ids.emplace_back(cellid);
3407 p->second.data.emplace_back(data.get());
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);
3421 for (
auto it = ghost_owners.begin();
3422 it!=ghost_owners.end();
3425 CellDataTransferBuffer<dim, DataType> &data = destination_to_data_buffer_map[*it];
3431 const int ierr = MPI_Isend(sendbuffers[idx].data(), sendbuffers[idx].size(),
3433 786, tria->get_communicator(), &requests[idx]);
3438 std::vector<char> receive;
3439 for (
unsigned int idx=0; idx<n_ghost_owners; ++idx)
3443 int ierr = MPI_Probe(MPI_ANY_SOURCE, 786, tria->get_communicator(), &status);
3445 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
3448 receive.resize(len);
3450 char *ptr = receive.data();
3451 ierr = MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
3452 tria->get_communicator(), &status);
3455 auto cellinfo = Utilities::unpack<CellDataTransferBuffer<dim, DataType> >(receive);
3457 DataType *data = cellinfo.data.data();
3458 for (
unsigned int c=0; c<cellinfo.cell_ids.size(); ++c, ++data)
3461 tria_cell = cellinfo.cell_ids[c].to_cell(*tria);
3463 const typename MeshType::active_cell_iterator
3464 cell (tria, tria_cell->level(), tria_cell->index(), &mesh);
3472 if (requests.size())
3474 const int ierr = MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
3477 #endif // DEAL_II_WITH_MPI 3483 DEAL_II_NAMESPACE_CLOSE
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={})
static ::ExceptionBase & ExcScalingFactorNotPositive(double arg1)
static const unsigned int invalid_unsigned_int
void copy_boundary_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool reset_boundary_ids=false)
static ::ExceptionBase & ExcPointNotFoundInCoarseGrid(Point< N > arg1)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
IteratorRange< active_cell_iterator > active_cell_iterators() const
SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
static ::ExceptionBase & ExcNonExistentSubdomain(int arg1)
T unpack(const std::vector< char > &buffer)
numbers::NumberTraits< Number >::real_type norm() const
static Tensor< 1, dim > d_linear_shape_function_gradient(const Point< dim > &xi, const unsigned int i)
SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
static ::ExceptionBase & ExcTriangulationHasBeenRefined()
static ::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
T sum(const T &t, const MPI_Comm &mpi_communicator)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
#define DeclException0(Exception0)
void copy_material_to_manifold_id(Triangulation< dim, spacedim > &tria, const bool compute_face_ids=false)
unsigned int subdomain_id
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
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
#define AssertThrowMPI(error_code)
static double d_linear_shape_function(const Point< dim > &xi, const unsigned int i)
size_t pack(const T &object, std::vector< char > &dest_buffer)
std::array< unsigned int, 4 > binary_type
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcVertexNotUsed(unsigned int arg1)
static ::ExceptionBase & ExcPointNotFound(Point< N > arg1)
static ::ExceptionBase & ExcInternalError()