17 #include <deal.II/base/polynomials_piecewise.h> 18 #include <deal.II/base/qprojector.h> 19 #include <deal.II/base/quadrature.h> 20 #include <deal.II/base/quadrature_lib.h> 21 #include <deal.II/base/std_cxx14/memory.h> 22 #include <deal.II/base/template_constraints.h> 23 #include <deal.II/base/tensor_product_polynomials.h> 24 #include <deal.II/base/tensor_product_polynomials_bubbles.h> 25 #include <deal.II/base/tensor_product_polynomials_const.h> 27 #include <deal.II/fe/fe_dgp.h> 28 #include <deal.II/fe/fe_dgq.h> 29 #include <deal.II/fe/fe_nothing.h> 30 #include <deal.II/fe/fe_q_base.h> 31 #include <deal.II/fe/fe_tools.h> 36 DEAL_II_NAMESPACE_OPEN
47 inline std::vector<unsigned int>
48 face_lexicographic_to_hierarchic_numbering(
const unsigned int degree)
50 std::vector<unsigned int> dpo(dim, 1U);
51 for (
unsigned int i = 1; i < dpo.size(); ++i)
52 dpo[i] = dpo[i - 1] * (degree - 1);
53 const ::FiniteElementData<dim - 1> face_data(dpo, 1, degree);
54 std::vector<unsigned int> face_renumber(face_data.dofs_per_cell);
62 inline std::vector<unsigned int>
63 face_lexicographic_to_hierarchic_numbering<1>(
const unsigned int)
65 return std::vector<unsigned int>();
75 zero_indices(
unsigned int (&indices)[dim])
77 for (
unsigned int d = 0;
d < dim; ++
d)
88 increment_indices(
unsigned int (&indices)[dim],
const unsigned int dofs1d)
91 for (
int d = 0;
d < dim - 1; ++
d)
92 if (indices[d] == dofs1d)
108 template <
class PolynomialType,
int xdim,
int xspacedim>
115 template <
int spacedim>
124 template <
int spacedim>
129 const unsigned int dim = 2;
131 unsigned int q_deg = fe.
degree;
132 if (std::is_same<PolynomialType,
180 std::vector<
Point<dim - 1>> constraint_points;
182 constraint_points.emplace_back(0.5);
186 const unsigned int n = q_deg - 1;
187 const double step = 1. / q_deg;
189 for (
unsigned int i = 1; i <= n; ++i)
190 constraint_points.push_back(
194 for (
unsigned int i = 1; i <= n; ++i)
195 constraint_points.push_back(
208 const std::vector<unsigned int> &index_map_inverse =
210 const std::vector<unsigned int> face_index_map =
211 internal::FE_Q_Base::face_lexicographic_to_hierarchic_numbering<dim>(
218 for (
unsigned int i = 0; i < constraint_points.size(); ++i)
219 for (
unsigned int j = 0; j < q_deg + 1; ++j)
222 p[0] = constraint_points[i](0);
224 fe.
poly_space.compute_value(index_map_inverse[j], p);
236 template <
int spacedim>
241 const unsigned int dim = 3;
243 unsigned int q_deg = fe.
degree;
244 if (std::is_same<PolynomialType,
263 std::vector<
Point<dim - 1>> constraint_points;
266 constraint_points.emplace_back(0.5, 0.5);
269 constraint_points.emplace_back(0, 0.5);
270 constraint_points.emplace_back(1, 0.5);
271 constraint_points.emplace_back(0.5, 0);
272 constraint_points.emplace_back(0.5, 1);
276 const unsigned int n = q_deg - 1;
277 const double step = 1. / q_deg;
278 std::vector<
Point<dim - 2>> line_support_points(n);
279 for (
unsigned int i = 0; i < n; ++i)
280 line_support_points[i](0) = (i + 1) * step;
281 Quadrature<dim - 2> qline(line_support_points);
284 std::vector<
Point<dim - 1>> p_line(n);
290 for (
unsigned int i = 0; i < n; ++i)
294 for (
unsigned int i = 0; i < n; ++i)
298 for (
unsigned int i = 0; i < n; ++i)
302 for (
unsigned int i = 0; i < n; ++i)
306 for (
unsigned int face = 0;
309 for (
unsigned int subface = 0;
317 constraint_points.insert(constraint_points.end(),
323 std::vector<
Point<dim - 1>> inner_points(n * n);
324 for (
unsigned int i = 0, iy = 1; iy <= n; ++iy)
325 for (
unsigned int ix = 1; ix <= n; ++ix)
329 for (
unsigned int child = 0;
332 for (
const auto &inner_point : inner_points)
333 constraint_points.push_back(
340 const unsigned int pnts = (q_deg + 1) * (q_deg + 1);
344 const std::vector<unsigned int> &index_map_inverse =
346 const std::vector<unsigned int> face_index_map =
347 internal::FE_Q_Base::face_lexicographic_to_hierarchic_numbering<dim>(
357 for (
unsigned int i = 0; i < constraint_points.size(); ++i)
359 const double interval =
static_cast<double>(q_deg * 2);
360 bool mirror[dim - 1];
372 for (
unsigned int k = 0; k < dim - 1; ++k)
374 const int coord_int =
375 static_cast<int>(constraint_points[i](k) * interval + 0.25);
376 constraint_point(k) = 1. * coord_int / interval;
398 mirror[k] = (constraint_point(k) > 0.5);
400 constraint_point(k) = 1.0 - constraint_point(k);
403 for (
unsigned int j = 0; j < pnts; ++j)
405 unsigned int indices[2] = {j % (q_deg + 1), j / (q_deg + 1)};
407 for (
unsigned int k = 0; k < 2; ++k)
409 indices[k] = q_deg - indices[k];
411 const unsigned int new_index =
412 indices[1] * (q_deg + 1) + indices[0];
415 fe.
poly_space.compute_value(index_map_inverse[new_index],
432 template <
class PolynomialType,
int dim,
int spacedim>
434 const PolynomialType & poly_space,
436 const std::vector<bool> & restriction_is_additive_flags)
437 :
FE_Poly<PolynomialType, dim, spacedim>(
440 restriction_is_additive_flags,
442 , q_degree(
std::is_same<PolynomialType,
450 template <
class PolynomialType,
int dim,
int spacedim>
453 const std::vector<
Point<1>> &points)
456 ExcMessage(
"The first support point has to be zero."));
457 Assert(points.back()[0] == 1,
458 ExcMessage(
"The last support point has to be one."));
463 const unsigned int q_dofs_per_cell =
464 Utilities::fixed_power<dim>(q_degree + 1);
465 Assert(q_dofs_per_cell == this->dofs_per_cell ||
466 q_dofs_per_cell + 1 == this->dofs_per_cell ||
467 q_dofs_per_cell + dim == this->dofs_per_cell,
471 std::vector<unsigned int> renumber(q_dofs_per_cell);
474 for (
unsigned int i = q_dofs_per_cell; i < this->dofs_per_cell; ++i)
475 renumber.push_back(i);
476 this->poly_space.set_numbering(renumber);
497 template <
class PolynomialType,
int dim,
int spacedim>
509 Assert(interpolation_matrix.
m() == this->dofs_per_cell,
511 this->dofs_per_cell));
517 const unsigned int q_dofs_per_cell =
518 Utilities::fixed_power<dim>(q_degree + 1);
519 const unsigned int source_q_dofs_per_cell =
520 Utilities::fixed_power<dim>(source_fe->degree + 1);
526 for (
unsigned int j = 0; j < q_dofs_per_cell; ++j)
529 const Point<dim> p = this->unit_support_points[j];
533 Assert(std::abs(this->poly_space.compute_value(j, p) - 1.) < 1e-13,
536 for (
unsigned int i = 0; i < source_q_dofs_per_cell; ++i)
537 interpolation_matrix(j, i) =
538 source_fe->poly_space.compute_value(i, p);
542 if (q_dofs_per_cell < this->dofs_per_cell)
545 for (
unsigned int i = 0; i < source_q_dofs_per_cell; ++i)
546 interpolation_matrix(q_dofs_per_cell, i) = 0.;
547 for (
unsigned int j = 0; j < q_dofs_per_cell; ++j)
548 interpolation_matrix(j, source_q_dofs_per_cell) = 0.;
549 interpolation_matrix(q_dofs_per_cell, source_q_dofs_per_cell) = 1.;
553 const double eps = 2e-13 * q_degree * dim;
554 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
555 for (
unsigned int j = 0; j < source_fe->dofs_per_cell; ++j)
556 if (std::fabs(interpolation_matrix(i, j)) < eps)
557 interpolation_matrix(i, j) = 0.;
561 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
564 for (
unsigned int j = 0; j < source_fe->dofs_per_cell; ++j)
565 sum += interpolation_matrix(i, j);
590 spacedim>::ExcInterpolationNotImplemented()));
595 template <
class PolynomialType,
int dim,
int spacedim>
602 get_subface_interpolation_matrix(source_fe,
604 interpolation_matrix);
609 template <
class PolynomialType,
int dim,
int spacedim>
613 const unsigned int subface,
627 Assert(interpolation_matrix.
n() == this->dofs_per_face,
629 this->dofs_per_face));
637 this->dofs_per_face <= source_fe->dofs_per_face,
639 spacedim>::ExcInterpolationNotImplemented()));
643 source_fe->get_unit_face_support_points());
648 double eps = 2e-13 * q_degree * (dim - 1);
659 for (
unsigned int i = 0; i < source_fe->dofs_per_face; ++i)
661 const Point<dim> &p = subface_quadrature.point(i);
663 for (
unsigned int j = 0; j < this->dofs_per_face; ++j)
665 double matrix_entry =
666 this->shape_value(this->face_to_cell_index(j, 0), p);
671 if (std::fabs(matrix_entry - 1.0) < eps)
673 if (std::fabs(matrix_entry) < eps)
676 interpolation_matrix(i, j) = matrix_entry;
682 for (
unsigned int j = 0; j < source_fe->dofs_per_face; ++j)
686 for (
unsigned int i = 0; i < this->dofs_per_face; ++i)
687 sum += interpolation_matrix(j, i);
692 else if (
dynamic_cast<const FE_Nothing<dim> *
>(&x_source_fe) !=
nullptr)
700 spacedim>::ExcInterpolationNotImplemented()));
705 template <
class PolynomialType,
int dim,
int spacedim>
714 template <
class PolynomialType,
int dim,
int spacedim>
715 std::vector<std::pair<unsigned int, unsigned int>>
724 &fe_other) !=
nullptr)
726 return std::vector<std::pair<unsigned int, unsigned int>>(
727 1, std::make_pair(0U, 0U));
733 return std::vector<std::pair<unsigned int, unsigned int>>();
744 return std::vector<std::pair<unsigned int, unsigned int>>();
749 return std::vector<std::pair<unsigned int, unsigned int>>();
755 template <
class PolynomialType,
int dim,
int spacedim>
756 std::vector<std::pair<unsigned int, unsigned int>>
774 const unsigned int p = this->degree;
775 const unsigned int q = fe_q_other->degree;
777 std::vector<std::pair<unsigned int, unsigned int>> identities;
779 const std::vector<unsigned int> &index_map_inverse =
780 this->poly_space.get_numbering_inverse();
781 const std::vector<unsigned int> &index_map_inverse_other =
782 fe_q_other->poly_space.get_numbering_inverse();
784 for (
unsigned int i = 0; i < p - 1; ++i)
785 for (
unsigned int j = 0; j < q - 1; ++j)
787 this->unit_support_points[index_map_inverse[i + 1]][0] -
788 fe_q_other->unit_support_points[index_map_inverse_other[j + 1]]
790 identities.emplace_back(i, j);
798 return std::vector<std::pair<unsigned int, unsigned int>>();
809 return std::vector<std::pair<unsigned int, unsigned int>>();
814 return std::vector<std::pair<unsigned int, unsigned int>>();
820 template <
class PolynomialType,
int dim,
int spacedim>
821 std::vector<std::pair<unsigned int, unsigned int>>
836 const unsigned int p = this->degree;
837 const unsigned int q = fe_q_other->degree;
839 std::vector<std::pair<unsigned int, unsigned int>> identities;
841 const std::vector<unsigned int> &index_map_inverse =
842 this->poly_space.get_numbering_inverse();
843 const std::vector<unsigned int> &index_map_inverse_other =
844 fe_q_other->poly_space.get_numbering_inverse();
846 for (
unsigned int i1 = 0; i1 < p - 1; ++i1)
847 for (
unsigned int i2 = 0; i2 < p - 1; ++i2)
848 for (
unsigned int j1 = 0; j1 < q - 1; ++j1)
849 for (
unsigned int j2 = 0; j2 < q - 1; ++j2)
851 this->unit_support_points[index_map_inverse[i1 + 1]][0] -
853 ->unit_support_points[index_map_inverse_other[j1 + 1]]
856 this->unit_support_points[index_map_inverse[i2 + 1]][0] -
858 ->unit_support_points[index_map_inverse_other[j2 + 1]]
860 identities.emplace_back(i1 * (p - 1) + i2, j1 * (q - 1) + j2);
868 return std::vector<std::pair<unsigned int, unsigned int>>();
879 return std::vector<std::pair<unsigned int, unsigned int>>();
884 return std::vector<std::pair<unsigned int, unsigned int>>();
896 template <
class PolynomialType,
int dim,
int spacedim>
899 const std::vector<
Point<1>> &points)
901 const std::vector<unsigned int> &index_map_inverse =
902 this->poly_space.get_numbering_inverse();
913 this->unit_support_points.resize(support_quadrature.
size());
914 for (
unsigned int k = 0; k < support_quadrature.
size(); ++k)
915 this->unit_support_points[index_map_inverse[k]] =
916 support_quadrature.
point(k);
921 template <
class PolynomialType,
int dim,
int spacedim>
924 const std::vector<
Point<1>> &points)
930 this->unit_face_support_points.resize(
931 Utilities::fixed_power<dim - 1>(q_degree + 1));
934 const std::vector<unsigned int> face_index_map =
935 internal::FE_Q_Base::face_lexicographic_to_hierarchic_numbering<dim>(
943 const Quadrature<dim - 1> support_quadrature(support_1d);
947 this->unit_face_support_points.resize(support_quadrature.size());
948 for (
unsigned int k = 0; k < support_quadrature.size(); ++k)
949 this->unit_face_support_points[face_index_map[k]] =
950 support_quadrature.point(k);
955 template <
class PolynomialType,
int dim,
int spacedim>
964 Assert(this->adjust_quad_dof_index_for_face_orientation_table.n_elements() ==
965 8 * this->dofs_per_quad,
968 const unsigned int n = q_degree - 1;
989 for (
unsigned int local = 0; local < this->dofs_per_quad; ++local)
993 unsigned int i = local % n, j = local / n;
996 this->adjust_quad_dof_index_for_face_orientation_table(local, 0) =
999 this->adjust_quad_dof_index_for_face_orientation_table(local, 1) =
1000 i + (n - 1 - j) * n - local;
1002 this->adjust_quad_dof_index_for_face_orientation_table(local, 2) =
1003 (n - 1 - j) + (n - 1 - i) * n - local;
1005 this->adjust_quad_dof_index_for_face_orientation_table(local, 3) =
1006 (n - 1 - i) + j * n - local;
1008 this->adjust_quad_dof_index_for_face_orientation_table(local, 4) = 0;
1010 this->adjust_quad_dof_index_for_face_orientation_table(local, 5) =
1011 j + (n - 1 - i) * n - local;
1013 this->adjust_quad_dof_index_for_face_orientation_table(local, 6) =
1014 (n - 1 - i) + (n - 1 - j) * n - local;
1016 this->adjust_quad_dof_index_for_face_orientation_table(local, 7) =
1017 (n - 1 - j) + i * n - local;
1021 for (
unsigned int i = 0; i < this->dofs_per_line; ++i)
1022 this->adjust_line_dof_index_for_line_orientation_table[i] =
1023 this->dofs_per_line - 1 - i - i;
1028 template <
class PolynomialType,
int dim,
int spacedim>
1031 const unsigned int face_index,
1032 const unsigned int face,
1033 const bool face_orientation,
1034 const bool face_flip,
1035 const bool face_rotation)
const 1037 Assert(face_index < this->dofs_per_face,
1053 if (face_index < this->first_face_line_index)
1058 const unsigned int face_vertex = face_index / this->dofs_per_vertex;
1059 const unsigned int dof_index_on_vertex =
1060 face_index % this->dofs_per_vertex;
1065 face, face_vertex, face_orientation, face_flip, face_rotation) *
1066 this->dofs_per_vertex +
1067 dof_index_on_vertex);
1069 else if (face_index < this->first_face_quad_index)
1074 const unsigned int index = face_index - this->first_face_line_index;
1076 const unsigned int face_line = index / this->dofs_per_line;
1077 const unsigned int dof_index_on_line = index % this->dofs_per_line;
1081 unsigned int adjusted_dof_index_on_line = 0;
1091 if (face_flip ==
false)
1092 adjusted_dof_index_on_line = dof_index_on_line;
1094 adjusted_dof_index_on_line =
1095 this->dofs_per_line - dof_index_on_line - 1;
1106 Assert((this->dofs_per_line <= 1) ||
1107 ((face_orientation ==
true) && (face_flip ==
false) &&
1108 (face_rotation ==
false)),
1110 adjusted_dof_index_on_line = dof_index_on_line;
1117 return (this->first_line_index +
1119 face, face_line, face_orientation, face_flip, face_rotation) *
1120 this->dofs_per_line +
1121 adjusted_dof_index_on_line);
1129 const unsigned int index = face_index - this->first_face_quad_index;
1134 Assert((this->dofs_per_quad <= 1) ||
1135 ((face_orientation ==
true) && (face_flip ==
false) &&
1136 (face_rotation ==
false)),
1138 return (this->first_quad_index + face * this->dofs_per_quad + index);
1144 template <
class PolynomialType,
int dim,
int spacedim>
1145 std::vector<unsigned int>
1147 const unsigned int degree)
1150 AssertThrow(degree > 0,
typename FEQ::ExcFEQCannotHaveDegree0());
1151 std::vector<unsigned int> dpo(dim + 1, 1U);
1152 for (
unsigned int i = 1; i < dpo.size(); ++i)
1153 dpo[i] = dpo[i - 1] * (degree - 1);
1159 template <
class PolynomialType,
int dim,
int spacedim>
1162 const std::vector<
Point<1>> &points)
1164 Implementation::initialize_constraints(points, *
this);
1169 template <
class PolynomialType,
int dim,
int spacedim>
1172 const unsigned int child,
1181 "Prolongation matrices are only available for refined cells!"));
1188 if (this->prolongation[refinement_case - 1][child].n() == 0)
1190 std::lock_guard<std::mutex> lock(this->mutex);
1193 if (this->prolongation[refinement_case - 1][child].n() ==
1194 this->dofs_per_cell)
1195 return this->prolongation[refinement_case - 1][child];
1198 const unsigned int q_dofs_per_cell =
1199 Utilities::fixed_power<dim>(q_degree + 1);
1207 const double eps = 1e-15 * q_degree * dim;
1212 for (
unsigned int i = 0; i < q_dofs_per_cell; ++i)
1214 Assert(std::fabs(1. - this->poly_space.compute_value(
1215 i, this->unit_support_points[i])) < eps,
1217 "to one or zero in a nodal point. " 1218 "This typically indicates that the " 1219 "polynomial interpolation is " 1220 "ill-conditioned such that round-off " 1221 "prevents the sum to be one."));
1222 for (
unsigned int j = 0; j < q_dofs_per_cell; ++j)
1224 Assert(std::fabs(this->poly_space.compute_value(
1225 i, this->unit_support_points[j])) < eps,
1227 "The Lagrange polynomial does not evaluate " 1228 "to one or zero in a nodal point. " 1229 "This typically indicates that the " 1230 "polynomial interpolation is " 1231 "ill-conditioned such that round-off " 1232 "prevents the sum to be one."));
1240 const unsigned int dofs1d = q_degree + 1;
1241 std::vector<Table<2, double>> subcell_evaluations(
1243 const std::vector<unsigned int> &index_map_inverse =
1244 this->poly_space.get_numbering_inverse();
1248 unsigned int step_size_diag = 0;
1250 unsigned int factor = 1;
1251 for (
unsigned int d = 0; d < dim; ++d)
1253 step_size_diag += factor;
1262 for (
unsigned int j = 0; j < dofs1d; ++j)
1264 const unsigned int diag_comp = index_map_inverse[j * step_size_diag];
1265 const Point<dim> p_subcell = this->unit_support_points[diag_comp];
1270 for (
unsigned int i = 0; i < dofs1d; ++i)
1271 for (
unsigned int d = 0; d < dim; ++d)
1275 point[0] = p_cell[d];
1276 const double cell_value =
1277 this->poly_space.compute_value(index_map_inverse[i], point);
1296 if (std::fabs(cell_value) < eps)
1297 subcell_evaluations[d](j, i) = 0;
1299 subcell_evaluations[d](j, i) = cell_value;
1305 unsigned int j_indices[dim];
1306 internal::FE_Q_Base::zero_indices<dim>(j_indices);
1307 for (
unsigned int j = 0; j < q_dofs_per_cell; j += dofs1d)
1309 unsigned int i_indices[dim];
1310 internal::FE_Q_Base::zero_indices<dim>(i_indices);
1311 for (
unsigned int i = 0; i < q_dofs_per_cell; i += dofs1d)
1313 double val_extra_dim = 1.;
1314 for (
unsigned int d = 1; d < dim; ++d)
1316 subcell_evaluations[d](j_indices[d - 1], i_indices[d - 1]);
1320 for (
unsigned int jj = 0; jj < dofs1d; ++jj)
1322 const unsigned int j_ind = index_map_inverse[j + jj];
1323 for (
unsigned int ii = 0; ii < dofs1d; ++ii)
1324 prolongate(j_ind, index_map_inverse[i + ii]) =
1325 val_extra_dim * subcell_evaluations[0](jj, ii);
1330 internal::FE_Q_Base::increment_indices<dim>(i_indices, dofs1d);
1333 internal::FE_Q_Base::increment_indices<dim>(j_indices, dofs1d);
1338 if (q_dofs_per_cell < this->dofs_per_cell)
1339 prolongate(q_dofs_per_cell, q_dofs_per_cell) = 1.;
1344 for (
unsigned int row = 0; row < this->dofs_per_cell; ++row)
1347 for (
unsigned int col = 0; col < this->dofs_per_cell; ++col)
1348 sum += prolongate(row, col);
1350 std::max(eps, 5e-16 * std::sqrt(this->dofs_per_cell)),
1352 "prolongation matrix do not add to one. " 1353 "This typically indicates that the " 1354 "polynomial interpolation is " 1355 "ill-conditioned such that round-off " 1356 "prevents the sum to be one."));
1362 this->prolongation[refinement_case - 1][child]));
1366 return this->prolongation[refinement_case - 1][child];
1371 template <
class PolynomialType,
int dim,
int spacedim>
1374 const unsigned int child,
1383 "Restriction matrices are only available for refined cells!"));
1390 if (this->restriction[refinement_case - 1][child].n() == 0)
1392 std::lock_guard<std::mutex> lock(this->mutex);
1395 if (this->restriction[refinement_case - 1][child].n() ==
1396 this->dofs_per_cell)
1397 return this->restriction[refinement_case - 1][child];
1400 this->dofs_per_cell);
1402 const unsigned int q_dofs_per_cell =
1403 Utilities::fixed_power<dim>(q_degree + 1);
1423 const double eps = 1e-15 * q_degree * dim;
1424 const std::vector<unsigned int> &index_map_inverse =
1425 this->poly_space.get_numbering_inverse();
1427 const unsigned int dofs1d = q_degree + 1;
1428 std::vector<Tensor<1, dim>> evaluations1d(dofs1d);
1430 my_restriction.
reinit(this->dofs_per_cell, this->dofs_per_cell);
1432 for (
unsigned int i = 0; i < q_dofs_per_cell; ++i)
1434 unsigned int mother_dof = index_map_inverse[i];
1435 const Point<dim> p_cell = this->unit_support_points[mother_dof];
1449 for (
unsigned int j = 0; j < dofs1d; ++j)
1450 for (
unsigned int d = 0; d < dim; ++d)
1453 point[0] = p_subcell[d];
1454 evaluations1d[j][d] =
1455 this->poly_space.compute_value(index_map_inverse[j],
1458 unsigned int j_indices[dim];
1459 internal::FE_Q_Base::zero_indices<dim>(j_indices);
1460 double sum_check = 0;
1461 for (
unsigned int j = 0; j < q_dofs_per_cell; j += dofs1d)
1463 double val_extra_dim = 1.;
1464 for (
unsigned int d = 1; d < dim; ++d)
1465 val_extra_dim *= evaluations1d[j_indices[d - 1]][d];
1466 for (
unsigned int jj = 0; jj < dofs1d; ++jj)
1474 const double val = val_extra_dim * evaluations1d[jj][0];
1475 const unsigned int child_dof = index_map_inverse[j + jj];
1476 if (std::fabs(val - 1.) < eps)
1477 my_restriction(mother_dof, child_dof) = 1.;
1478 else if (std::fabs(val) > eps)
1479 my_restriction(mother_dof, child_dof) = val;
1482 internal::FE_Q_Base::increment_indices<dim>(j_indices,
1485 Assert(std::fabs(sum_check - 1) <
1486 std::max(eps, 5e-16 * std::sqrt(this->dofs_per_cell)),
1488 "restriction matrix do not add to one. " 1489 "This typically indicates that the " 1490 "polynomial interpolation is " 1491 "ill-conditioned such that round-off " 1492 "prevents the sum to be one."));
1496 if (q_dofs_per_cell < this->dofs_per_cell)
1497 my_restriction(this->dofs_per_cell - 1, this->dofs_per_cell - 1) =
1505 this->restriction[refinement_case - 1][child]));
1508 return this->restriction[refinement_case - 1][child];
1518 template <
class PolynomialType,
int dim,
int spacedim>
1521 const unsigned int shape_index,
1522 const unsigned int face_index)
const 1524 Assert(shape_index < this->dofs_per_cell,
1533 return (((shape_index == 0) && (face_index == 0)) ||
1534 ((shape_index == 1) && (face_index == 1)));
1538 if (((dim == 2) && (shape_index >= this->first_quad_index)) ||
1539 ((dim == 3) && (shape_index >= this->first_hex_index)))
1543 if (shape_index < this->first_line_index)
1548 const unsigned int vertex_no = shape_index;
1552 for (
unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_face; ++v)
1559 else if (shape_index < this->first_quad_index)
1562 const unsigned int line_index =
1563 (shape_index - this->first_line_index) / this->dofs_per_line;
1569 return (line_index == face_index);
1573 const unsigned int lines_per_face =
1576 for (
unsigned int l = 0; l < lines_per_face; ++l)
1586 else if (shape_index < this->first_hex_index)
1589 const unsigned int quad_index =
1590 (shape_index - this->first_quad_index) / this->dofs_per_quad;
1591 Assert(static_cast<signed int>(quad_index) <
1601 return (quad_index == face_index);
1620 template <
typename PolynomialType,
int dim,
int spacedim>
1621 std::pair<Table<2, bool>, std::vector<unsigned int>>
1629 for (
unsigned int i = 0; i < Utilities::fixed_power<dim>(q_degree + 1); ++i)
1630 constant_modes(0, i) =
true;
1631 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
1632 constant_modes, std::vector<unsigned int>(1, 0));
1638 #include "fe_q_base.inst" 1640 DEAL_II_NAMESPACE_CLOSE
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)
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
FE_Q_Base(const PolynomialType &poly_space, const FiniteElementData< dim > &fe_data, const std::vector< bool > &restriction_is_additive_flags)
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const override
void swap(TableBase< N, T > &v)
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
static void initialize_constraints(const std::vector< Point< 1 >> &, FE_Q_Base< PolynomialType, 1, spacedim > &)
FullMatrix< double > interface_constraints
static void project_to_subface(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)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Task< RT > new_task(const std::function< RT()> &function)
const unsigned int degree
const Point< dim > & point(const unsigned int i) const
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
static Point< dim > cell_to_child_coordinates(const Point< dim > &p, const unsigned int child_index, const RefinementCase< dim > refine_case=RefinementCase< dim >::isotropic_refinement)
#define AssertThrow(cond, exc)
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
void initialize_unit_face_support_points(const std::vector< Point< 1 >> &points)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void initialize_unit_support_points(const std::vector< Point< 1 >> &points)
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const override
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false) const override
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
void initialize_constraints(const std::vector< Point< 1 >> &points)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< rank, dim, Number > sum(const SymmetricTensor< rank, dim, Number > &local, const MPI_Comm &mpi_communicator)
unsigned int size() const
const unsigned int dofs_per_cell
virtual bool hp_constraints_are_implemented() const override
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
void initialize(const std::vector< Point< 1 >> &support_points_1d)
static void project_to_face(const SubQuadrature &quadrature, const unsigned int face_no, std::vector< Point< dim >> &q_points)
void initialize_quad_dof_index_permutation()
const unsigned int dofs_per_face
static ::ExceptionBase & ExcNotImplemented()
PolynomialType poly_space
TableIndices< 2 > interface_constraints_size() const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const override
static ::ExceptionBase & ExcInternalError()