28#include <boost/container/small_vector.hpp>
37template <
int dim,
int spacedim>
49template <
int dim,
int spacedim>
57 w *
p2 + (1 - w) *
p1);
62template <
int dim,
int spacedim>
68 const double tol = 1
e-10;
75 "There should be as many surrounding points as weights given."));
79 ExcMessage(
"The weights for the individual points should sum to 1!"));
84 boost::container::small_vector<unsigned int, 100> permutation(n_points);
85 std::iota(permutation.begin(), permutation.end(), 0
u);
86 std::sort(permutation.begin(),
88 [&weights](
const std::size_t a,
const std::size_t b) {
89 return weights[a] < weights[b];
94 double w = weights[permutation[0]];
96 for (
unsigned int i = 1; i < n_points; ++i)
99 if (
std::abs(weights[permutation[i]] + w) < tol)
102 weight =
w / (weights[permutation[i]] +
w);
106 p = get_intermediate_point(p,
114 w += weights[permutation[i]];
122template <
int dim,
int spacedim>
131 for (
unsigned int row = 0; row < weights.
size(0); ++row)
147 const int spacedim = 2;
152 ((p - face->vertex(0)).norm_square() > (p - face->vertex(1)).norm_square() ?
153 -get_tangent_vector(p, face->vertex(0)) :
154 get_tangent_vector(p, face->vertex(1)));
158 return normal / normal.norm();
168 const int spacedim = 3;
170 const std::array<Point<spacedim>, 4>
vertices{
171 {face->vertex(0), face->vertex(1), face->vertex(2), face->vertex(3)}};
188 for (
unsigned int i = 0; i < 3; ++i)
190 for (
unsigned int j = i + 1;
j < 4; ++
j)
205 ExcMessage(
"The search for possible directions did not succeed."));
225 if (normal.norm_square() < 1
e4 * std::numeric_limits<double>::epsilon() *
226 t1.norm_square() *
t2.norm_square())
249 normal.norm_square() > 1
e4 * std::numeric_limits<double>::epsilon() *
250 t1.norm_square() *
t2.norm_square(),
252 "Manifold::normal_vector was unable to find a suitable combination "
253 "of vertices to compute a normal on this face. We chose the secants "
254 "that are as orthogonal as possible, but tangents appear to be "
255 "linearly dependent. Check for distorted faces in your triangulation."));
267 return normal / normal.norm();
272template <
int dim,
int spacedim>
290 n[0] =
cross_product_2d(get_tangent_vector(face->vertex(0), face->vertex(1)));
294 for (
unsigned int i = 0; i < 2; ++i)
298 "computed normals have "
312 n[0] =
cross_product_3d(get_tangent_vector(face->vertex(0), face->vertex(1)),
313 get_tangent_vector(face->vertex(0), face->vertex(2)));
315 n[1] =
cross_product_3d(get_tangent_vector(face->vertex(1), face->vertex(3)),
316 get_tangent_vector(face->vertex(1), face->vertex(0)));
318 n[2] =
cross_product_3d(get_tangent_vector(face->vertex(2), face->vertex(0)),
319 get_tangent_vector(face->vertex(2), face->vertex(3)));
321 n[3] =
cross_product_3d(get_tangent_vector(face->vertex(3), face->vertex(2)),
322 get_tangent_vector(face->vertex(3), face->vertex(1)));
324 for (
unsigned int i = 0; i < 4; ++i)
328 "computed normals have "
336template <
int dim,
int spacedim>
340 FaceVertexNormals & n)
const
342 for (
unsigned int v = 0; v < face->reference_cell().n_vertices(); ++v)
344 n[v] = normal_vector(face, face->vertex(v));
351template <
int dim,
int spacedim>
365template <
int dim,
int spacedim>
379template <
int dim,
int spacedim>
389 return get_new_point_on_line(face);
391 return get_new_point_on_quad(face);
399template <
int dim,
int spacedim>
407 return get_new_point_on_line(cell);
409 return get_new_point_on_quad(cell);
411 return get_new_point_on_hex(cell);
485template <
int dim,
int spacedim>
511template <
int dim,
int spacedim>
516 const double epsilon = 1e-8;
518 const std::array<Point<spacedim>, 2> points{{
x1,
x2}};
548 return tmp / tmp.norm();
554template <
int dim,
int spacedim>
557 const double tolerance)
558 : periodicity(periodicity)
559 , tolerance(tolerance)
564template <
int dim,
int spacedim>
565std::unique_ptr<Manifold<dim, spacedim>>
568 return std::make_unique<FlatManifold<dim, spacedim>>(periodicity, tolerance);
573template <
int dim,
int spacedim>
581 ExcMessage(
"The weights for the new point should sum to 1!"));
595 for (
unsigned int d = 0;
d < spacedim; ++
d)
596 if (periodicity[d] > 0)
601 periodicity[d] + tolerance * periodicity[d]) ||
603 -tolerance * periodicity[d]),
612 for (
unsigned int d = 0;
d < spacedim; ++
d)
613 if (periodicity[d] > 0)
623 for (
unsigned int d = 0;
d < spacedim; ++
d)
624 if (periodicity[d] > 0)
626 p[
d] += periodicity[
d];
634template <
int dim,
int spacedim>
642 if (weights.
size(0) == 0)
653 for (
unsigned int row = 0; row < weights.
size(0); ++row)
655 &weights(row, 0) + n_points,
658 ExcMessage(
"The weights for each of the points should sum to "
661 constexpr std::size_t n_lanes =
664 const std::size_t
n_regular_cols = (n_points / n_lanes) * n_lanes;
665 for (
unsigned int row = 0; row < weights.
size(0); row += n_lanes)
667 std::array<unsigned int, n_lanes>
offsets;
670 for (std::size_t i = 0; i < n_lanes; ++i)
672 std::min<unsigned int>((row + i) * n_points,
673 (weights.
size(0) - 1) * n_points);
679 &weights(0, 0) + col,
682 for (std::size_t i = 0; i < n_lanes; ++i)
691 for (
unsigned int r = row;
696 for (
unsigned int d = 0;
d < spacedim; ++
d)
704 for (
unsigned int row = 0; row < weights.
size(0); ++row)
712template <
int dim,
int spacedim>
723template <
int dim,
int spacedim>
732template <
int dim,
int spacedim>
743 for (
unsigned int d = 0;
d < spacedim; ++
d)
744 if (periodicity[d] > tolerance)
746 if (direction[d] < -periodicity[d] / 2)
747 direction[
d] += periodicity[
d];
748 else if (direction[d] > periodicity[d] / 2)
749 direction[
d] -= periodicity[
d];
828 for (
unsigned int vertex = 0; vertex < vertices_per_face; ++vertex)
890template <
int dim,
int spacedim>
926 const unsigned int facedim = dim - 1;
930 const auto face_reference_cell = face->reference_cell();
932 if (face_reference_cell == ReferenceCells::get_hypercube<facedim>())
934 for (
unsigned int i = 0; i <
facedim; ++i)
939 for (
unsigned int i = 0; i <
facedim; ++i)
943 const double eps = 1e-12;
949 for (
const unsigned int v : face->vertex_indices())
951 face->vertex(v) * face_reference_cell.d_linear_shape_function(
xi, v);
953 for (
unsigned int i = 0; i <
facedim; ++i)
956 for (
const unsigned int v : face->vertex_indices())
959 face_reference_cell.d_linear_shape_function_gradient(
xi, v)[i];
963 for (
unsigned int i = 0; i <
facedim; ++i)
964 for (
unsigned int j = 0;
j < spacedim; ++
j)
968 for (
unsigned int i = 0; i <
facedim; ++i)
970 for (
unsigned int k = 0;
k < spacedim; ++
k)
979 "The Newton iteration to find the reference point "
980 "did not converge in 10 iterations. Do you have a "
981 "deformed cell? (See the glossary for a definition "
982 "of what a deformed cell is. You may want to output "
983 "the vertices of your cell."));
1002 return internal::normalized_alternating_product(
grad_F);
1007template <
int dim,
int spacedim,
int chartdim>
1010 : sub_manifold(periodicity)
1015template <
int dim,
int spacedim,
int chartdim>
1020 const double w)
const
1022 const std::array<Point<spacedim>, 2> points{{
p1,
p2}};
1023 const std::array<double, 2> weights{{1. - w, w}};
1030template <
int dim,
int spacedim,
int chartdim>
1038 boost::container::small_vector<Point<chartdim>, 200>
chart_points(n_points);
1040 for (
unsigned int i = 0; i < n_points; ++i)
1051template <
int dim,
int spacedim,
int chartdim>
1063 boost::container::small_vector<Point<chartdim>, 200>
chart_points(n_points);
1064 for (std::size_t i = 0; i < n_points; ++i)
1069 sub_manifold.get_new_points(
1074 for (std::size_t row = 0; row < weights.
size(0); ++row)
1080template <
int dim,
int spacedim,
int chartdim>
1093template <
int dim,
int spacedim,
int chartdim>
1100 push_forward_gradient(pull_back(
x1));
1111 "The derivative of a chart function must not be singular."));
1114 sub_manifold.get_tangent_vector(pull_back(
x1), pull_back(
x2));
1117 for (
unsigned int i = 0; i < spacedim; ++i)
1125template <
int dim,
int spacedim,
int chartdim>
1129 return sub_manifold.get_periodicity();
1133#include "manifold.inst"
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
value_type * data() const noexcept
ChartManifold(const Tensor< 1, chartdim > &periodicity=Tensor< 1, chartdim >())
virtual void get_new_points(const ArrayView< const Point< spacedim > > &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim > > new_points) const override
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const override
virtual DerivativeForm< 1, chartdim, spacedim > push_forward_gradient(const Point< chartdim > &chart_point) const
const Tensor< 1, chartdim > & get_periodicity() const
virtual Point< spacedim > get_intermediate_point(const Point< spacedim > &p1, const Point< spacedim > &p2, const double w) const override
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim > > &surrounding_points, const ArrayView< const double > &weights) const override
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const override
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, typename Manifold< dim, spacedim >::FaceVertexNormals &face_vertex_normals) const override
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const override
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim > > &points, const Point< spacedim > &candidate) const override
const Tensor< 1, spacedim > & get_periodicity() const
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim > > &surrounding_points, const ArrayView< const double > &weights) const override
FlatManifold(const Tensor< 1, spacedim > &periodicity=Tensor< 1, spacedim >(), const double tolerance=1e-10)
virtual void get_new_points(const ArrayView< const Point< spacedim > > &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim > > new_points) const override
virtual Point< spacedim > get_new_point_on_hex(const typename Triangulation< dim, spacedim >::hex_iterator &hex) const
virtual Point< spacedim > get_new_point_on_line(const typename Triangulation< dim, spacedim >::line_iterator &line) const
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim > > &surrounding_points, const Point< spacedim > &candidate) const
virtual void get_new_points(const ArrayView< const Point< spacedim > > &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim > > new_points) const
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, FaceVertexNormals &face_vertex_normals) const
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const
std::array< Tensor< 1, spacedim >, GeometryInfo< dim >::vertices_per_face > FaceVertexNormals
virtual Point< spacedim > get_intermediate_point(const Point< spacedim > &p1, const Point< spacedim > &p2, const double w) const
Point< spacedim > get_new_point_on_face(const typename Triangulation< dim, spacedim >::face_iterator &face) const
virtual Point< spacedim > get_new_point_on_quad(const typename Triangulation< dim, spacedim >::quad_iterator &quad) const
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const
Point< spacedim > get_new_point_on_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim > > &surrounding_points, const ArrayView< const double > &weights) const
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcEmptyObject()
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcPureFunctionCalled()
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename IteratorSelector::hex_iterator hex_iterator
typename IteratorSelector::quad_iterator quad_iterator
typename IteratorSelector::line_iterator line_iterator
std::pair< std::array< Point< MeshIteratorType::AccessorType::space_dimension >, n_default_points_per_cell< MeshIteratorType >()>, std::array< double, n_default_points_per_cell< MeshIteratorType >()> > get_default_points_and_weights(const MeshIteratorType &iterator, const bool with_interpolation=false)
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
Tensor< 2, dim, Number > w(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
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)
SymmetricTensor< 2, dim, Number > epsilon(const Tensor< 2, dim, Number > &Grad_u)
constexpr const ReferenceCell Line
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)
void vectorized_load_and_transpose(const unsigned int n_entries, const Number *in, const unsigned int *offsets, VectorizedArray< Number, width > *out)