22#include <boost/container/small_vector.hpp>
36 reflect(
const std::vector<
Point<2>> &points)
38 std::vector<Point<2>> q_points;
39 q_points.reserve(points.size());
41 q_points.emplace_back(p[1], p[0]);
50 rotate(
const std::vector<
Point<2>> &points,
const unsigned int n_times)
52 std::vector<Point<2>> q_points;
53 q_points.reserve(points.size());
59 q_points.push_back(p);
64 q_points.emplace_back(1.0 - p[1], p[0]);
69 q_points.emplace_back(1.0 - p[0], 1.0 - p[1]);
74 q_points.emplace_back(p[1], 1.0 - p[0]);
88 project_to_hex_face_and_append(
90 const unsigned int face_no,
93 const unsigned int subface_no = 0)
97 const double const_value = face_no % 2;
102 const unsigned int xi_index = (1 + face_no / 2) % 3,
103 eta_index = (2 + face_no / 2) % 3,
104 const_index = face_no / 2;
111 double xi_scale = 1.0, eta_scale = 1.0, xi_translation = 0.0,
112 eta_translation = 0.0;
121 xi_translation = subface_no % 2 * 0.5;
125 eta_translation = subface_no % 2 * 0.5;
130 xi_translation =
int(subface_no % 2) * 0.5;
131 eta_translation =
int(subface_no / 2) * 0.5;
143 cell_point[xi_index] = xi_scale * p[0] + xi_translation;
144 cell_point[eta_index] = eta_scale * p[1] + eta_translation;
145 cell_point[const_index] = const_value;
146 q_points.push_back(cell_point);
150 std::vector<Point<2>>
151 mutate_points_with_offset(
152 const std::vector<
Point<2>> &points,
165 switch (combined_orientation)
168 return reflect(points);
170 return rotate(reflect(points), 3);
172 return rotate(reflect(points), 2);
174 return rotate(reflect(points), 1);
178 return rotate(points, 1);
180 return rotate(points, 2);
182 return rotate(points, 3);
219 append_subobject_rule(
223 const double measure,
226 std::vector<double> &weights)
228 const auto support_points =
232 combined_orientation));
234 for (
unsigned int j = 0; j < quadrature.
size(); ++j)
239 for (
const unsigned int vertex_no :
242 support_points[vertex_no] *
246 points.push_back(mapped_point);
250 weights.push_back(quadrature.
weight(j) * measure /
251 face_reference_cell.
volume());
264 const unsigned int face_no,
268 const auto face_quadrature =
273 q_points = face_quadrature.get_points();
282 const unsigned int face_no,
286 const auto face_quadrature =
291 q_points = face_quadrature.get_points();
300 const unsigned int face_no,
304 (void)reference_cell;
310 internal::QProjector::project_to_hex_face_and_append(quadrature.
get_points(),
321 const unsigned int face_no,
322 const bool face_orientation,
323 const bool face_flip,
324 const bool face_rotation)
342 const unsigned int face_no,
347 reference_cell.n_face_orientations(face_no));
350 std::vector<Point<dim>> points;
351 std::vector<double> weights;
354 reference_cell.face_reference_cell(face_no);
355 std::vector<Point<dim>> face_vertices(face_reference_cell.
n_vertices());
356 for (
const unsigned int vertex_no : face_reference_cell.
vertex_indices())
357 face_vertices[vertex_no] =
358 reference_cell.face_vertex_location<dim>(face_no, vertex_no);
359 internal::QProjector::append_subobject_rule(face_reference_cell,
362 reference_cell.face_measure(
364 combined_orientation,
377 const unsigned int face_no,
383 (void)reference_cell;
385 const unsigned int dim = 1;
389 q_points[0] =
Point<dim>(
static_cast<double>(face_no));
398 const unsigned int face_no,
399 const unsigned int subface_no,
404 const auto face_quadrature =
411 q_points = face_quadrature.get_points();
420 const unsigned int face_no,
421 const unsigned int subface_no,
426 (void)reference_cell;
428 const auto face_quadrature =
435 q_points = face_quadrature.get_points();
445 const unsigned int face_no,
446 const unsigned int subface_no,
467 const unsigned int face_no,
468 const unsigned int subface_no,
474 reference_cell.n_face_orientations(face_no));
477 reference_cell.face_reference_cell(face_no)
478 .template n_children<dim - 1>(ref_case));
480 std::vector<Point<dim>> q_points;
481 std::vector<double> q_weights = quadrature.
get_weights();
482 q_points.reserve(quadrature.
size());
484 if constexpr (dim == 1)
487 q_points.emplace_back(
static_cast<double>(face_no));
489 else if constexpr (dim == 2)
494 for (
unsigned int p = 0; p < quadrature.
size(); ++p)
499 q_points.emplace_back(quadrature.
point(p)[0] / 2, 0);
501 q_points.emplace_back(0.5 + quadrature.
point(p)[0] / 2, 0);
503 else if (face_no == 1)
506 q_points.emplace_back(1 - quadrature.
point(p)[0] / 2,
507 quadrature.
point(p)[0] / 2);
509 q_points.emplace_back(0.5 - quadrature.
point(p)[0] / 2,
510 0.5 + quadrature.
point(p)[0] / 2);
512 else if (face_no == 2)
515 q_points.emplace_back(0, 1 - quadrature.
point(p)[0] / 2);
517 q_points.emplace_back(0, 0.5 - quadrature.
point(p)[0] / 2);
523 for (
unsigned int p = 0; p < quadrature.
size(); ++p)
528 q_points.emplace_back(0, quadrature.
point(p)[0] / 2);
530 q_points.emplace_back(0, quadrature.
point(p)[0] / 2 + 0.5);
532 else if (face_no == 1)
535 q_points.emplace_back(1, quadrature.
point(p)[0] / 2);
537 q_points.emplace_back(1, quadrature.
point(p)[0] / 2 + 0.5);
539 else if (face_no == 2)
542 q_points.emplace_back(quadrature.
point(p)[0] / 2, 0);
544 q_points.emplace_back(quadrature.
point(p)[0] / 2 + 0.5, 0);
546 else if (face_no == 3)
549 q_points.emplace_back(quadrature.
point(p)[0] / 2, 1);
551 q_points.emplace_back(quadrature.
point(p)[0] / 2 + 0.5, 1);
561 std::reverse(q_points.begin(), q_points.end());
562 std::reverse(q_weights.begin(), q_weights.end());
564 for (
auto &w : q_weights)
565 w *= reference_cell.face_measure(face_no);
567 else if constexpr (dim == 3)
570 internal::QProjector::project_to_hex_face_and_append(
571 quadrature.
get_points(), face_no, q_points, ref_case, subface_no);
589 std::vector<Point<dim>> points;
590 std::vector<double> weights;
592 for (
const unsigned int face_no : reference_cell.face_indices())
595 reference_cell.face_reference_cell(face_no);
596 std::vector<Point<dim>> face_vertices(face_reference_cell.
n_vertices());
597 for (
const unsigned int vertex_no : face_reference_cell.
vertex_indices())
598 face_vertices[vertex_no] =
599 reference_cell.face_vertex_location<dim>(face_no, vertex_no);
602 combined_orientation < reference_cell.n_face_orientations(face_no);
603 ++combined_orientation)
604 internal::QProjector::append_subobject_rule(
606 quadrature[quadrature.
size() == 1 ? 0 : face_no],
608 reference_cell.face_measure(face_no),
609 combined_orientation,
625 (void)reference_cell;
627 const unsigned int dim = 1;
634 std::vector<Point<dim>> q_points;
635 q_points.reserve(n_points * n_faces * subfaces_per_face);
636 std::vector<Point<dim>> help(n_points);
640 for (
unsigned int face = 0; face < n_faces; ++face)
641 for (
unsigned int subface = 0; subface < subfaces_per_face; ++subface)
644 std::copy(help.begin(), help.end(), std::back_inserter(q_points));
648 std::vector<double> weights;
649 weights.reserve(n_points * n_faces * subfaces_per_face);
650 for (
unsigned int face = 0; face < n_faces; ++face)
651 for (
unsigned int subface = 0; subface < subfaces_per_face; ++subface)
654 std::back_inserter(weights));
656 Assert(q_points.size() == n_points * n_faces * subfaces_per_face,
658 Assert(weights.size() == n_points * n_faces * subfaces_per_face,
675 const unsigned int dim = 2;
677 std::vector<Point<dim>> q_points;
678 std::vector<double> weights;
682 for (
unsigned int face = 0; face < reference_cell.n_faces(); ++face)
684 orientation < reference_cell.n_face_orientations(face);
686 for (
unsigned int subface = 0;
688 reference_cell.face_reference_cell(face).n_isotropic_children();
691 const unsigned int local_subface =
694 const auto sub_quadrature =
701 q_points.insert(q_points.end(),
702 sub_quadrature.get_points().begin(),
703 sub_quadrature.get_points().end());
704 weights.insert(weights.end(),
705 sub_quadrature.get_weights().begin(),
706 sub_quadrature.get_weights().end());
725 const unsigned int dim = 3;
727 const unsigned int n_points = quadrature.
size(),
729 total_subfaces_per_face = 2 + 2 + 4;
732 std::vector<Point<dim>> q_points;
733 q_points.reserve(n_points * n_faces * total_subfaces_per_face * 8);
735 std::vector<double> weights;
736 weights.reserve(n_points * n_faces * total_subfaces_per_face * 8);
740 for (
unsigned char offset = 0; offset < 8; ++offset)
742 const auto mutation =
743 internal::QProjector::mutate_points_with_offset(quadrature.
get_points(),
747 for (
unsigned int face = 0; face < n_faces; ++face)
751 for (
unsigned int subface = 0;
756 internal::QProjector::project_to_hex_face_and_append(
766 std::back_inserter(weights));
770 Assert(q_points.size() == n_points * n_faces * total_subfaces_per_face * 8,
772 Assert(weights.size() == n_points * n_faces * total_subfaces_per_face * 8,
784 const unsigned int child_no)
788 (void)reference_cell;
792 const unsigned int n_q_points = quadrature.
size();
794 std::vector<Point<dim>> q_points(n_q_points);
795 for (
unsigned int i = 0; i < n_q_points; ++i)
803 std::vector<double> weights = quadrature.
get_weights();
804 for (
unsigned int i = 0; i < n_q_points; ++i)
819 (void)reference_cell;
821 const unsigned int n_points = quadrature.
size(),
824 std::vector<Point<dim>> q_points(n_points * n_children);
825 std::vector<double> weights(n_points * n_children);
829 for (
unsigned int child = 0; child < n_children; ++child)
833 for (
unsigned int i = 0; i < n_points; ++i)
835 q_points[child * n_points + i] = help.
point(i);
836 weights[child * n_points + i] = help.
weight(i);
853 (void)reference_cell;
855 const unsigned int n = quadrature.
size();
856 std::vector<Point<dim>> points(n);
857 std::vector<double> weights(n);
858 const double length = p1.
distance(p2);
860 for (
unsigned int k = 0; k < n; ++k)
862 const double alpha = quadrature.
point(k)[0];
863 points[k] = alpha * p2;
864 points[k] += (1. - alpha) * p1;
865 weights[k] = length * quadrature.
weight(k);
875 const unsigned int face_no,
876 const bool face_orientation,
877 const bool face_flip,
878 const bool face_rotation,
879 const unsigned int n_quadrature_points)
881 return face(reference_cell,
886 n_quadrature_points);
895 const unsigned int face_no,
897 const unsigned int n_quadrature_points)
901 reference_cell.n_face_orientations(face_no));
905 return {(reference_cell.n_face_orientations(face_no) * face_no +
906 combined_orientation) *
907 n_quadrature_points};
916 const unsigned int face_no,
917 const bool face_orientation,
918 const bool face_flip,
919 const bool face_rotation,
922 return face(reference_cell,
936 const unsigned int face_no,
942 reference_cell.n_face_orientations(face_no));
945 unsigned int offset = 0;
946 if (quadrature.
size() == 1)
948 reference_cell.n_face_orientations(0) * quadrature[0].
size() * face_no;
950 for (
unsigned int i = 0; i < face_no; ++i)
951 offset += reference_cell.n_face_orientations(i) * quadrature[i].
size();
953 return {offset + combined_orientation *
954 quadrature[quadrature.
size() == 1 ? 0 : face_no].
size()};
963 const unsigned int face_no,
964 const unsigned int subface_no,
965 const bool face_orientation,
966 const bool face_flip,
967 const bool face_rotation,
968 const unsigned int n_quadrature_points,
988 const unsigned int face_no,
989 const unsigned int subface_no,
991 const unsigned int n_quadrature_points,
995 (void)reference_cell;
1002 n_quadrature_points);
1011 const unsigned int face_no,
1012 const unsigned int subface_no,
1014 const unsigned int n_quadrature_points,
1021 const unsigned int n_faces = reference_cell.n_faces();
1022 const unsigned int n_subfaces =
1023 reference_cell.face_reference_cell(face_no).n_isotropic_children();
1024 const unsigned int n_orientations =
1025 reference_cell.n_face_orientations(face_no);
1031 return ((face_no * n_orientations * n_subfaces +
1032 combined_orientation * n_subfaces + subface_no) *
1033 n_quadrature_points);
1042 const unsigned int face_no,
1043 const unsigned int subface_no,
1045 const unsigned int n_quadrature_points,
1048 const unsigned int dim = 3;
1051 (void)reference_cell;
1065 const unsigned int total_subfaces_per_face = 8;
1082 static const unsigned int ref_case_offset[3] = {
1088 const auto [final_subface_no, refinement_case] =
1089 reference_cell.equivalent_refinement_case(combined_orientation,
1093 return ((face_no * total_subfaces_per_face +
1094 ref_case_offset[refinement_case - 1] + final_subface_no) +
1096 combined_orientation) *
1097 n_quadrature_points;
1106 const unsigned int face_no)
1110 (void)reference_cell;
1112 std::vector<Point<dim>> points(quadrature.
size());
1123 const unsigned int face_no,
1124 const unsigned int subface_no,
1129 (void)reference_cell;
1131 std::vector<Point<dim>> points(quadrature.
size());
1133 reference_cell, quadrature, face_no, subface_no, points, ref_case);
auto make_const_array_view(const Container &container) -> decltype(make_array_view(container))
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
Class storing the offset index into a Quadrature rule created by project_to_all_faces() or project_to...
static DataSetDescriptor subface(const ReferenceCell &reference_cell, const unsigned int face_no, const unsigned int subface_no, const bool face_orientation, const bool face_flip, const bool face_rotation, const unsigned int n_quadrature_points, const internal::SubfaceCase< dim > ref_case=internal::SubfaceCase< dim >::case_isotropic)
static DataSetDescriptor face(const ReferenceCell &reference_cell, const unsigned int face_no, const bool face_orientation, const bool face_flip, const bool face_rotation, const unsigned int n_quadrature_points)
Class which transforms dim - 1-dimensional quadrature rules to dim-dimensional face quadratures.
static Quadrature< dim > project_to_all_subfaces(const ReferenceCell &reference_cell, const SubQuadrature &quadrature)
static Quadrature< dim > project_to_all_faces(const ReferenceCell &reference_cell, const hp::QCollection< dim - 1 > &quadrature)
static Quadrature< dim > project_to_child(const ReferenceCell &reference_cell, const Quadrature< dim > &quadrature, const unsigned int child_no)
static Quadrature< dim > project_to_oriented_subface(const ReferenceCell &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, const unsigned int subface_no, const bool face_orientation, const bool face_flip, const bool face_rotation, const internal::SubfaceCase< dim > ref_case)
static Quadrature< dim > project_to_oriented_face(const ReferenceCell &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, const bool face_orientation, const bool face_flip, const bool face_rotation)
static Quadrature< dim > project_to_line(const ReferenceCell &reference_cell, const Quadrature< 1 > &quadrature, const Point< dim > &p1, const Point< dim > &p2)
static void project_to_subface(const ReferenceCell &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, const unsigned int subface_no, std::vector< Point< dim > > &q_points, const RefinementCase< dim - 1 > &ref_case=RefinementCase< dim - 1 >::isotropic_refinement)
static Quadrature< dim > project_to_all_children(const ReferenceCell &reference_cell, const Quadrature< dim > &quadrature)
static void project_to_face(const ReferenceCell &reference_cell, const SubQuadrature &quadrature, const unsigned int face_no, std::vector< Point< dim > > &q_points)
Quadrature< dim - 1 > SubQuadrature
const Point< dim > & point(const unsigned int i) const
double weight(const unsigned int i) const
const std::vector< double > & get_weights() const
const std::vector< Point< dim > > & get_points() const
unsigned int size() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices() const
unsigned int n_vertices() const
double d_linear_shape_function(const Point< dim > &xi, const unsigned int i) const
types::geometric_orientation get_inverse_combined_orientation(const types::geometric_orientation orientation) const
boost::container::small_vector< T, 8 > permute_by_combined_orientation(const ArrayView< const T > &vertices, const types::geometric_orientation orientation) const
unsigned int size() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
constexpr ReferenceCell Triangle
constexpr ReferenceCell Hexahedron
constexpr const ReferenceCell & get_hypercube()
constexpr ReferenceCell Quadrilateral
constexpr ReferenceCell Tetrahedron
constexpr ReferenceCell Line
types::geometric_orientation combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)
constexpr types::geometric_orientation reverse_line_orientation
constexpr types::geometric_orientation default_geometric_orientation
unsigned char geometric_orientation
static constexpr unsigned int max_children_per_face
static constexpr unsigned int faces_per_cell
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
static Point< dim > child_to_cell_coordinates(const Point< dim > &p, const unsigned int child_index, const RefinementCase< dim > refine_case=RefinementCase< dim >::isotropic_refinement)
static constexpr unsigned int max_children_per_cell