15#ifndef dealii_grid_tools_geometry_h
16#define dealii_grid_tools_geometry_h
51 template <
int dim,
int spacedim>
78 template <
int dim,
int spacedim>
109 template <
int dim,
int spacedim>
124 template <
int dim,
int spacedim>
129 (ReferenceCells::get_hypercube<dim>()
131 .
template get_default_linear_mapping<dim, spacedim>()
133 .ReferenceCell::get_default_linear_mapping<dim, spacedim>()
147 template <
int dim,
int spacedim>
152 (ReferenceCells::get_hypercube<dim>()
154 .
template get_default_linear_mapping<dim, spacedim>()
156 .ReferenceCell::get_default_linear_mapping<dim, spacedim>()
195 template <
int dim,
int spacedim>
196 std::pair<unsigned int, double>
222 template <
int dim,
int spacedim>
287 template <
int dim,
int spacedim>
308 template <
typename MeshType>
314 const std::function<
bool(
315 const typename MeshType::
316 active_cell_iterator &)>
336 template <
typename Iterator>
339 const Iterator &
object,
349 namespace ProjectToObject
363 struct CrossDerivative
365 const unsigned int direction_0;
366 const unsigned int direction_1;
368 CrossDerivative(
const unsigned int d0,
const unsigned int d1);
371 inline CrossDerivative::CrossDerivative(
const unsigned int d0,
372 const unsigned int d1)
383 template <
typename F>
385 centered_first_difference(
const double center,
387 const F &f) ->
decltype(f(center) - f(center))
389 return (f(center + step) - f(center - step)) / (2.0 * step);
398 template <
typename F>
400 centered_second_difference(
const double center,
402 const F &f) ->
decltype(f(center) - f(center))
404 return (f(center + step) - 2.0 * f(center) + f(center - step)) /
419 template <
int structdim,
typename F>
422 const CrossDerivative cross_derivative,
425 const F &f) ->
decltype(f(center) - f(center))
428 simplex_vector[cross_derivative.direction_0] = 0.5 * step;
429 simplex_vector[cross_derivative.direction_1] = -0.5 * step;
430 return (-4.0 * f(center) - 1.0 * f(center + simplex_vector) -
431 1.0 / 3.0 * f(center - simplex_vector) +
432 16.0 / 3.0 * f(center + 0.5 * simplex_vector)) /
444 template <
int spacedim,
int structdim,
typename F>
447 const unsigned int row_n,
448 const unsigned int dependent_direction,
455 dependent_direction <
457 ExcMessage(
"This function assumes that the last weight is a "
458 "dependent variable (and hence we cannot take its "
459 "derivative directly)."));
460 Assert(row_n != dependent_direction,
462 "We cannot differentiate with respect to the variable "
463 "that is assumed to be dependent."));
467 {row_n, dependent_direction}, center, step, f);
469 for (
unsigned int dim_n = 0; dim_n < spacedim; ++dim_n)
471 -2.0 * (p0[dim_n] - manifold_point[dim_n]) * stencil_value[dim_n];
480 template <
typename Iterator,
int spacedim,
int structdim>
482 project_to_d_linear_object(
const Iterator &
object,
518 for (
unsigned int d = 0;
d < structdim; ++
d)
523 x_k += object->vertex(i) *
524 GeometryInfo<structdim>::d_linear_shape_function(xi, i);
529 for (
const unsigned int i :
532 (x_k - trial_point) * object->vertex(i) *
533 GeometryInfo<structdim>::d_linear_shape_function_gradient(xi,
537 for (
const unsigned int i :
539 for (const unsigned
int j :
547 H_k += (
object->vertex(i) *
object->vertex(j)) * tmp;
554 for (
const unsigned int i :
556 x_k += object->vertex(i) *
557 GeometryInfo<structdim>::d_linear_shape_function(xi, i);
559 if (delta_xi.
norm() < 1e-7)
570 template <
int structdim>
577 static const std::size_t n_vertices_per_cell =
579 n_independent_components;
580 std::array<double, n_vertices_per_cell> copied_weights;
581 for (
unsigned int i = 0; i < n_vertices_per_cell; ++i)
583 copied_weights[i] = v[i];
584 if (v[i] < 0.0 || v[i] > 1.0)
589 std::sort(copied_weights.begin(), copied_weights.end());
591 std::accumulate(copied_weights.begin(), copied_weights.end(), 0.0);
598 template <
typename Iterator>
601 const Iterator &
object,
604 const int spacedim = Iterator::AccessorType::space_dimension;
605 const int structdim = Iterator::AccessorType::structure_dimension;
609 if (structdim >= spacedim)
610 return projected_point;
611 else if (structdim == 1 || structdim == 2)
613 using namespace internal::ProjectToObject;
618 const int dim = Iterator::AccessorType::dimension;
621 &manifold) !=
nullptr)
624 project_to_d_linear_object<Iterator, spacedim, structdim>(
625 object, trial_point);
670 const double step_size =
object->diameter() / 64.0;
672 constexpr unsigned int n_vertices_per_cell =
675 std::array<Point<spacedim>, n_vertices_per_cell> vertices;
676 for (
unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
678 vertices[vertex_n] = object->vertex(vertex_n);
680 auto get_point_from_weights =
683 return object->get_manifold().get_new_point(
691 double guess_weights_sum = 0.0;
692 for (
unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
695 const double distance =
696 vertices[vertex_n].distance(trial_point);
700 guess_weights[vertex_n] = 1.0;
701 guess_weights_sum = 1.0;
706 guess_weights[vertex_n] = 1.0 / distance;
707 guess_weights_sum += guess_weights[vertex_n];
710 guess_weights /= guess_weights_sum;
711 Assert(internal::weights_are_ok<structdim>(guess_weights),
720 for (
unsigned int outer_n = 0; outer_n < 40; ++outer_n)
722 const unsigned int dependent_direction =
723 n_vertices_per_cell - 1;
725 for (
unsigned int row_n = 0; row_n < n_vertices_per_cell;
728 if (row_n != dependent_direction)
730 current_gradient[row_n] =
731 gradient_entry<spacedim, structdim>(
737 get_point_from_weights);
739 current_gradient[dependent_direction] -=
740 current_gradient[row_n];
758 double gradient_weight = -0.5;
759 auto gradient_weight_objective_function =
760 [&](
const double gradient_weight_guess) ->
double {
761 return (trial_point -
762 get_point_from_weights(guess_weights +
763 gradient_weight_guess *
768 for (
unsigned int inner_n = 0; inner_n < 10; ++inner_n)
770 const double update_numerator = centered_first_difference(
773 gradient_weight_objective_function);
774 const double update_denominator =
775 centered_second_difference(
778 gradient_weight_objective_function);
782 if (
std::abs(update_denominator) == 0.0)
785 gradient_weight - update_numerator / update_denominator;
792 gradient_weight = -10.0;
802 guess_weights + gradient_weight * current_gradient;
804 double new_gradient_weight = gradient_weight;
805 for (
unsigned int iteration_count = 0; iteration_count < 40;
808 if (internal::weights_are_ok<structdim>(tentative_weights))
811 for (
unsigned int i = 0; i < n_vertices_per_cell; ++i)
813 if (tentative_weights[i] < 0.0)
816 (tentative_weights[i] / current_gradient[i]) *
819 if (tentative_weights[i] < 0.0 ||
820 1.0 < tentative_weights[i])
822 new_gradient_weight /= 2.0;
825 new_gradient_weight * current_gradient;
832 if (!internal::weights_are_ok<structdim>(tentative_weights))
837 if (get_point_from_weights(tentative_weights)
838 .distance(trial_point) <
839 get_point_from_weights(guess_weights).distance(trial_point))
840 guess_weights = tentative_weights;
843 Assert(internal::weights_are_ok<structdim>(guess_weights),
846 Assert(internal::weights_are_ok<structdim>(guess_weights),
848 projected_point = get_point_from_weights(guess_weights);
858 for (
unsigned int line_n = 0;
859 line_n < GeometryInfo<structdim>::lines_per_cell;
862 line_projections[line_n] =
865 std::sort(line_projections.begin(),
866 line_projections.end(),
868 return a.distance(trial_point) <
869 b.distance(trial_point);
871 if (line_projections[0].distance(trial_point) <
872 projected_point.
distance(trial_point))
873 projected_point = line_projections[0];
879 return projected_point;
882 return projected_point;
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
Abstract base class for mapping classes.
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
numbers::NumberTraits< Number >::real_type norm() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DEAL_II_NOT_IMPLEMENTED()
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
T sum(const T &t, const MPI_Comm mpi_communicator)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
DEAL_II_HOST constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)