13#ifndef dealii_grid_tools_geometry_h
14#define dealii_grid_tools_geometry_h
50 template <
int dim,
int spacedim>
77 template <
int dim,
int spacedim>
108 template <
int dim,
int spacedim>
123 template <
int dim,
int spacedim>
127 (ReferenceCells::get_hypercube<dim>()
129 .
template get_default_linear_mapping<spacedim>()
146 template <
int dim,
int spacedim>
150 (ReferenceCells::get_hypercube<dim>()
152 .
template get_default_linear_mapping<spacedim>()
194 template <
int dim,
int spacedim>
195 std::pair<unsigned int, double>
221 template <
int dim,
int spacedim>
286 template <
int dim,
int spacedim>
307 template <
typename MeshType>
313 const std::function<
bool(
314 const typename MeshType::
315 active_cell_iterator &)>
335 template <
typename Iterator>
338 const Iterator &
object,
348 namespace ProjectToObject
362 struct CrossDerivative
364 const unsigned int direction_0;
365 const unsigned int direction_1;
367 CrossDerivative(
const unsigned int d0,
const unsigned int d1);
370 inline CrossDerivative::CrossDerivative(
const unsigned int d0,
371 const unsigned int d1)
382 template <
typename F>
384 centered_first_difference(
const double center,
386 const F &f) ->
decltype(f(center) - f(center))
388 return (f(center + step) - f(center - step)) / (2.0 * step);
397 template <
typename F>
399 centered_second_difference(
const double center,
401 const F &f) ->
decltype(f(center) - f(center))
403 return (f(center + step) - 2.0 * f(center) + f(center - step)) /
418 template <
int structdim,
typename F>
421 const CrossDerivative cross_derivative,
424 const F &f) ->
decltype(f(center) - f(center))
427 simplex_vector[cross_derivative.direction_0] = 0.5 * step;
428 simplex_vector[cross_derivative.direction_1] = -0.5 * step;
429 return (-4.0 * f(center) - 1.0 * f(center + simplex_vector) -
430 1.0 / 3.0 * f(center - simplex_vector) +
431 16.0 / 3.0 * f(center + 0.5 * simplex_vector)) /
443 template <
int spacedim,
int structdim,
typename F>
446 const unsigned int row_n,
447 const unsigned int dependent_direction,
454 dependent_direction <
456 ExcMessage(
"This function assumes that the last weight is a "
457 "dependent variable (and hence we cannot take its "
458 "derivative directly)."));
459 Assert(row_n != dependent_direction,
461 "We cannot differentiate with respect to the variable "
462 "that is assumed to be dependent."));
466 {row_n, dependent_direction}, center, step, f);
468 for (
unsigned int dim_n = 0; dim_n < spacedim; ++dim_n)
470 -2.0 * (p0[dim_n] - manifold_point[dim_n]) * stencil_value[dim_n];
479 template <
typename Iterator,
int spacedim,
int structdim>
481 project_to_d_linear_object(
const Iterator &
object,
517 for (
unsigned int d = 0;
d < structdim; ++
d)
522 x_k += object->vertex(i) *
523 GeometryInfo<structdim>::d_linear_shape_function(xi, i);
528 for (
const unsigned int i :
531 (x_k - trial_point) * object->vertex(i) *
532 GeometryInfo<structdim>::d_linear_shape_function_gradient(xi,
536 for (
const unsigned int i :
546 H_k += (
object->vertex(i) *
object->vertex(j)) * tmp;
553 for (
const unsigned int i :
555 x_k += object->vertex(i) *
556 GeometryInfo<structdim>::d_linear_shape_function(xi, i);
558 if (delta_xi.
norm() < 1e-7)
569 template <
int structdim>
576 static const std::size_t n_vertices_per_cell =
578 n_independent_components;
579 std::array<double, n_vertices_per_cell> copied_weights;
580 for (
unsigned int i = 0; i < n_vertices_per_cell; ++i)
582 copied_weights[i] = v[i];
583 if (v[i] < 0.0 || v[i] > 1.0)
588 std::sort(copied_weights.begin(), copied_weights.end());
590 std::accumulate(copied_weights.begin(), copied_weights.end(), 0.0);
597 template <
typename Iterator>
600 const Iterator &
object,
603 const int spacedim = Iterator::AccessorType::space_dimension;
604 const int structdim = Iterator::AccessorType::structure_dimension;
608 if (structdim >= spacedim)
609 return projected_point;
610 else if (structdim == 1 || structdim == 2)
612 using namespace internal::ProjectToObject;
617 const int dim = Iterator::AccessorType::dimension;
620 &manifold) !=
nullptr)
623 project_to_d_linear_object<Iterator, spacedim, structdim>(
624 object, trial_point);
669 const double step_size =
object->diameter() / 64.0;
671 constexpr unsigned int n_vertices_per_cell =
674 std::array<Point<spacedim>, n_vertices_per_cell> vertices;
675 for (
unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
677 vertices[vertex_n] = object->vertex(vertex_n);
679 auto get_point_from_weights =
682 return object->get_manifold().get_new_point(
690 double guess_weights_sum = 0.0;
691 for (
unsigned int vertex_n = 0; vertex_n < n_vertices_per_cell;
694 const double distance =
695 vertices[vertex_n].distance(trial_point);
699 guess_weights[vertex_n] = 1.0;
700 guess_weights_sum = 1.0;
705 guess_weights[vertex_n] = 1.0 / distance;
706 guess_weights_sum += guess_weights[vertex_n];
709 guess_weights /= guess_weights_sum;
710 Assert(internal::weights_are_ok<structdim>(guess_weights),
719 for (
unsigned int outer_n = 0; outer_n < 40; ++outer_n)
721 const unsigned int dependent_direction =
722 n_vertices_per_cell - 1;
724 for (
unsigned int row_n = 0; row_n < n_vertices_per_cell;
727 if (row_n != dependent_direction)
729 current_gradient[row_n] =
730 gradient_entry<spacedim, structdim>(
736 get_point_from_weights);
738 current_gradient[dependent_direction] -=
739 current_gradient[row_n];
757 double gradient_weight = -0.5;
758 auto gradient_weight_objective_function =
759 [&](
const double gradient_weight_guess) ->
double {
760 return (trial_point -
761 get_point_from_weights(guess_weights +
762 gradient_weight_guess *
767 for (
unsigned int inner_n = 0; inner_n < 10; ++inner_n)
769 const double update_numerator = centered_first_difference(
772 gradient_weight_objective_function);
773 const double update_denominator =
774 centered_second_difference(
777 gradient_weight_objective_function);
781 if (
std::abs(update_denominator) == 0.0)
784 gradient_weight - update_numerator / update_denominator;
791 gradient_weight = -10.0;
801 guess_weights + gradient_weight * current_gradient;
803 double new_gradient_weight = gradient_weight;
804 for (
unsigned int iteration_count = 0; iteration_count < 40;
807 if (internal::weights_are_ok<structdim>(tentative_weights))
810 for (
unsigned int i = 0; i < n_vertices_per_cell; ++i)
812 if (tentative_weights[i] < 0.0)
815 (tentative_weights[i] / current_gradient[i]) *
818 if (tentative_weights[i] < 0.0 ||
819 1.0 < tentative_weights[i])
821 new_gradient_weight /= 2.0;
824 new_gradient_weight * current_gradient;
831 if (!internal::weights_are_ok<structdim>(tentative_weights))
836 if (get_point_from_weights(tentative_weights)
837 .distance(trial_point) <
838 get_point_from_weights(guess_weights).distance(trial_point))
839 guess_weights = tentative_weights;
842 Assert(internal::weights_are_ok<structdim>(guess_weights),
845 Assert(internal::weights_are_ok<structdim>(guess_weights),
847 projected_point = get_point_from_weights(guess_weights);
857 for (
unsigned int line_n = 0;
858 line_n < GeometryInfo<structdim>::lines_per_cell;
861 line_projections[line_n] =
864 std::sort(line_projections.begin(),
865 line_projections.end(),
867 return a.distance(trial_point) <
868 b.distance(trial_point);
870 if (line_projections[0].distance(trial_point) <
871 projected_point.
distance(trial_point))
872 projected_point = line_projections[0];
878 return projected_point;
881 return projected_point;
* * for(const auto &cell :triangulation.active_cell_iterators())
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 DEAL_II_NOT_IMPLEMENTED()
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
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)
* * * * std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters const
T sum(const T &t, const MPI_Comm mpi_communicator)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
constexpr SymmetricTensor< 4, dim, Number > outer_product(const SymmetricTensor< 2, dim, Number > &t1, const SymmetricTensor< 2, dim, Number > &t2)