36 compute_n_dofs(
const unsigned int dim,
const unsigned int degree)
46 std::vector<Point<dim>>
47 get_support_points(
const unsigned int degree)
53 std::vector<Point<dim>> support_points;
54 support_points.resize(compute_n_dofs(dim,
degree));
56 const double z_equidistance = 1.0 /
degree;
65 const unsigned int total_dofs_faces =
69 std::vector<unsigned int> start_lines(4);
74 for (
unsigned int i = 1; i < 4; ++i)
78 std::vector<unsigned int> start_faces(4);
81 for (
unsigned int i = 1; i < 4; ++i)
82 start_faces[i] = start_faces[i - 1] + (
degree - 2) * (
degree - 1) / 2;
87 [](
const Point<2> &p2d,
const double scale,
const double z) {
88 return Point<dim>(scale * (2.0 * p2d[0] - 1.0),
89 scale * (2.0 * p2d[1] - 1.0),
100 for (
unsigned int v = 0; v < fe_q.reference_cell().n_vertices(); ++v)
103 lift_point(fe_q.get_unit_support_points()[v], 1.0, 0.0);
106 for (
unsigned int l = 0;
107 l < fe_q.reference_cell().n_lines() * fe_q.n_dofs_per_line();
110 support_points[5 +
l] = lift_point(
111 fe_q.get_unit_support_points()[fe_q.reference_cell().n_vertices() +
117 for (
unsigned int q = 0; q < fe_q.n_dofs_per_quad(); ++q)
119 support_points[5 + 8 * n_dofs_per_line + q] = lift_point(
120 fe_q.get_unit_support_points()[fe_q.reference_cell().n_vertices() +
121 fe_q.reference_cell().n_lines() *
122 fe_q.n_dofs_per_line() +
129 for (
unsigned int current_degree = degree - 1; current_degree > 0;
137 const auto &points = fe_q.get_unit_support_points();
140 const double z = (degree - current_degree) * z_equidistance;
141 const double scale = current_degree * z_equidistance;
144 for (
unsigned int line = 0; line < fe_q.reference_cell().n_vertices();
147 support_points[start_lines[line]++] =
148 lift_point(points[p++], scale, z);
151 for (
unsigned int face = 0; face < fe_q.reference_cell().n_lines();
154 for (
unsigned int n_dof = 0; n_dof < fe_q.n_dofs_per_line();
156 support_points[start_faces[face]++] =
157 lift_point(points[p++], scale, z);
160 for (
unsigned int hex = 0; hex < fe_q.n_dofs_per_quad(); ++hex)
162 support_points[start_hex++] = lift_point(points[p++], scale, z);
166 for (
unsigned int d = 0;
d < dim; ++
d)
173 support_points[4] = tip;
175 return support_points;
184 get_dpo(
const unsigned int degree,
198 const unsigned int n_dofs_per_line = degree - 1;
203 const unsigned int n_dofs_per_quad = n_dofs_per_line * n_dofs_per_line;
204 const unsigned int n_dofs_per_tri = (degree - 2) * (degree - 1) / 2;
205 const unsigned int total_dofs_faces =
206 n_dofs_per_quad + 4 * n_dofs_per_tri;
208 const unsigned int n_dofs_per_tri_inclusive =
209 (degree + 1) * (degree + 2) / 2;
211 const unsigned int n_dofs_total = compute_n_dofs(dim, degree);
228 {n_dofs_total - 5 - 8 * n_dofs_per_line - total_dofs_faces}};
241 {(degree + 1) * (degree + 1),
242 n_dofs_per_tri_inclusive,
243 n_dofs_per_tri_inclusive,
244 n_dofs_per_tri_inclusive,
245 n_dofs_per_tri_inclusive},
251 5 + 1 * n_dofs_per_line,
252 5 + 2 * n_dofs_per_line,
253 5 + 3 * n_dofs_per_line,
254 5 + 4 * n_dofs_per_line,
255 5 + 5 * n_dofs_per_line,
256 5 + 6 * n_dofs_per_line,
257 5 + 7 * n_dofs_per_line},
258 {5 + 8 * n_dofs_per_line,
259 5 + 8 * n_dofs_per_line + n_dofs_per_quad,
260 5 + 8 * n_dofs_per_line + n_dofs_per_quad + n_dofs_per_tri,
261 5 + 8 * n_dofs_per_line + n_dofs_per_quad + 2 * n_dofs_per_tri,
262 5 + 8 * n_dofs_per_line + n_dofs_per_quad + 3 * n_dofs_per_tri},
263 {5 + 8 * n_dofs_per_line + total_dofs_faces}};
267 {4 + 4 * n_dofs_per_line,
268 3 + 3 * n_dofs_per_line,
269 3 + 3 * n_dofs_per_line,
270 3 + 3 * n_dofs_per_line,
271 3 + 3 * n_dofs_per_line}};
278template <
int dim,
int spacedim>
280 const unsigned int degree,
283 const bool prolongation_is_additive,
287 compute_n_dofs(dim,
degree),
302 prolongation_is_additive),
314 for (
auto &support_point : support_points)
324 const auto face_reference_cell =
333 for (
const auto &face_support_point :
337 for (
unsigned int d = 0; d < dim - 1; ++d)
338 p[d] = face_support_point[d];
345 for (
const auto &face_support_point :
349 for (
unsigned int d = 0; d < dim - 1; ++d)
350 p[d] = face_support_point[d];
360template <
int dim,
int spacedim>
365 std::vector<double> &nodal_values)
const
368 this->get_unit_support_points().size());
376 nodal_values[i] = support_point_values[i](0);
382template <
int dim,
int spacedim>
387 get_support_points<dim>(
degree),
399 const unsigned int n =
degree - 1;
400 const unsigned int face_no_quad = 0;
403 for (
unsigned int local = 0; local < this->
n_dofs_per_quad(face_no_quad);
406 unsigned int i = local % n, j = local / n;
415 i + (n - 1 - j) * n - local;
419 (n - 1 - j) + (n - 1 - i) * n - local;
423 (n - 1 - i) + j * n - local;
430 j + (n - 1 - i) * n - local;
434 (n - 1 - i) + (n - 1 - j) * n - local;
438 (n - 1 - j) + i * n - local;
449template <
int dim,
int spacedim>
450std::unique_ptr<FiniteElement<dim, spacedim>>
453 return std::make_unique<FE_PyramidP<dim, spacedim>>(*this);
458template <
int dim,
int spacedim>
462 std::ostringstream namebuf;
464 << this->degree <<
")";
466 return namebuf.str();
471template <
int dim,
int spacedim>
475 const unsigned int codim)
const
496 if (this->degree < fe_pp_other->
degree)
498 else if (this->degree == fe_pp_other->degree)
506 if (this->degree < fe_p_other->
degree)
508 else if (this->degree == fe_p_other->degree)
516 if (this->degree < fe_q_other->
degree)
518 else if (this->degree == fe_q_other->degree)
526 if (this->degree < fe_pp_other->
degree)
528 else if (this->degree == fe_pp_other->degree)
536 if (fe_nothing->is_dominating())
551template <
int dim,
int spacedim>
552std::vector<std::pair<unsigned int, unsigned int>>
569template <
int dim,
int spacedim>
570std::vector<std::pair<unsigned int, unsigned int>>
580 std::vector<std::pair<unsigned int, unsigned int>> identities;
585 const auto &face_support_points_other =
593 const unsigned int offset =
595 2 * this->n_dofs_per_line();
597 const unsigned int offset_other =
598 fe_other.
reference_cell().face_reference_cell(0).is_hyper_cube() ?
604 for (
unsigned int i = 0; i < this->n_dofs_per_line(); ++i)
606 if (face_support_points[i + offset].distance(
607 face_support_points_other[j + offset_other]) < 1e-14)
608 identities.emplace_back(i, j);
615template <
int dim,
int spacedim>
616std::vector<std::pair<unsigned int, unsigned int>>
619 const unsigned int face_no)
const
622 std::vector<std::pair<unsigned int, unsigned int>> identities;
624 unsigned int face_no_neighbor;
635 face_no_neighbor = 2;
637 face_no_neighbor = 0;
647 face_no_neighbor = 1;
649 face_no_neighbor = 0;
654 const auto &face_support_points_other =
659 const auto face_reference_cell =
662 Assert(face_reference_cell ==
666 const unsigned int offset =
667 face_reference_cell.n_vertices() +
668 face_reference_cell.n_lines() * this->n_dofs_per_line();
670 const unsigned int offset_other =
671 face_reference_cell.n_vertices() +
675 for (
unsigned int i = 0; i < this->n_dofs_per_quad(face_no); ++i)
676 for (
unsigned int j = 0; j < fe_other.
n_dofs_per_quad(face_no_neighbor);
678 if (face_support_points[i + offset].distance(
679 face_support_points_other[j + offset_other]) < 1e-14)
680 identities.emplace_back(i, j);
687template <
int dim,
int spacedim>
692 get_support_points<dim>(
degree),
699template <
int dim,
int spacedim>
700std::unique_ptr<FiniteElement<dim, spacedim>>
703 return std::make_unique<FE_PyramidDGP<dim, spacedim>>(*this);
708template <
int dim,
int spacedim>
712 std::ostringstream namebuf;
714 << this->degree <<
")";
716 return namebuf.str();
720#include "fe/fe_pyramid_p.inst"
FE_Poly(const ScalarPolynomialsBase< dim > &poly_space, const FiniteElementData< dim > &fe_data, const std::vector< bool > &restriction_is_additive_flags, const std::vector< ComponentMask > &nonzero_components)
std::string get_name() const override
FE_PyramidDGP(const unsigned int degree)
std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
FE_PyramidP(const unsigned int degree)
std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other, const unsigned int face_no=0) const override
std::string get_name() const override
FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim) const override
FE_PyramidPoly(const unsigned int degree, const internal::GenericDoFsPerObject dpos, const std::vector< Point< dim > > support_points, const bool prolongation_is_additive, const typename FiniteElementData< dim >::Conformity conformity)
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const override
const unsigned int degree
unsigned int n_dofs_per_line() const
unsigned int n_dofs_per_quad(unsigned int face_no=0) const
const unsigned int dofs_per_cell
FiniteElementData(const std::vector< unsigned int > &dofs_per_object, const unsigned int n_components, const unsigned int degree, const Conformity conformity=unknown, const BlockIndices &block_indices=BlockIndices())
ReferenceCell< dim > reference_cell() const
std::vector< std::vector< Point< dim - 1 > > > unit_face_support_points
std::vector< Table< 2, int > > adjust_quad_dof_index_for_face_orientation_table
const std::vector< Point< dim > > & get_unit_support_points() const
const std::vector< Point< dim - 1 > > & get_unit_face_support_points(const unsigned int face_no=0) const
std::vector< int > adjust_line_dof_index_for_line_orientation_table
FiniteElement(const FiniteElementData< dim > &fe_data, const std::vector< bool > &restriction_is_additive_flags, const std::vector< ComponentMask > &nonzero_components)
std::vector< Point< dim > > unit_support_points
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
@ either_element_can_dominate
@ other_element_dominates
@ neither_element_dominates
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
constexpr ReferenceCell< 2 > Quadrilateral
constexpr ReferenceCell< 2 > Triangle
constexpr ReferenceCell< 3 > Pyramid
std::string dim_string(const int dim, const int spacedim)
types::geometric_orientation combined_face_orientation(const bool face_orientation, const bool face_rotation, const bool face_flip)
template internal::GenericDoFsPerObject expand< 3 >(const std::vector< unsigned int > &dofs_per_object, const ReferenceCell< 3 > cell_type)
std::vector< std::vector< unsigned int > > object_index
std::vector< std::vector< unsigned int > > first_object_index_on_face
std::vector< std::vector< unsigned int > > dofs_per_object_inclusive
std::vector< std::vector< unsigned int > > dofs_per_object_exclusive