16 #ifndef dealii_grid_tools_h
17 # define dealii_grid_tools_h
52 # include <boost/archive/binary_iarchive.hpp>
53 # include <boost/archive/binary_oarchive.hpp>
54 # include <boost/geometry/index/rtree.hpp>
55 # include <boost/random/mersenne_twister.hpp>
56 # include <boost/serialization/array.hpp>
57 # include <boost/serialization/vector.hpp>
59 # ifdef DEAL_II_WITH_ZLIB
60 # include <boost/iostreams/device/back_inserter.hpp>
61 # include <boost/iostreams/filter/gzip.hpp>
62 # include <boost/iostreams/filtering_stream.hpp>
63 # include <boost/iostreams/stream.hpp>
87 class MappingCollection;
95 template <
int dim,
int spacedim,
class MeshType>
100 using type =
typename MeshType::active_cell_iterator;
107 template <
int dim,
int spacedim>
118 template <
int dim,
int spacedim>
119 class ActiveCellIterator<dim, spacedim, ::
hp::DoFHandler<dim, spacedim>>
138 template <
int dim,
int spacedim>
152 template <
int dim,
int spacedim>
182 template <
int dim,
int spacedim>
186 (ReferenceCells::get_hypercube<dim>()
187 .
template get_default_linear_mapping<dim, spacedim>()));
199 template <
int dim,
int spacedim>
204 (ReferenceCells::get_hypercube<dim>()
205 .
template get_default_linear_mapping<dim, spacedim>()));
217 template <
int dim,
int spacedim>
222 (ReferenceCells::get_hypercube<dim>()
223 .
template get_default_linear_mapping<dim, spacedim>()));
285 template <
int dim,
int spacedim>
347 template <
int dim,
int spacedim>
368 template <
typename Iterator>
371 const Iterator &
object,
386 template <
int dim,
int spacedim>
388 tuple<std::vector<Point<spacedim>>, std::vector<CellData<dim>>,
SubCellData>
413 template <
int dim,
int spacedim>
436 template <
int dim,
int spacedim>
441 std::vector<unsigned int> & considered_vertices,
442 const double tol = 1
e-12);
462 template <
int dim,
int spacedim>
540 template <
int dim,
typename Transformation,
int spacedim>
550 template <
int dim,
int spacedim>
584 const unsigned int axis,
649 const bool solve_for_absolute_positions =
false);
656 template <
int dim,
int spacedim>
657 std::map<unsigned int, Point<spacedim>>
667 template <
int dim,
int spacedim>
669 scale(
const double scaling_factor,
686 template <
int dim,
int spacedim>
691 const bool keep_boundary =
true,
692 const unsigned int seed = boost::random::mt19937::default_seed);
727 template <
int dim,
int spacedim>
730 const bool isotropic =
false,
731 const unsigned int max_iterations = 100);
757 template <
int dim,
int spacedim>
760 const double max_ratio = 1.6180339887,
761 const unsigned int max_iterations = 5);
852 template <
int dim,
int spacedim>
855 const double limit_angle_fraction = .75);
917 template <
int dim,
int spacedim>
920 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
921 std::vector<std::vector<Point<dim>>>,
922 std::vector<std::vector<unsigned int>>>
966 template <
int dim,
int spacedim>
969 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
970 std::vector<std::vector<Point<dim>>>,
971 std::vector<std::vector<unsigned int>>,
972 std::vector<unsigned int>>
1052 template <
int dim,
int spacedim>
1055 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>,
1056 std::vector<std::vector<Point<dim>>>,
1057 std::vector<std::vector<unsigned int>>,
1058 std::vector<std::vector<Point<spacedim>>>,
1059 std::vector<std::vector<unsigned int>>>
1067 const double tolerance = 1
e-10);
1085 template <
int dim,
int spacedim>
1094 std::vector<std::tuple<std::pair<int, int>,
1124 std::vector<std::tuple<unsigned int, unsigned int, unsigned int>>
1149 template <
int dim,
int spacedim>
1155 const double tolerance,
1156 const bool perform_handshake,
1157 const bool enforce_unique_mapping =
false);
1197 template <
int dim,
int spacedim>
1198 std::map<unsigned int, Point<spacedim>>
1202 (ReferenceCells::get_hypercube<dim>()
1203 .
template get_default_linear_mapping<dim, spacedim>()));
1214 template <
int spacedim>
1242 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1246 const std::vector<bool> & marked_vertices = {});
1271 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1274 const MeshType<dim, spacedim> &mesh,
1276 const std::vector<bool> & marked_vertices = {});
1298 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1300 std::vector<typename MeshType<dim, spacedim>::active_cell_iterator>
1303 typename ::internal::
1304 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type>
1307 const unsigned int vertex_index);
1371 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1373 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim>>
1375 std::pair<typename ::internal::
1376 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1380 const MeshType<dim, spacedim> &mesh,
1382 const std::vector<bool> &marked_vertices = {},
1383 const double tolerance = 1.e-10);
1392 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1394 typename MeshType<dim, spacedim>::active_cell_iterator
1396 typename ::internal::
1397 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type
1401 const std::vector<bool> &marked_vertices = {},
1402 const double tolerance = 1.e-10);
1410 template <
int dim,
int spacedim>
1411 std::pair<typename DoFHandler<dim, spacedim>::active_cell_iterator,
1417 const double tolerance = 1.e-10);
1470 template <
int dim,
int spacedim>
1471 std::pair<typename Triangulation<dim, spacedim>::active_cell_iterator,
1474 const Cache<dim, spacedim> &cache,
1478 const std::vector<bool> &marked_vertices = {},
1479 const double tolerance = 1.e-10);
1494 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1496 std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
Point<dim>>
1498 std::pair<typename ::internal::
1499 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1504 const MeshType<dim, spacedim> &mesh,
1507 std::set<
typename MeshType<dim, spacedim>::active_cell_iterator>>
1510 const typename MeshType<dim, spacedim>::active_cell_iterator &cell_hint =
1511 typename MeshType<dim, spacedim>::active_cell_iterator(),
1512 const std::vector<bool> & marked_vertices = {},
1515 const double tolerance = 1.e-10);
1538 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1540 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1543 std::vector<std::pair<
1544 typename ::internal::
1545 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1550 const MeshType<dim, spacedim> &mesh,
1552 const double tolerance,
1553 const std::pair<
typename MeshType<dim, spacedim>::active_cell_iterator,
1562 template <
int dim,
template <
int,
int>
class MeshType,
int spacedim>
1564 std::vector<std::pair<typename MeshType<dim, spacedim>::active_cell_iterator,
1567 std::vector<std::pair<
1568 typename ::internal::
1569 ActiveCellIterator<dim, spacedim, MeshType<dim, spacedim>>::type,
1574 const MeshType<dim, spacedim> &mesh,
1576 const double tolerance = 1
e-10,
1577 const std::vector<bool> & marked_vertices = {});
1600 template <
class MeshType>
1601 std::vector<typename MeshType::active_cell_iterator>
1628 template <
class MeshType>
1631 const typename MeshType::active_cell_iterator & cell,
1632 std::vector<typename MeshType::active_cell_iterator> &active_neighbors);
1683 template <
class MeshType>
1684 std::vector<typename MeshType::active_cell_iterator>
1686 const MeshType &mesh,
1687 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1698 template <
class MeshType>
1699 std::vector<typename MeshType::cell_iterator>
1701 const MeshType &mesh,
1702 const std::function<
bool(
const typename MeshType::cell_iterator &)>
1704 const unsigned int level);
1719 template <
class MeshType>
1720 std::vector<typename MeshType::active_cell_iterator>
1771 template <
class MeshType>
1772 std::vector<typename MeshType::active_cell_iterator>
1774 const MeshType &mesh,
1775 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1777 const double layer_thickness);
1801 template <
class MeshType>
1802 std::vector<typename MeshType::active_cell_iterator>
1804 const double layer_thickness);
1821 template <
class MeshType>
1824 const MeshType &mesh,
1825 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1880 template <
class MeshType>
1881 std::vector<BoundingBox<MeshType::space_dimension>>
1883 const MeshType &mesh,
1884 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
1886 const unsigned int refinement_level = 0,
1887 const bool allow_merge =
false,
1917 template <
int spacedim>
1919 std::tuple<std::vector<std::vector<unsigned int>>,
1920 std::map<unsigned int, unsigned int>,
1921 std::map<unsigned int, std::vector<unsigned int>>>
1964 template <
int spacedim>
1966 std::tuple<std::map<unsigned int, std::vector<unsigned int>>,
1967 std::map<unsigned int, unsigned int>,
1968 std::map<unsigned int, std::vector<unsigned int>>>
1985 template <
int dim,
int spacedim>
1987 std::set<typename Triangulation<dim, spacedim>::active_cell_iterator>>
2002 template <
int dim,
int spacedim>
2003 std::vector<std::vector<Tensor<1, spacedim>>>
2018 template <
int dim,
int spacedim>
2024 (ReferenceCells::get_hypercube<dim>()
2025 .
template get_default_linear_mapping<dim, spacedim>()));
2038 template <
int dim,
int spacedim>
2039 std::map<unsigned int, types::global_vertex_index>
2054 template <
int dim,
int spacedim>
2055 std::pair<unsigned int, double>
2073 template <
int dim,
int spacedim>
2087 template <
int dim,
int spacedim>
2101 template <
int dim,
int spacedim>
2105 const unsigned int level,
2128 template <
int dim,
int spacedim>
2145 template <
int dim,
int spacedim>
2148 const std::vector<unsigned int> &cell_weights,
2198 template <
int dim,
int spacedim>
2216 template <
int dim,
int spacedim>
2219 const std::vector<unsigned int> &cell_weights,
2239 template <
int dim,
int spacedim>
2243 const bool group_siblings =
true);
2256 template <
int dim,
int spacedim>
2267 template <
int dim,
int spacedim>
2268 std::vector<types::subdomain_id>
2270 const std::vector<CellId> & cell_ids);
2282 template <
int dim,
int spacedim>
2285 std::vector<types::subdomain_id> & subdomain);
2301 template <
int dim,
int spacedim>
2336 template <
int dim,
int spacedim>
2379 template <
typename MeshType>
2380 std::list<std::pair<
typename MeshType::cell_iterator,
2381 typename MeshType::cell_iterator>>
2393 template <
int dim,
int spacedim>
2407 template <
typename MeshType>
2432 template <
int dim,
int spacedim>
2488 template <
class MeshType>
2489 std::vector<typename MeshType::active_cell_iterator>
2514 template <
class Container>
2515 std::vector<typename Container::cell_iterator>
2517 const std::vector<typename Container::active_cell_iterator> &patch_cells);
2585 template <
class Container>
2588 const std::vector<typename Container::active_cell_iterator> &patch,
2590 &local_triangulation,
2593 Container::space_dimension>::active_cell_iterator,
2594 typename Container::active_cell_iterator> &patch_to_global_tria_map);
2627 template <
int dim,
int spacedim>
2630 std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>>
2646 template <
typename CellIterator>
2746 template <
typename FaceIterator>
2748 std::bitset<3> & orientation,
2749 const FaceIterator & face1,
2750 const FaceIterator & face2,
2751 const int direction,
2760 template <
typename FaceIterator>
2763 const FaceIterator & face1,
2764 const FaceIterator & face2,
2765 const int direction,
2827 template <
typename MeshType>
2830 const MeshType & mesh,
2833 const int direction,
2863 template <
typename MeshType>
2866 const MeshType & mesh,
2868 const int direction,
2871 const ::Tensor<1, MeshType::space_dimension> &offset =
2901 template <
int dim,
int spacedim>
2904 const bool reset_boundary_ids =
false);
2927 template <
int dim,
int spacedim>
2930 const std::vector<types::boundary_id> &src_boundary_ids,
2931 const std::vector<types::manifold_id> &dst_manifold_ids,
2933 const std::vector<types::boundary_id> &reset_boundary_ids = {});
2964 template <
int dim,
int spacedim>
2967 const bool compute_face_ids =
false);
2993 template <
int dim,
int spacedim>
2998 const std::set<types::manifold_id> &)> &disambiguation_function =
2999 [](
const std::set<types::manifold_id> &manifold_ids) {
3000 if (manifold_ids.size() == 1)
3001 return *manifold_ids.
begin();
3005 bool overwrite_only_flat_manifold_ids =
true);
3092 template <
typename DataType,
typename MeshType>
3095 const MeshType & mesh,
3096 const std::function<std_cxx17::optional<DataType>(
3097 const typename MeshType::active_cell_iterator &)> &
pack,
3098 const std::function<
void(
const typename MeshType::active_cell_iterator &,
3099 const DataType &)> &
unpack,
3100 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
3114 template <
typename DataType,
typename MeshType>
3117 const MeshType & mesh,
3118 const std::function<std_cxx17::optional<DataType>(
3119 const typename MeshType::level_cell_iterator &)> &
pack,
3120 const std::function<
void(
const typename MeshType::level_cell_iterator &,
3121 const DataType &)> &
unpack,
3122 const std::function<
bool(
const typename MeshType::level_cell_iterator &)> &
3137 template <
int spacedim>
3138 std::vector<std::vector<BoundingBox<spacedim>>>
3141 const MPI_Comm & mpi_communicator);
3175 template <
int spacedim>
3179 const MPI_Comm & mpi_communicator);
3198 template <
int dim,
int spacedim>
3202 std::map<
unsigned int, std::vector<unsigned int>> &coinciding_vertex_groups,
3203 std::map<unsigned int, unsigned int> &vertex_to_coinciding_vertex_group);
3211 template <
int dim,
int spacedim>
3212 std::map<unsigned int, std::set<::types::subdomain_id>>
3228 template <
int dim,
typename T>
3249 template <
class Archive>
3251 save(Archive &ar,
const unsigned int version)
const;
3259 template <
class Archive>
3261 load(Archive &ar,
const unsigned int version);
3269 template <
class Archive>
3275 BOOST_SERIALIZATION_SPLIT_MEMBER()
3298 template <
int dim,
typename VectorType>
3321 const VectorType & ls_vector,
3322 const double iso_level,
3334 const VectorType & ls_vector,
3335 const double iso_level,
3353 const double iso_level,
3365 const std::vector<
Point<2>> & points,
3366 const std::vector<unsigned int> mask,
3367 const double iso_level,
3376 const std::vector<
Point<3>> & points,
3377 const std::vector<unsigned int> mask,
3378 const double iso_level,
3413 <<
"The number of partitions you gave is " << arg1
3414 <<
", but must be greater than zero.");
3420 <<
"The subdomain id " << arg1
3421 <<
" has no cells associated with it.");
3432 <<
"The scaling factor must be positive, but it is " << arg1
3440 <<
"The given vertex with index " << arg1
3441 <<
" is not used in the given triangulation.");
3458 "The edges of the mesh are not consistently orientable.");
3495 template <
int dim,
typename Predicate,
int spacedim>
3500 std::vector<bool> treated_vertices(
triangulation.n_vertices(),
false);
3511 for (; cell != endc; ++cell)
3512 for (
const unsigned int v : cell->vertex_indices())
3513 if (treated_vertices[cell->vertex_index(v)] ==
false)
3516 cell->vertex(v) = predicate(cell->vertex(v));
3518 treated_vertices[cell->vertex_index(v)] =
true;
3528 for (; cell != endc; ++cell)
3529 for (
const unsigned int face : cell->face_indices())
3530 if (cell->face(face)->has_children() &&
3531 !cell->face(face)->at_boundary())
3533 Assert(cell->reference_cell() ==
3534 ReferenceCells::get_hypercube<dim>(),
3538 cell->face(face)->child(0)->vertex(1) =
3539 (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) /
3548 for (; cell != endc; ++cell)
3549 for (
const unsigned int face : cell->face_indices())
3550 if (cell->face(face)->has_children() &&
3551 !cell->face(face)->at_boundary())
3553 Assert(cell->reference_cell() ==
3554 ReferenceCells::get_hypercube<dim>(),
3558 cell->face(face)->child(0)->vertex(1) =
3559 (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) /
3561 cell->face(face)->child(0)->vertex(2) =
3562 (cell->face(face)->vertex(0) + cell->face(face)->vertex(2)) /
3564 cell->face(face)->child(1)->vertex(3) =
3565 (cell->face(face)->vertex(1) + cell->face(face)->vertex(3)) /
3567 cell->face(face)->child(2)->vertex(3) =
3568 (cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) /
3572 cell->face(face)->child(0)->vertex(3) =
3573 (cell->face(face)->vertex(0) + cell->face(face)->vertex(1) +
3574 cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) /
3585 template <
class MeshType>
3586 std::vector<typename MeshType::active_cell_iterator>
3589 std::vector<typename MeshType::active_cell_iterator> child_cells;
3591 if (cell->has_children())
3593 for (
unsigned int child = 0; child < cell->n_children(); ++child)
3594 if (cell->child(child)->has_children())
3596 const std::vector<typename MeshType::active_cell_iterator>
3597 children = get_active_child_cells<MeshType>(cell->child(child));
3598 child_cells.insert(child_cells.end(),
3603 child_cells.push_back(cell->child(child));
3611 template <
class MeshType>
3614 const typename MeshType::active_cell_iterator & cell,
3615 std::vector<typename MeshType::active_cell_iterator> &active_neighbors)
3617 active_neighbors.clear();
3618 for (
const unsigned int n : cell->face_indices())
3619 if (!cell->at_boundary(n))
3621 if (MeshType::dimension == 1)
3628 typename MeshType::cell_iterator neighbor_child =
3630 if (!neighbor_child->is_active())
3632 while (neighbor_child->has_children())
3633 neighbor_child = neighbor_child->child(n == 0 ? 1 : 0);
3635 Assert(neighbor_child->neighbor(n == 0 ? 1 : 0) == cell,
3638 active_neighbors.push_back(neighbor_child);
3642 if (cell->face(n)->has_children())
3646 for (
unsigned int c = 0;
3647 c < cell->face(n)->n_active_descendants();
3649 active_neighbors.push_back(
3650 cell->neighbor_child_on_subface(n, c));
3656 active_neighbors.push_back(cell->neighbor(n));
3666 namespace ProjectToObject
3680 struct CrossDerivative
3682 const unsigned int direction_0;
3683 const unsigned int direction_1;
3685 CrossDerivative(
const unsigned int d0,
const unsigned int d1);
3688 inline CrossDerivative::CrossDerivative(
const unsigned int d0,
3689 const unsigned int d1)
3700 template <
typename F>
3702 centered_first_difference(
const double center,
3706 return (f(
center + step) - f(
center - step)) / (2.0 * step);
3715 template <
typename F>
3717 centered_second_difference(
const double center,
3736 template <
int structdim,
typename F>
3739 const CrossDerivative cross_derivative,
3745 simplex_vector[cross_derivative.direction_0] = 0.5 * step;
3746 simplex_vector[cross_derivative.direction_1] = -0.5 * step;
3747 return (-4.0 * f(
center) - 1.0 * f(
center + simplex_vector) -
3748 1.0 / 3.0 * f(
center - simplex_vector) +
3749 16.0 / 3.0 * f(
center + 0.5 * simplex_vector)) /
3761 template <
int spacedim,
int structdim,
typename F>
3764 const unsigned int row_n,
3765 const unsigned int dependent_direction,
3772 dependent_direction <
3774 ExcMessage(
"This function assumes that the last weight is a "
3775 "dependent variable (and hence we cannot take its "
3776 "derivative directly)."));
3777 Assert(row_n != dependent_direction,
3779 "We cannot differentiate with respect to the variable "
3780 "that is assumed to be dependent."));
3784 {row_n, dependent_direction},
center, step, f);
3786 for (
unsigned int dim_n = 0; dim_n < spacedim; ++dim_n)
3788 -2.0 * (p0[dim_n] - manifold_point[dim_n]) * stencil_value[dim_n];
3797 template <
typename Iterator,
int spacedim,
int structdim>
3799 project_to_d_linear_object(
const Iterator &
object,
3834 for (
unsigned int d = 0;
d < structdim; ++
d)
3839 x_k +=
object->vertex(i) *
3845 for (
const unsigned int i :
3848 (x_k - trial_point) * object->vertex(i) *
3853 for (
const unsigned int i :
3855 for (
const unsigned int j :
3863 H_k += (
object->vertex(i) *
object->vertex(j)) * tmp;
3870 for (
const unsigned int i :
3872 x_k +=
object->vertex(i) *
3875 if (delta_xi.
norm() < 1
e-7)
3891 template <
int structdim>
3898 static const std::size_t n_vertices_per_cell =
3900 n_independent_components;
3901 std::array<double, n_vertices_per_cell> copied_weights;
3902 for (
unsigned int i = 0; i < n_vertices_per_cell; ++i)
3904 copied_weights[i] = v[i];
3905 if (v[i] < 0.0 || v[i] > 1.0)
3910 std::sort(copied_weights.begin(), copied_weights.end());
3912 std::accumulate(copied_weights.begin(), copied_weights.end(), 0.0);
3917 template <
typename Iterator>
3920 const Iterator &
object,
3923 const int spacedim = Iterator::AccessorType::space_dimension;
3924 const int structdim = Iterator::AccessorType::structure_dimension;
3928 if (structdim >= spacedim)
3929 return projected_point;
3930 else if (structdim == 1 || structdim == 2)
3932 using namespace internal::ProjectToObject;
3937 const int dim = Iterator::AccessorType::dimension;
3940 &manifold) !=
nullptr)
3943 project_to_d_linear_object<Iterator, spacedim, structdim>(
3944 object, trial_point);
3989 const double step_size =
object->diameter() / 64.0;
3991 constexpr
unsigned int n_vertices_per_cell =
3994 std::array<Point<spacedim>, n_vertices_per_cell>
vertices;
3995 for (
unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
3997 vertices[vertex_n] = object->vertex(vertex_n);
3999 auto get_point_from_weights =
4002 return object->get_manifold().get_new_point(
4010 double guess_weights_sum = 0.0;
4011 for (
unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
4014 const double distance =
4016 if (distance == 0.0)
4018 guess_weights = 0.0;
4019 guess_weights[vertex_n] = 1.0;
4020 guess_weights_sum = 1.0;
4025 guess_weights[vertex_n] = 1.0 / distance;
4026 guess_weights_sum += guess_weights[vertex_n];
4029 guess_weights /= guess_weights_sum;
4030 Assert(internal::weights_are_ok<structdim>(guess_weights),
4039 for (
unsigned int outer_n = 0; outer_n < 40; ++outer_n)
4041 const unsigned int dependent_direction =
4042 n_vertices_per_cell - 1;
4044 for (
unsigned int row_n = 0; row_n < n_vertices_per_cell;
4047 if (row_n != dependent_direction)
4049 current_gradient[row_n] =
4050 gradient_entry<spacedim, structdim>(
4052 dependent_direction,
4056 get_point_from_weights);
4058 current_gradient[dependent_direction] -=
4059 current_gradient[row_n];
4077 double gradient_weight = -0.5;
4078 auto gradient_weight_objective_function =
4079 [&](
const double gradient_weight_guess) ->
double {
4080 return (trial_point -
4081 get_point_from_weights(guess_weights +
4082 gradient_weight_guess *
4087 for (
unsigned int inner_n = 0; inner_n < 10; ++inner_n)
4089 const double update_numerator = centered_first_difference(
4092 gradient_weight_objective_function);
4093 const double update_denominator =
4094 centered_second_difference(
4097 gradient_weight_objective_function);
4101 if (std::abs(update_denominator) == 0.0)
4104 gradient_weight - update_numerator / update_denominator;
4109 if (std::abs(gradient_weight) > 10)
4111 gradient_weight = -10.0;
4121 guess_weights + gradient_weight * current_gradient;
4123 double new_gradient_weight = gradient_weight;
4124 for (
unsigned int iteration_count = 0; iteration_count < 40;
4127 if (internal::weights_are_ok<structdim>(tentative_weights))
4130 for (
unsigned int i = 0; i < n_vertices_per_cell; ++i)
4132 if (tentative_weights[i] < 0.0)
4134 tentative_weights -=
4135 (tentative_weights[i] / current_gradient[i]) *
4138 if (tentative_weights[i] < 0.0 ||
4139 1.0 < tentative_weights[i])
4141 new_gradient_weight /= 2.0;
4144 new_gradient_weight * current_gradient;
4151 if (!internal::weights_are_ok<structdim>(tentative_weights))
4156 if (get_point_from_weights(tentative_weights)
4157 .distance(trial_point) <
4158 get_point_from_weights(guess_weights).distance(trial_point))
4159 guess_weights = tentative_weights;
4162 Assert(internal::weights_are_ok<structdim>(guess_weights),
4165 Assert(internal::weights_are_ok<structdim>(guess_weights),
4167 projected_point = get_point_from_weights(guess_weights);
4177 for (
unsigned int line_n = 0;
4178 line_n < GeometryInfo<structdim>::lines_per_cell;
4181 line_projections[line_n] =
4184 std::sort(line_projections.begin(),
4185 line_projections.end(),
4187 return a.distance(trial_point) <
4188 b.distance(trial_point);
4190 if (line_projections[0].distance(trial_point) <
4191 projected_point.
distance(trial_point))
4192 projected_point = line_projections[0];
4198 return projected_point;
4201 return projected_point;
4206 template <
int dim,
typename T>
4207 template <
class Archive>
4209 CellDataTransferBuffer<dim, T>::save(Archive &ar,
4210 const unsigned int )
const
4212 Assert(cell_ids.size() == data.size(),
4215 const std::size_t
n_cells = cell_ids.size();
4217 for (
const auto &
id : cell_ids)
4220 ar & binary_cell_id;
4228 template <
int dim,
typename T>
4229 template <
class Archive>
4231 CellDataTransferBuffer<dim, T>::load(Archive &ar,
4232 const unsigned int )
4238 for (
unsigned int c = 0; c <
n_cells; ++c)
4242 cell_ids.emplace_back(value);
4250 template <
typename DataType,
4252 typename MeshCellIteratorType>
4255 const MeshType &mesh,
4256 const std::function<
4257 std_cxx17::optional<DataType>(
const MeshCellIteratorType &)> &
pack,
4258 const std::function<
void(
const MeshCellIteratorType &,
const DataType &)>
4260 const std::function<
bool(
const MeshCellIteratorType &)> & cell_filter,
4261 const std::function<
void(
4262 const std::function<
void(
const MeshCellIteratorType &,
4264 const std::function<std::set<types::subdomain_id>(
4266 MeshType::space_dimension> &)>
4267 &compute_ghost_owners)
4269 # ifndef DEAL_II_WITH_MPI
4274 (void)process_cells;
4275 (void)compute_ghost_owners;
4278 constexpr
int dim = MeshType::dimension;
4279 constexpr
int spacedim = MeshType::space_dimension;
4282 &mesh.get_triangulation());
4286 "The function exchange_cell_data_to_ghosts() only works with parallel triangulations."));
4288 if (
const auto tria =
dynamic_cast<
4290 &mesh.get_triangulation()))
4293 tria->with_artificial_cells(),
4295 "The functions GridTools::exchange_cell_data_to_ghosts() and "
4296 "GridTools::exchange_cell_data_to_level_ghosts() can only "
4297 "operate on a single layer ghost cells. However, you have "
4298 "given a Triangulation object of type "
4299 "parallel::shared::Triangulation without artificial cells "
4300 "resulting in arbitrary numbers of ghost layers."));
4304 std::set<::types::subdomain_id> ghost_owners =
4305 compute_ghost_owners(*tria);
4307 std::vector<typename CellId::binary_type>>
4310 for (
const auto ghost_owner : ghost_owners)
4311 neighbor_cell_list[ghost_owner] = {};
4313 process_cells([&](
const auto &cell,
const auto key) {
4314 if (cell_filter(cell))
4315 neighbor_cell_list[key].emplace_back(
4316 cell->id().template to_binary<spacedim>());
4319 Assert(ghost_owners.size() == neighbor_cell_list.size(),
4331 const int mpi_tag_reply =
4335 std::vector<MPI_Request> requests(ghost_owners.size());
4337 unsigned int idx = 0;
4338 for (
const auto &it : neighbor_cell_list)
4341 const int ierr = MPI_Isend(it.second.data(),
4342 it.second.size() *
sizeof(it.second[0]),
4353 using DestinationToBufferMap =
4356 DestinationToBufferMap destination_to_data_buffer_map;
4359 std::vector<std::vector<typename CellId::binary_type>> cell_data_to_send(
4360 ghost_owners.size());
4361 std::vector<std::vector<types::global_dof_index>>
4362 send_dof_numbers_and_indices(ghost_owners.size());
4363 std::vector<MPI_Request> reply_requests(ghost_owners.size());
4364 std::vector<std::vector<char>> sendbuffers(ghost_owners.size());
4366 for (
unsigned int idx = 0; idx < ghost_owners.size(); ++idx)
4369 int ierr = MPI_Probe(MPI_ANY_SOURCE,
4376 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
4378 Assert(len %
sizeof(cell_data_to_send[idx][0]) == 0,
4383 cell_data_to_send[idx].resize(
n_cells);
4385 ierr = MPI_Recv(cell_data_to_send[idx].data(),
4395 for (
unsigned int c = 0; c < static_cast<unsigned int>(
n_cells); ++c)
4400 MeshCellIteratorType mesh_it(tria,
4404 const std_cxx17::optional<DataType> data =
pack(mesh_it);
4408 typename DestinationToBufferMap::iterator p =
4409 destination_to_data_buffer_map
4410 .insert(std::make_pair(
4415 p->second.cell_ids.emplace_back(cell->id());
4416 p->second.data.emplace_back(*data);
4422 destination_to_data_buffer_map[idx];
4426 ierr = MPI_Isend(sendbuffers[idx].data(),
4427 sendbuffers[idx].size(),
4432 &reply_requests[idx]);
4437 std::vector<char> receive;
4438 for (
unsigned int idx = 0; idx < ghost_owners.size(); ++idx)
4441 int ierr = MPI_Probe(MPI_ANY_SOURCE,
4448 ierr = MPI_Get_count(&status, MPI_BYTE, &len);
4451 receive.resize(len);
4453 char *ptr = receive.data();
4454 ierr = MPI_Recv(ptr,
4464 Utilities::unpack<CellDataTransferBuffer<dim, DataType>>(
4467 DataType *data = cellinfo.
data.data();
4468 for (
unsigned int c = 0; c < cellinfo.cell_ids.size(); ++c, ++data)
4473 MeshCellIteratorType cell(tria,
4484 if (requests.size() > 0)
4487 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
4490 if (reply_requests.size() > 0)
4492 const int ierr = MPI_Waitall(reply_requests.size(),
4493 reply_requests.data(),
4494 MPI_STATUSES_IGNORE);
4504 template <
typename DataType,
typename MeshType>
4507 const MeshType & mesh,
4508 const std::function<std_cxx17::optional<DataType>(
4509 const typename MeshType::active_cell_iterator &)> &
pack,
4510 const std::function<
void(
const typename MeshType::active_cell_iterator &,
4511 const DataType &)> &
unpack,
4512 const std::function<
bool(
const typename MeshType::active_cell_iterator &)>
4515 # ifndef DEAL_II_WITH_MPI
4522 internal::exchange_cell_data<DataType,
4524 typename MeshType::active_cell_iterator>(
4529 [&](
const auto &process) {
4530 for (
const auto &cell : mesh.active_cell_iterators())
4531 if (cell->is_ghost())
4532 process(cell, cell->subdomain_id());
4534 [](
const auto &tria) {
return tria.ghost_owners(); });
4540 template <
typename DataType,
typename MeshType>
4543 const MeshType & mesh,
4544 const std::function<std_cxx17::optional<DataType>(
4545 const typename MeshType::level_cell_iterator &)> &
pack,
4546 const std::function<
void(
const typename MeshType::level_cell_iterator &,
4547 const DataType &)> &
unpack,
4548 const std::function<
bool(
const typename MeshType::level_cell_iterator &)>
4551 # ifndef DEAL_II_WITH_MPI
4558 internal::exchange_cell_data<DataType,
4560 typename MeshType::level_cell_iterator>(
4565 [&](
const auto &process) {
4566 for (
const auto &cell : mesh.cell_iterators())
4567 if (cell->level_subdomain_id() !=
4569 !cell->is_locally_owned_on_level())
4570 process(cell, cell->level_subdomain_id());
4572 [](
const auto &tria) {
return tria.level_ghost_owners(); });
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
std::array< unsigned int, 4 > binary_type
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &t)
constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)
numbers::NumberTraits< Number >::real_type norm() const
virtual MPI_Comm get_communicator() const
cell_iterator create_cell_iterator(const CellId &cell_id) const
cell_iterator begin(const unsigned int level=0) const
typename MeshType::active_cell_iterator type
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_DEPRECATED_EARLY
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
__global__ void set(Number *val, const Number s, const size_type N)
#define DeclException0(Exception0)
static ::ExceptionBase & ExcMeshNotOrientable()
static ::ExceptionBase & ExcScalingFactorNotPositive(double arg1)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNeedsMPI()
static ::ExceptionBase & ExcVertexNotUsed(unsigned int arg1)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcTriangulationHasBeenRefined()
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotImplemented()
#define AssertThrowMPI(error_code)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcNonExistentSubdomain(int arg1)
typename ActiveSelector::active_cell_iterator active_cell_iterator
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)
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={})
std::map< unsigned int, std::set<::types::subdomain_id > > compute_vertices_with_ghost_neighbors(const Triangulation< dim, spacedim > &tria)
void exchange_cell_data_to_ghosts(const MeshType &mesh, const std::function< std_cxx17::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})
std::vector< std::vector< BoundingBox< spacedim > > > exchange_local_bounding_boxes(const std::vector< BoundingBox< spacedim >> &local_bboxes, const MPI_Comm &mpi_communicator)
void exchange_cell_data_to_level_ghosts(const MeshType &mesh, const std::function< std_cxx17::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})
RTree< std::pair< BoundingBox< spacedim >, unsigned int > > build_global_description_tree(const std::vector< BoundingBox< spacedim >> &local_description, const MPI_Comm &mpi_communicator)
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)
@ matrix
Contents is actually a matrix.
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
T sum(const T &t, const MPI_Comm &mpi_communicator)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
T unpack(const std::vector< char > &buffer, const bool allow_compression=true)
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
const types::subdomain_id artificial_subdomain_id
static const unsigned int invalid_unsigned_int
const types::manifold_id flat_manifold_id
unsigned int global_dof_index
unsigned int subdomain_id
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
boost::geometry::index::rtree< LeafType, IndexType, IndexableGetter > RTree
static double d_linear_shape_function(const Point< dim > &xi, const unsigned int i)
static Tensor< 1, dim > d_linear_shape_function_gradient(const Point< dim > &xi, const unsigned int i)