53 std::vector<Point<dim>> support_points;
54 support_points.resize(compute_n_dofs(dim, degree));
56 const double z_equidistance = 1.0 / degree;
59 const unsigned int n_dofs_per_line = 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);
69 std::vector<unsigned int> start_lines(4);
72 start_lines[0] = 5 + 4 * n_dofs_per_line;
74 for (
unsigned int i = 1; i < 4; ++i)
75 start_lines[i] = start_lines[i - 1] + n_dofs_per_line;
78 std::vector<unsigned int> start_faces(4);
79 start_faces[0] = 5 + 8 * n_dofs_per_line + n_dofs_per_quad;
81 for (
unsigned int i = 1; i < 4; ++i)
82 start_faces[i] = start_faces[i - 1] + (degree - 2) * (degree - 1) / 2;
84 unsigned int start_hex = 5 + 8 * n_dofs_per_line + total_dofs_faces;
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());
372 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
376 nodal_values[i] = support_point_values[i](0);
580 std::vector<std::pair<unsigned int, unsigned int>> identities;
584 const auto &face_support_points = this->get_unit_face_support_points(0);
585 const auto &face_support_points_other =
593 const unsigned int offset =
594 this->reference_cell().face_reference_cell(0).n_vertices() +
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);
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;
653 const auto &face_support_points = this->get_unit_face_support_points(face_no);
654 const auto &face_support_points_other =
659 const auto face_reference_cell =
660 this->reference_cell().face_reference_cell(face_no);
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);