deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
fe_pyramid_p.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2021 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#include <deal.II/base/config.h>
14
18
19#include <deal.II/fe/fe_dgq.h>
22#include <deal.II/fe/fe_q.h>
25#include <deal.II/fe/fe_tools.h>
27
29
30namespace
31{
35 unsigned int
36 compute_n_dofs(const unsigned int dim, const unsigned int degree)
37 {
38 AssertDimension(dim, 3);
39 return (degree + 1) * (degree + 2) * (2 * degree + 3) / 6;
40 }
41
45 template <int dim>
46 std::vector<Point<dim>>
47 get_support_points(const unsigned int degree)
48 {
50 Assert(degree > 0, ExcInternalError("Degree must be larger than 0."));
51
52
53 std::vector<Point<dim>> support_points;
54 support_points.resize(compute_n_dofs(dim, degree));
55
56 const double z_equidistance = 1.0 / degree;
57
58 // the support points on the 8 lines excluding the vertices
59 const unsigned int n_dofs_per_line = degree - 1;
60
61 // support points on the bottom quad face and on the 4 triangular faces,
62 // on the triangular faces the number of points is the sum from 1 to
63 // (degree - 2) so 4*0.5*(degree - 2)*(degree - 1)
64 const unsigned int n_dofs_per_quad = n_dofs_per_line * n_dofs_per_line;
65 const unsigned int total_dofs_faces =
66 n_dofs_per_quad + 2 * (degree - 2) * (degree - 1);
67
68 // starting indices for lines 4 - 7
69 std::vector<unsigned int> start_lines(4);
70 // line 4 starts after the DoFs at the vertices and the DoFs on the lines of
71 // the bottom quad
72 start_lines[0] = 5 + 4 * n_dofs_per_line;
73 // the rest increments with the number of DoFs on the edges 4 - 7
74 for (unsigned int i = 1; i < 4; ++i)
75 start_lines[i] = start_lines[i - 1] + n_dofs_per_line;
76
77 // same applies to the triangular faces 1 - 4
78 std::vector<unsigned int> start_faces(4);
79 start_faces[0] = 5 + 8 * n_dofs_per_line + n_dofs_per_quad;
80
81 for (unsigned int i = 1; i < 4; ++i)
82 start_faces[i] = start_faces[i - 1] + (degree - 2) * (degree - 1) / 2;
83
84 unsigned int start_hex = 5 + 8 * n_dofs_per_line + total_dofs_faces;
85
86 auto lift_point =
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),
90 z);
91 };
92 {
93 // this gives all info on the vertices, the first 4 edges and the
94 // first face
95 // switch to FE_Q when simplex supports electrostatic points
96 // FE_Q<2> fe_q(degree);
97 FE_Q<2> fe_q(QIterated<1>(QTrapezoid<1>(), degree));
98
99 // vertices
100 for (unsigned int v = 0; v < fe_q.reference_cell().n_vertices(); ++v)
101 {
102 support_points[v] =
103 lift_point(fe_q.get_unit_support_points()[v], 1.0, 0.0);
104 }
105 // lines
106 for (unsigned int l = 0;
107 l < fe_q.reference_cell().n_lines() * fe_q.n_dofs_per_line();
108 ++l)
109 {
110 support_points[5 + l] = lift_point(
111 fe_q.get_unit_support_points()[fe_q.reference_cell().n_vertices() +
112 l],
113 1.0,
114 0.0);
115 }
116 // quad
117 for (unsigned int q = 0; q < fe_q.n_dofs_per_quad(); ++q)
118 {
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() +
123 q],
124 1.0,
125 0.0);
126 }
127 }
128 // now add the other layers
129 for (unsigned int current_degree = degree - 1; current_degree > 0;
130 --current_degree)
131 {
132 // switch to FE_Q when simplex supports electrostatic points
133 // FE_Q<2> fe_q(current_degree);
134 FE_Q<2> fe_q(QIterated<1>(QTrapezoid<1>(), current_degree));
135
136
137 const auto &points = fe_q.get_unit_support_points();
138 unsigned int p = 0;
139
140 const double z = (degree - current_degree) * z_equidistance;
141 const double scale = current_degree * z_equidistance;
142
143 // vertices are on lines
144 for (unsigned int line = 0; line < fe_q.reference_cell().n_vertices();
145 ++line)
146 {
147 support_points[start_lines[line]++] =
148 lift_point(points[p++], scale, z);
149 }
150 // lines are on face
151 for (unsigned int face = 0; face < fe_q.reference_cell().n_lines();
152 ++face)
153 {
154 for (unsigned int n_dof = 0; n_dof < fe_q.n_dofs_per_line();
155 ++n_dof)
156 support_points[start_faces[face]++] =
157 lift_point(points[p++], scale, z);
158 }
159 // faces are on hex
160 for (unsigned int hex = 0; hex < fe_q.n_dofs_per_quad(); ++hex)
161 {
162 support_points[start_hex++] = lift_point(points[p++], scale, z);
163 }
164 }
165 Point<dim> tip;
166 for (unsigned int d = 0; d < dim; ++d)
167 {
168 if (d == 2)
169 tip[d] = 1.0;
170 else
171 tip[d] = 0.0;
172 }
173 support_points[4] = tip;
174
175 return support_points;
176 }
177
178
182 template <int dim>
184 get_dpo(const unsigned int degree,
185 const typename FiniteElementData<dim>::Conformity conformity)
186 {
187 AssertDimension(dim, 3);
189
190 if (conformity == FiniteElementData<dim>::L2)
191 {
192 dpo = internal::expand<3>({{0, 0, 0, compute_n_dofs(dim, degree)}},
194 }
195 else if (conformity == FiniteElementData<dim>::H1)
196 {
197 // the support points on the 8 lines excluding the vertices
198 const unsigned int n_dofs_per_line = degree - 1;
199
200 // support points on the bottom quad face and on the 4 triangular faces,
201 // on the triangular faces the number of points is the sum from 1 to
202 // (degree - 2) so 4*0.5*(degree - 2)*(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;
207 // total number of DoFs on a tri
208 const unsigned int n_dofs_per_tri_inclusive =
209 (degree + 1) * (degree + 2) / 2;
210
211 const unsigned int n_dofs_total = compute_n_dofs(dim, degree);
212
214 {1, 1, 1, 1, 1},
215 {n_dofs_per_line,
216 n_dofs_per_line,
217 n_dofs_per_line,
218 n_dofs_per_line,
219 n_dofs_per_line,
220 n_dofs_per_line,
221 n_dofs_per_line,
222 n_dofs_per_line},
223 {n_dofs_per_quad,
224 n_dofs_per_tri,
225 n_dofs_per_tri,
226 n_dofs_per_tri,
227 n_dofs_per_tri},
228 {n_dofs_total - 5 - 8 * n_dofs_per_line - total_dofs_faces}};
229
230 dpo.dofs_per_object_inclusive = {{1, 1, 1, 1, 1},
231 {
232 degree + 1,
233 degree + 1,
234 degree + 1,
235 degree + 1,
236 degree + 1,
237 degree + 1,
238 degree + 1,
239 degree + 1,
240 },
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},
246 {n_dofs_total}};
247
248 dpo.object_index = {
249 {0, 1, 2, 3, 4},
250 {5,
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}};
264
265 dpo.first_object_index_on_face = {{0, 0, 0, 0, 0},
266 {4, 3, 3, 3, 3},
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}};
272 }
273 return dpo;
274 }
275} // namespace
276
277
278template <int dim, int spacedim>
280 const unsigned int degree,
282 const std::vector<Point<dim>> support_points,
283 const bool prolongation_is_additive,
284 const typename FiniteElementData<dim>::Conformity conformity)
285 : ::FE_Poly<dim, spacedim>(
287 compute_n_dofs(dim, degree),
288 support_points),
289 FiniteElementData<dim>(dpos,
290 reinterpret_cast<const ReferenceCell<dim> &>(
291 ReferenceCells::Pyramid),
292 1,
293 degree,
294 conformity),
295 std::vector<bool>(
296 FiniteElementData<dim>(dpos,
297 reinterpret_cast<const ReferenceCell<dim> &>(
298 ReferenceCells::Pyramid),
299 1,
300 degree)
301 .dofs_per_cell,
302 prolongation_is_additive),
303 std::vector<ComponentMask>(
304 FiniteElementData<dim>(dpos,
305 reinterpret_cast<const ReferenceCell<dim> &>(
306 ReferenceCells::Pyramid),
307 1,
308 degree)
309 .dofs_per_cell,
310 ComponentMask(std::vector<bool>(1, true))))
311{
312 AssertDimension(dim, 3);
313
314 for (auto &support_point : support_points)
315 this->unit_support_points.emplace_back(support_point);
316
317 if (conformity == FiniteElementData<dim>::H1)
318 {
319 // face support points
320 this->unit_face_support_points.resize(this->reference_cell().n_faces());
321
322 for (const auto f : this->reference_cell().face_indices())
323 {
324 const auto face_reference_cell =
325 this->reference_cell().face_reference_cell(f);
326
327 if (face_reference_cell == ReferenceCells::Quadrilateral)
328 {
329 // switch to FE_Q when simplex supports electrostatic points
330 // FE_Q<2> fe_face(degree);
332
333 for (const auto &face_support_point :
334 fe_face.get_unit_support_points())
335 {
336 Point<dim - 1> p;
337 for (unsigned int d = 0; d < dim - 1; ++d)
338 p[d] = face_support_point[d];
339 this->unit_face_support_points[f].emplace_back(p);
340 }
341 }
342 else if (face_reference_cell == ReferenceCells::Triangle)
343 {
344 FE_SimplexP<2> fe_face(degree);
345 for (const auto &face_support_point :
346 fe_face.get_unit_support_points())
347 {
348 Point<dim - 1> p;
349 for (unsigned int d = 0; d < dim - 1; ++d)
350 p[d] = face_support_point[d];
351 this->unit_face_support_points[f].emplace_back(p);
352 }
353 }
354 }
355 }
356}
357
358
359
360template <int dim, int spacedim>
361void
364 const std::vector<Vector<double>> &support_point_values,
365 std::vector<double> &nodal_values) const
366{
367 AssertDimension(support_point_values.size(),
368 this->get_unit_support_points().size());
369 AssertDimension(support_point_values.size(), nodal_values.size());
370 AssertDimension(this->dofs_per_cell, nodal_values.size());
371
372 for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
373 {
374 AssertDimension(support_point_values[i].size(), 1);
375
376 nodal_values[i] = support_point_values[i](0);
377 }
378}
379
380
381
382template <int dim, int spacedim>
384 : FE_PyramidPoly<dim, spacedim>(degree,
385 get_dpo<dim>(degree,
386 FiniteElementData<dim>::H1),
387 get_support_points<dim>(degree),
388 false,
389 FiniteElementData<dim>::H1)
390{
391 if (degree > 2)
392 {
393 // adjust DoFs on lines
394 for (unsigned int i = 0; i < this->n_dofs_per_line(); ++i)
396 this->n_dofs_per_line() - 1 - i - i;
397
398 // do the quad face first
399 const unsigned int n = degree - 1;
400 const unsigned int face_no_quad = 0;
401 Assert(n * n == this->n_dofs_per_quad(face_no_quad), ExcInternalError());
402 // see fe_q_base.cc
403 for (unsigned int local = 0; local < this->n_dofs_per_quad(face_no_quad);
404 ++local)
405 {
406 unsigned int i = local % n, j = local / n;
407
408 // face_orientation=false, face_flip=false, face_rotation=false
410 local, internal::combined_face_orientation(false, false, false)) =
411 j + i * n - local;
412 // face_orientation=false, face_flip=false, face_rotation=true
414 local, internal::combined_face_orientation(false, true, false)) =
415 i + (n - 1 - j) * n - local;
416 // face_orientation=false, face_flip=true, face_rotation=false
418 local, internal::combined_face_orientation(false, false, true)) =
419 (n - 1 - j) + (n - 1 - i) * n - local;
420 // face_orientation=false, face_flip=true, face_rotation=true
422 local, internal::combined_face_orientation(false, true, true)) =
423 (n - 1 - i) + j * n - local;
424 // face_orientation=true, face_flip=false, face_rotation=false
426 local, internal::combined_face_orientation(true, false, false)) = 0;
427 // face_orientation=true, face_flip=false, face_rotation=true
429 local, internal::combined_face_orientation(true, true, false)) =
430 j + (n - 1 - i) * n - local;
431 // face_orientation=true, face_flip=true, face_rotation=false
433 local, internal::combined_face_orientation(true, false, true)) =
434 (n - 1 - i) + (n - 1 - j) * n - local;
435 // face_orientation=true, face_flip=true, face_rotation=true
437 local, internal::combined_face_orientation(true, true, true)) =
438 (n - 1 - j) + i * n - local;
439 }
440
441 // Now do it for the triangular faces
442 // for degree 3 there is only 1 DoF on the face
444 }
445}
446
447
448
449template <int dim, int spacedim>
450std::unique_ptr<FiniteElement<dim, spacedim>>
452{
453 return std::make_unique<FE_PyramidP<dim, spacedim>>(*this);
454}
455
456
457
458template <int dim, int spacedim>
459std::string
461{
462 std::ostringstream namebuf;
463 namebuf << "FE_PyramidP<" << Utilities::dim_string(dim, spacedim) << ">("
464 << this->degree << ")";
465
466 return namebuf.str();
467}
468
469
470
471template <int dim, int spacedim>
474 const FiniteElement<dim, spacedim> &fe_other,
475 const unsigned int codim) const
476{
477 Assert(codim <= dim, ExcImpossibleInDim(dim));
478
479 // vertex/line/face domination
480 // (if fe_other is derived from FE_SimplexDGP)
481 // ------------------------------------
482 if (codim > 0)
483 if (dynamic_cast<const FE_SimplexDGP<dim, spacedim> *>(&fe_other) !=
484 nullptr)
485 // there are no requirements between continuous and discontinuous
486 // elements
488
489 // vertex/line/face domination
490 // (if fe_other is not derived from FE_SimplexDGP)
491 // & cell domination
492 // ----------------------------------------
493 if (const FE_PyramidP<dim, spacedim> *fe_pp_other =
494 dynamic_cast<const FE_PyramidP<dim, spacedim> *>(&fe_other))
495 {
496 if (this->degree < fe_pp_other->degree)
498 else if (this->degree == fe_pp_other->degree)
500 else
502 }
503 else if (const FE_SimplexP<dim, spacedim> *fe_p_other =
504 dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other))
505 {
506 if (this->degree < fe_p_other->degree)
508 else if (this->degree == fe_p_other->degree)
510 else
512 }
513 else if (const FE_Q<dim, spacedim> *fe_q_other =
514 dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other))
515 {
516 if (this->degree < fe_q_other->degree)
518 else if (this->degree == fe_q_other->degree)
520 else
522 }
523 else if (const FE_WedgeP<dim, spacedim> *fe_pp_other =
524 dynamic_cast<const FE_WedgeP<dim, spacedim> *>(&fe_other))
525 {
526 if (this->degree < fe_pp_other->degree)
528 else if (this->degree == fe_pp_other->degree)
530 else
532 }
533 else if (const FE_Nothing<dim, spacedim> *fe_nothing =
534 dynamic_cast<const FE_Nothing<dim, spacedim> *>(&fe_other))
535 {
536 if (fe_nothing->is_dominating())
538 else
539 // the FE_Nothing has no degrees of freedom and it is typically used
540 // in a context where we don't require any continuity along the
541 // interface
543 }
544
547}
548
549
550
551template <int dim, int spacedim>
552std::vector<std::pair<unsigned int, unsigned int>>
554 const FiniteElement<dim, spacedim> &fe_other) const
555{
556 (void)fe_other;
557
558 Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)) ||
559 (dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)) ||
560 (dynamic_cast<const FE_PyramidP<dim, spacedim> *>(&fe_other)) ||
561 (dynamic_cast<const FE_WedgeP<dim, spacedim> *>(&fe_other)),
563
564 return {{0, 0}};
565}
566
567
568
569template <int dim, int spacedim>
570std::vector<std::pair<unsigned int, unsigned int>>
572 const FiniteElement<dim, spacedim> &fe_other) const
573{
574 Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)) ||
575 (dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)) ||
576 (dynamic_cast<const FE_PyramidP<dim, spacedim> *>(&fe_other)) ||
577 (dynamic_cast<const FE_WedgeP<dim, spacedim> *>(&fe_other)),
579
580 std::vector<std::pair<unsigned int, unsigned int>> identities;
581 // check if the support points are the same location on the line
582 // the pyramid base is defined by the vertices [-1,-1,0], [1,-1,0],
583 // [-1,1,0], [1,1,0], to avoid rescaling use the support points on the faces
584 const auto &face_support_points = this->get_unit_face_support_points(0);
585 const auto &face_support_points_other =
587
588 // now just compare the DoFs on the line going from [0,0] to [1,0]
589 // for a triangular face that is the first line
590 // for a quad face that is the third line
591 // adjust the offsets accordingly
592 // face number 0 of the pyramid is a quad
593 const unsigned int offset =
594 this->reference_cell().face_reference_cell(0).n_vertices() +
595 2 * this->n_dofs_per_line();
596
597 const unsigned int offset_other =
598 fe_other.reference_cell().face_reference_cell(0).is_hyper_cube() ?
599 fe_other.reference_cell().face_reference_cell(0).n_vertices() +
600 2 * fe_other.n_dofs_per_line() :
601 fe_other.reference_cell().face_reference_cell(0).n_vertices();
602
603 // now get the identities
604 for (unsigned int i = 0; i < this->n_dofs_per_line(); ++i)
605 for (unsigned int j = 0; j < fe_other.n_dofs_per_line(); ++j)
606 if (face_support_points[i + offset].distance(
607 face_support_points_other[j + offset_other]) < 1e-14)
608 identities.emplace_back(i, j);
609
610 return identities;
611}
612
613
614
615template <int dim, int spacedim>
616std::vector<std::pair<unsigned int, unsigned int>>
618 const FiniteElement<dim, spacedim> &fe_other,
619 const unsigned int face_no) const
620{
621 AssertIndexRange(face_no, 5);
622 std::vector<std::pair<unsigned int, unsigned int>> identities;
623
624 unsigned int face_no_neighbor;
625
626 if (face_no == 0)
627 {
628 // on a quad, neighbor can be a hex, a pyramid or a wedge
629 Assert((dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)) ||
630 (dynamic_cast<const FE_PyramidP<dim, spacedim> *>(&fe_other)) ||
631 (dynamic_cast<const FE_WedgeP<dim, spacedim> *>(&fe_other)),
633 // for the wedge the first quad face is face no. 2
634 if (dynamic_cast<const FE_WedgeP<dim, spacedim> *>(&fe_other))
635 face_no_neighbor = 2;
636 else
637 face_no_neighbor = 0;
638 }
639 else
640 {
641 Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)) ||
642 (dynamic_cast<const FE_PyramidP<dim, spacedim> *>(&fe_other)) ||
643 (dynamic_cast<const FE_WedgeP<dim, spacedim> *>(&fe_other)),
645 // on tri, neighbor can be a tet, a pyramid or a wedge
646 if (dynamic_cast<const FE_PyramidP<dim, spacedim> *>(&fe_other))
647 face_no_neighbor = 1;
648 else
649 face_no_neighbor = 0;
650 }
651
652 // compare the face support points
653 const auto &face_support_points = this->get_unit_face_support_points(face_no);
654 const auto &face_support_points_other =
655 fe_other.get_unit_face_support_points(face_no_neighbor);
656
657 // get the offsets to only compare the DoFs within the face as the vertices
658 // and lines were done before
659 const auto face_reference_cell =
660 this->reference_cell().face_reference_cell(face_no);
661
662 Assert(face_reference_cell ==
663 fe_other.reference_cell().face_reference_cell(face_no_neighbor),
665
666 const unsigned int offset =
667 face_reference_cell.n_vertices() +
668 face_reference_cell.n_lines() * this->n_dofs_per_line();
669
670 const unsigned int offset_other =
671 face_reference_cell.n_vertices() +
672 face_reference_cell.n_lines() * fe_other.n_dofs_per_line();
673
674 // do the comparison
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);
677 ++j)
678 if (face_support_points[i + offset].distance(
679 face_support_points_other[j + offset_other]) < 1e-14)
680 identities.emplace_back(i, j);
681
682 return identities;
683}
684
685
686
687template <int dim, int spacedim>
689 : FE_PyramidPoly<dim, spacedim>(degree,
690 get_dpo<dim>(degree,
691 FiniteElementData<dim>::L2),
692 get_support_points<dim>(degree),
693 true,
694 FiniteElementData<dim>::L2)
695{}
696
697
698
699template <int dim, int spacedim>
700std::unique_ptr<FiniteElement<dim, spacedim>>
702{
703 return std::make_unique<FE_PyramidDGP<dim, spacedim>>(*this);
704}
705
706
707
708template <int dim, int spacedim>
709std::string
711{
712 std::ostringstream namebuf;
713 namebuf << "FE_PyramidDGP<" << Utilities::dim_string(dim, spacedim) << ">("
714 << this->degree << ")";
715
716 return namebuf.str();
717}
718
719// explicit instantiations
720#include "fe/fe_pyramid_p.inst"
721
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
Definition fe_q.h:552
const unsigned int degree
Definition fe_data.h:450
unsigned int n_dofs_per_line() const
unsigned int n_dofs_per_quad(unsigned int face_no=0) const
ReferenceCell< dim > reference_cell() const
std::vector< std::vector< Point< dim - 1 > > > unit_face_support_points
Definition fe.h:2592
std::vector< Table< 2, int > > adjust_quad_dof_index_for_face_orientation_table
Definition fe.h:2621
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
Definition fe.h:2634
std::vector< Point< dim > > unit_support_points
Definition fe.h:2585
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#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()
std::size_t size
Definition mpi.cc:733
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
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)
Definition utilities.cc:547
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)
STL namespace.
std::vector< std::vector< unsigned int > > object_index
Definition fe_data.h:195
std::vector< std::vector< unsigned int > > first_object_index_on_face
Definition fe_data.h:200
std::vector< std::vector< unsigned int > > dofs_per_object_inclusive
Definition fe_data.h:190
std::vector< std::vector< unsigned int > > dofs_per_object_exclusive
Definition fe_data.h:185