17 #include <deal.II/base/std_cxx14/memory.h> 19 #include <deal.II/fe/fe_nothing.h> 20 #include <deal.II/fe/fe_q_hierarchical.h> 30 DEAL_II_NAMESPACE_OPEN
41 inline std::vector<unsigned int>
42 invert_numbering(
const std::vector<unsigned int> &in)
44 std::vector<unsigned int> out(in.size());
45 for (
unsigned int i = 0; i < in.size(); ++i)
62 Polynomials::Hierarchical::generate_complete_basis(degree),
72 std::vector<bool>(1, true)))
73 , face_renumber(face_fe_q_hierarchical_to_hierarchic_numbering(degree))
92 std::vector<FullMatrix<double>> dofs_cell(
96 std::vector<FullMatrix<double>> dofs_subcell(
129 std::ostringstream namebuf;
130 namebuf <<
"FE_Q_Hierarchical<" << dim <<
">(" << this->
degree <<
")";
132 return namebuf.str();
138 std::unique_ptr<FiniteElement<dim, dim>>
141 return std_cxx14::make_unique<FE_Q_Hierarchical<dim>>(*this);
174 const std::vector<unsigned int> dof_map =
176 for (
unsigned int j = 0; j < dof_map.size(); j++)
177 matrix[dof_map[j]][j] = 1.;
182 const std::vector<unsigned int> dof_map =
183 source_fe->get_embedding_dofs(this->
degree);
184 for (
unsigned int j = 0; j < dof_map.size(); j++)
185 matrix[j][dof_map[j]] = 1.;
193 "Interpolation is supported only between FE_Q_Hierarchical"));
200 const unsigned int child,
206 "Prolongation matrices are only available for isotropic refinement!"));
226 std::vector<std::pair<unsigned int, unsigned int>>
240 return std::vector<std::pair<unsigned int, unsigned int>>(
241 1, std::make_pair(0U, 0U));
249 return std::vector<std::pair<unsigned int, unsigned int>>();
254 return std::vector<std::pair<unsigned int, unsigned int>>();
259 std::vector<std::pair<unsigned int, unsigned int>>
275 std::vector<std::pair<unsigned int, unsigned int>> res;
276 for (
unsigned int i = 0; i < std::min(this_dpl, other_dpl); i++)
277 res.emplace_back(i, i);
287 return std::vector<std::pair<unsigned int, unsigned int>>();
292 return std::vector<std::pair<unsigned int, unsigned int>>();
297 std::vector<std::pair<unsigned int, unsigned int>>
313 std::vector<std::pair<unsigned int, unsigned int>> res;
314 for (
unsigned int i = 0; i < std::min(this_dpq, other_dpq); i++)
315 res.emplace_back(i, i);
325 return std::vector<std::pair<unsigned int, unsigned int>>();
330 return std::vector<std::pair<unsigned int, unsigned int>>();
344 if (this->degree < fe_q_other->
degree)
346 else if (this->degree == fe_q_other->degree)
354 if (fe_nothing->is_dominating())
432 for (
unsigned int c = 0; c < GeometryInfo<1>::max_children_per_cell; ++c)
433 for (
unsigned int j = 0; j < dofs_1d; ++j)
434 for (
unsigned int k = 0; k < dofs_1d; ++k)
437 if ((j <= 1) && (k <= 1))
439 if (((c == 0) && (j == 0) && (k == 0)) ||
440 ((c == 1) && (j == 1) && (k == 1)))
441 dofs_cell[c](j, k) = 1.;
443 dofs_cell[c](j, k) = 0.;
445 if (((c == 0) && (j == 1)) || ((c == 1) && (j == 0)))
446 dofs_subcell[c](j, k) = .5;
447 else if (((c == 0) && (k == 0)) || ((c == 1) && (k == 1)))
448 dofs_subcell[c](j, k) = 1.;
450 dofs_subcell[c](j, k) = 0.;
453 else if ((j <= 1) && (k >= 2))
455 if (((c == 0) && (j == 1) && ((k % 2) == 0)) ||
456 ((c == 1) && (j == 0) && ((k % 2) == 0)))
457 dofs_subcell[c](j, k) = -1.;
460 else if ((j >= 2) && (k >= 2) && (j <= k))
463 for (
unsigned int i = 1; i <= j; ++i)
464 factor *= ((
double)(k - i + 1)) / ((double)i);
468 dofs_subcell[c](j, k) =
470 std::pow(.5, static_cast<double>(k)) * factor :
471 -std::pow(.5, static_cast<double>(k)) * factor;
473 std::pow(2., static_cast<double>(j)) * factor;
477 dofs_subcell[c](j, k) =
478 std::pow(.5, static_cast<double>(k)) * factor;
481 std::pow(2., static_cast<double>(j)) * factor :
482 -std::pow(2., static_cast<double>(j)) * factor;
511 for (
unsigned int i = 0; i < dofs_1d; ++i)
514 for (
unsigned int c = 0; c < GeometryInfo<1>::max_children_per_cell;
516 for (
unsigned int i = 0; i < dofs_1d; ++i)
517 for (
unsigned int j = 2; j < dofs_1d; ++j)
519 i) = dofs_subcell[c](j, i);
525 for (
unsigned int i = 0; i < dofs_1d * dofs_1d; i++)
529 dofs_subcell[0](1, i % dofs_1d) *
530 dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
534 dofs_subcell[0](0, i % dofs_1d) *
535 dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
537 dofs_subcell[1](1, i % dofs_1d) *
538 dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
540 dofs_subcell[0](1, i % dofs_1d) *
541 dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
543 dofs_subcell[1](0, i % dofs_1d) *
544 dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
547 for (
unsigned int j = 0; j < (this->
degree - 1); j++)
550 dofs_subcell[0](1, i % dofs_1d) *
551 dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
554 dofs_subcell[0](1, i % dofs_1d) *
555 dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
558 dofs_subcell[0](2 + j, i % dofs_1d) *
559 dofs_subcell[1](0, (i - (i % dofs_1d)) / dofs_1d);
562 dofs_subcell[1](2 + j, i % dofs_1d) *
563 dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
567 for (
unsigned int j = 0; j < (this->
degree - 1); j++)
572 dofs_subcell[0](0, i % dofs_1d) *
573 dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
577 dofs_subcell[0](0, i % dofs_1d) *
578 dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
581 2 * (this->
degree - 1) + j,
583 dofs_subcell[1](1, i % dofs_1d) *
584 dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
586 3 * (this->
degree - 1) + j,
588 dofs_subcell[1](1, i % dofs_1d) *
589 dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
592 4 * (this->
degree - 1) + j,
594 dofs_subcell[0](2 + j, i % dofs_1d) *
595 dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
597 5 * (this->
degree - 1) + j,
599 dofs_subcell[1](2 + j, i % dofs_1d) *
600 dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
603 6 * (this->
degree - 1) + j,
605 dofs_subcell[0](2 + j, i % dofs_1d) *
606 dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
608 7 * (this->
degree - 1) + j,
610 dofs_subcell[1](2 + j, i % dofs_1d) *
611 dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
615 for (
unsigned int j = 0; j < (this->
degree - 1); j++)
616 for (
unsigned int k = 0; k < (this->
degree - 1); k++)
620 j + k * (this->
degree - 1),
622 dofs_subcell[0](2 + j, i % dofs_1d) *
623 dofs_subcell[0](2 + k, (i - (i % dofs_1d)) / dofs_1d);
626 j + k * (this->
degree - 1) +
630 dofs_subcell[1](2 + j, i % dofs_1d) *
631 dofs_subcell[0](2 + k, (i - (i % dofs_1d)) / dofs_1d);
634 j + k * (this->
degree - 1) +
638 dofs_subcell[0](2 + j, i % dofs_1d) *
639 dofs_subcell[1](2 + k, (i - (i % dofs_1d)) / dofs_1d);
642 j + k * (this->
degree - 1) +
646 dofs_subcell[1](2 + j, i % dofs_1d) *
647 dofs_subcell[1](2 + k, (i - (i % dofs_1d)) / dofs_1d);
671 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell; ++c)
683 for (
unsigned int c = 0; c < GeometryInfo<dim>::max_children_per_cell;
708 for (
unsigned int c = 0;
709 c < GeometryInfo<2>::max_children_per_cell;
713 const unsigned int c0 = c % 2;
715 const unsigned int c1 = c / 2;
718 dofs_subcell[c0](renumber[j] % dofs_1d,
719 renumber[i] % dofs_1d) *
720 dofs_subcell[c1]((renumber[j] - (renumber[j] % dofs_1d)) /
722 (renumber[i] - (renumber[i] % dofs_1d)) /
726 dofs_cell[c0](renumber[j] % dofs_1d,
727 renumber[i] % dofs_1d) *
728 dofs_cell[c1]((renumber[j] - (renumber[j] % dofs_1d)) /
730 (renumber[i] - (renumber[i] % dofs_1d)) /
738 for (
unsigned int c = 0;
739 c < GeometryInfo<3>::max_children_per_cell;
743 const unsigned int c0 = c % 2;
745 const unsigned int c1 = (c % 4) / 2;
747 const unsigned int c2 = c / 4;
750 dofs_subcell[c0](renumber[j] % dofs_1d,
751 renumber[i] % dofs_1d) *
753 ((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) %
755 ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d) %
758 ((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d -
759 (((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) %
762 ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d -
763 (((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d) %
768 dofs_cell[c0](renumber[j] % dofs_1d,
769 renumber[i] % dofs_1d) *
771 ((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) %
773 ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d) %
776 ((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d -
777 (((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) %
780 ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d -
781 (((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d) %
800 unsigned int n = this->
degree + 1;
801 for (
unsigned int i = 1; i < dim; ++i)
806 const std::vector<unsigned int> &index_map_inverse =
838 for (
unsigned int iz = 0; iz <= ((dim > 2) ? this->
degree : 0); ++iz)
839 for (
unsigned int iy = 0; iy <= ((dim > 1) ? this->
degree : 0); ++iy)
840 for (
unsigned int ix = 0; ix <= this->
degree; ++ix)
913 (dynamic_cast<const FEQHierarchical *>(&x_source_fe) !=
942 interpolation_matrix = 0;
955 interpolation_matrix(i, i) = 1;
962 for (
unsigned int i = 0; i < GeometryInfo<3>::vertices_per_face; ++i)
963 interpolation_matrix(i, i) = 1;
965 for (
unsigned int i = 0; i < this->
degree - 1; ++i)
967 for (
unsigned int j = 0; j < GeometryInfo<3>::lines_per_face; ++j)
968 interpolation_matrix(i + j * (x_source_fe.
degree - 1) +
970 i + j * (this->degree - 1) +
973 for (
unsigned int j = 0; j < this->degree - 1; ++j)
975 (x_source_fe.
degree - 1) +
992 const unsigned int subface,
1000 (dynamic_cast<const FEQHierarchical *>(&x_source_fe) !=
1037 interpolation_matrix(0, 0) = 1.0;
1038 interpolation_matrix(1, 0) = 0.5;
1039 interpolation_matrix(1, 1) = 0.5;
1043 interpolation_matrix(1, dof) = -1.0;
1047 int factorial_i = 1;
1049 for (
int i = 2; i < (int)this->dofs_per_face; ++i)
1051 interpolation_matrix(i, i) = std::pow(0.5, i);
1053 int factorial_j = factorial_i;
1054 int factorial_ij = 1;
1056 for (
int j = i + 1; j < (int)this->dofs_per_face; ++j)
1058 factorial_ij *= j - i;
1062 interpolation_matrix(i, j) =
1063 -1.0 * std::pow(0.5, j) * factorial_j /
1064 (factorial_i * factorial_ij);
1067 interpolation_matrix(i, j) =
1068 std::pow(0.5, j) * factorial_j /
1069 (factorial_i * factorial_ij);
1078 interpolation_matrix(0, 0) = 0.5;
1079 interpolation_matrix(0, 1) = 0.5;
1083 interpolation_matrix(0, dof) = -1.0;
1087 interpolation_matrix(1, 1) = 1.0;
1089 int factorial_i = 1;
1091 for (
int i = 2; i < (int)this->dofs_per_face; ++i)
1093 interpolation_matrix(i, i) = std::pow(0.5, i);
1095 int factorial_j = factorial_i;
1096 int factorial_ij = 1;
1098 for (
int j = i + 1; j < (int)this->dofs_per_face; ++j)
1100 factorial_ij *= j - i;
1102 interpolation_matrix(i, j) =
1103 std::pow(0.5, j) * factorial_j /
1104 (factorial_i * factorial_ij);
1119 interpolation_matrix(0, 0) = 1.0;
1120 interpolation_matrix(1, 0) = 0.5;
1121 interpolation_matrix(1, 1) = 0.5;
1122 interpolation_matrix(2, 0) = 0.5;
1123 interpolation_matrix(2, 2) = 0.5;
1125 for (
unsigned int i = 0; i < this->
degree - 1;)
1127 for (
unsigned int line = 0;
1128 line < GeometryInfo<3>::lines_per_face;
1130 interpolation_matrix(3,
1131 i + line * (this->degree - 1) +
1134 for (
unsigned int j = 0; j < this->degree - 1;)
1136 interpolation_matrix(3,
1137 i + (j + 4) * this->degree - j) =
1142 interpolation_matrix(1, i + 2 * (this->degree + 1)) =
1144 interpolation_matrix(2, i + 4) = -1.0;
1148 for (
unsigned int vertex = 0;
1149 vertex < GeometryInfo<3>::vertices_per_face;
1151 interpolation_matrix(3, vertex) = 0.25;
1153 int factorial_i = 1;
1155 for (
int i = 2; i <= (int)this->degree; ++i)
1157 double tmp = std::pow(0.5, i);
1158 interpolation_matrix(i + 2, i + 2) = tmp;
1159 interpolation_matrix(i + 2 * source_fe.
degree,
1160 i + 2 * this->degree) = tmp;
1162 interpolation_matrix(i + source_fe.
degree + 1, i + 2) =
1164 interpolation_matrix(i + source_fe.
degree + 1,
1165 i + this->degree + 1) = tmp;
1166 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1167 i + 2 * this->degree) = tmp;
1168 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1169 i + 3 * this->degree - 1) = tmp;
1172 for (
unsigned int j = 0; j < this->degree - 1;)
1174 interpolation_matrix(i + source_fe.
degree + 1,
1175 (i + 2) * this->degree + j + 2 -
1177 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1178 i + (j + 4) * this->degree - j -
1183 int factorial_k = 1;
1185 for (
int j = 2; j <= (int)this->degree; ++j)
1187 interpolation_matrix(i + (j + 2) * source_fe.
degree -
1189 i + (j + 2) * this->degree - j) =
1190 std::pow(0.5, i + j);
1192 int factorial_kl = 1;
1193 int factorial_l = factorial_k;
1195 for (
int k = j + 1; k < (int)this->degree; ++k)
1197 factorial_kl *= k - j;
1201 interpolation_matrix(
1202 i + (j + 2) * source_fe.
degree - j,
1203 i + (k + 2) * this->degree - k) =
1204 -1.0 * std::pow(0.5, i + k) * factorial_l /
1205 (factorial_k * factorial_kl);
1208 interpolation_matrix(
1209 i + (j + 2) * source_fe.
degree - j,
1210 i + (k + 2) * this->degree - k) =
1211 std::pow(0.5, i + k) * factorial_l /
1212 (factorial_k * factorial_kl);
1217 int factorial_j = factorial_i;
1218 int factorial_ij = 1;
1220 for (
int j = i + 1; j <= (int)this->degree; ++j)
1222 factorial_ij *= j - i;
1227 tmp = -1.0 * std::pow(0.5, j) * factorial_j /
1228 (factorial_i * factorial_ij);
1229 interpolation_matrix(i + 2, j + 2) = tmp;
1230 interpolation_matrix(i + 2 * source_fe.
degree,
1231 j + 2 * this->degree) = tmp;
1234 for (
int k = 2; k <= (int)this->degree; ++k)
1236 interpolation_matrix(
1237 i + (k + 2) * source_fe.
degree - k,
1238 j + (k + 2) * this->degree - k) =
1239 tmp * std::pow(0.5, k);
1241 int factorial_l = factorial_k;
1242 int factorial_kl = 1;
1244 for (
int l = k + 1; l <= (int)this->degree;
1247 factorial_kl *= l - k;
1251 interpolation_matrix(
1252 i + (k + 2) * source_fe.
degree - k,
1253 j + (l + 2) * this->degree - l) =
1254 -1.0 * tmp * std::pow(0.5, l) *
1256 (factorial_k * factorial_kl);
1259 interpolation_matrix(
1260 i + (k + 2) * source_fe.
degree - k,
1261 j + (l + 2) * this->degree - l) =
1262 tmp * std::pow(0.5, l) * factorial_l /
1263 (factorial_k * factorial_kl);
1268 interpolation_matrix(i + source_fe.
degree + 1,
1270 interpolation_matrix(i + source_fe.
degree + 1,
1271 j + this->degree + 1) = tmp;
1272 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1273 j + 2 * this->degree) = tmp;
1274 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1275 j + 3 * this->degree - 1) =
1279 for (
unsigned int k = 0; k < this->degree - 1;)
1281 interpolation_matrix(i + source_fe.
degree + 1,
1282 (j + 2) * this->degree +
1284 interpolation_matrix(
1285 i + 3 * source_fe.
degree - 1,
1286 j + (k + 4) * this->degree - k - 2) = tmp;
1292 tmp = std::pow(0.5, j) * factorial_j /
1293 (factorial_i * factorial_ij);
1294 interpolation_matrix(i + 2, j + 2) = tmp;
1295 interpolation_matrix(i + 2 * source_fe.
degree,
1296 j + 2 * this->degree) = tmp;
1299 for (
int k = 2; k <= (int)this->degree; ++k)
1301 interpolation_matrix(
1302 i + (k + 2) * source_fe.
degree - k,
1303 j + (k + 2) * this->degree - k) =
1304 tmp * std::pow(0.5, k);
1306 int factorial_l = factorial_k;
1307 int factorial_kl = 1;
1309 for (
int l = k + 1; l <= (int)this->degree;
1312 factorial_kl *= l - k;
1316 interpolation_matrix(
1317 i + (k + 2) * source_fe.
degree - k,
1318 j + (l + 2) * this->degree - l) =
1319 -1.0 * tmp * std::pow(0.5, l) *
1321 (factorial_k * factorial_kl);
1324 interpolation_matrix(
1325 i + (k + 2) * source_fe.
degree - k,
1326 j + (l + 2) * this->degree - l) =
1327 tmp * std::pow(0.5, l) * factorial_l /
1328 (factorial_k * factorial_kl);
1333 interpolation_matrix(i + source_fe.
degree + 1,
1335 interpolation_matrix(i + source_fe.
degree + 1,
1336 j + this->degree + 1) = tmp;
1337 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1338 j + 2 * this->degree) = tmp;
1339 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1340 j + 3 * this->degree - 1) =
1344 for (
unsigned int k = 0; k < this->degree - 1;)
1346 interpolation_matrix(i + source_fe.
degree + 1,
1347 (j + 2) * this->degree +
1349 interpolation_matrix(
1350 i + 3 * source_fe.
degree - 1,
1351 j + (k + 4) * this->degree - k - 2) = tmp;
1363 interpolation_matrix(0, 0) = 0.5;
1364 interpolation_matrix(0, 1) = 0.5;
1365 interpolation_matrix(1, 1) = 1.0;
1366 interpolation_matrix(3, 1) = 0.5;
1367 interpolation_matrix(3, 3) = 0.5;
1369 for (
unsigned int i = 0; i < this->
degree - 1;)
1371 for (
unsigned int line = 0;
1372 line < GeometryInfo<3>::lines_per_face;
1374 interpolation_matrix(2,
1375 i + line * (this->degree - 1) +
1378 for (
unsigned int j = 0; j < this->degree - 1;)
1380 interpolation_matrix(2,
1381 i + (j + 4) * this->degree - j) =
1386 interpolation_matrix(0, i + 2 * (this->degree + 1)) =
1388 interpolation_matrix(3, i + this->degree + 3) = -1.0;
1392 for (
unsigned int vertex = 0;
1393 vertex < GeometryInfo<3>::vertices_per_face;
1395 interpolation_matrix(2, vertex) = 0.25;
1397 int factorial_i = 1;
1399 for (
int i = 2; i <= (int)this->degree; ++i)
1401 double tmp = std::pow(0.5, i + 1);
1402 interpolation_matrix(i + 2, i + 2) = tmp;
1403 interpolation_matrix(i + 2, i + this->degree + 1) = tmp;
1404 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1405 i + 2 * this->degree) = tmp;
1406 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1407 i + 3 * this->degree - 1) = tmp;
1410 for (
unsigned int j = 0; j < this->degree - 1;)
1412 interpolation_matrix(i + 2,
1413 j + (i + 2) * this->degree + 2 -
1415 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1416 i + (j + 4) * this->degree - j -
1422 interpolation_matrix(i + source_fe.
degree + 1,
1423 i + this->degree + 1) = tmp;
1424 interpolation_matrix(i + 2 * source_fe.
degree,
1425 i + 2 * this->degree) = tmp;
1427 int factorial_j = factorial_i;
1428 int factorial_ij = 1;
1430 for (
int j = i + 1; j <= (int)this->degree; ++j)
1432 factorial_ij *= j - i;
1434 tmp = std::pow(0.5, j) * factorial_j /
1435 (factorial_i * factorial_ij);
1436 interpolation_matrix(i + 2 * source_fe.
degree,
1437 j + 2 * this->degree) = tmp;
1438 int factorial_k = 1;
1440 for (
int k = 2; k <= (int)this->degree; ++k)
1442 interpolation_matrix(
1443 i + (k + 2) * source_fe.
degree - k,
1444 j + (k + 2) * this->degree - k) =
1445 tmp * std::pow(0.5, k);
1447 int factorial_l = factorial_k;
1448 int factorial_kl = 1;
1450 for (
int l = k + 1; l <= (int)this->degree; ++l)
1452 factorial_kl *= l - k;
1456 interpolation_matrix(
1457 i + (k + 2) * source_fe.
degree - k,
1458 j + (l + 2) * this->degree - l) =
1459 -1.0 * tmp * std::pow(0.5, l) *
1461 (factorial_k * factorial_kl);
1464 interpolation_matrix(
1465 i + (k + 2) * source_fe.
degree - k,
1466 j + (l + 2) * this->degree - l) =
1467 tmp * std::pow(0.5, l) * factorial_l /
1468 (factorial_k * factorial_kl);
1474 for (
unsigned int k = 0; k < this->degree - 1;)
1476 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1477 j + (k + 4) * this->degree -
1483 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1484 j + 2 * this->degree) = tmp;
1485 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1486 j + 3 * this->degree - 1) = tmp;
1491 interpolation_matrix(i + 2, j + 2) = tmp;
1492 interpolation_matrix(i + 2, j + this->degree + 1) =
1494 interpolation_matrix(i + source_fe.
degree + 1,
1495 j + this->degree + 1) =
1499 for (
unsigned int k = 0; k < this->degree - 1;)
1501 interpolation_matrix(i + 2,
1502 k + (j + 2) * this->degree +
1508 int factorial_k = 1;
1510 for (
int j = 2; j <= (int)this->degree; ++j)
1512 interpolation_matrix(i + (j + 2) * source_fe.
degree -
1514 i + (j + 2) * this->degree - j) =
1515 std::pow(0.5, i + j);
1517 int factorial_l = factorial_k;
1518 int factorial_kl = 1;
1520 for (
int k = j + 1; k <= (int)this->degree; ++k)
1522 factorial_kl *= k - j;
1526 interpolation_matrix(
1527 i + (j + 2) * source_fe.
degree - j,
1528 i + (k + 2) * this->degree - k) =
1529 -1.0 * std::pow(0.5, i + k) * factorial_l /
1530 (factorial_k * factorial_kl);
1533 interpolation_matrix(
1534 i + (j + 2) * source_fe.
degree - j,
1535 i + (k + 2) * this->degree - k) =
1536 std::pow(0.5, i + k) * factorial_l /
1537 (factorial_k * factorial_kl);
1547 interpolation_matrix(0, 0) = 0.5;
1548 interpolation_matrix(0, 2) = 0.5;
1549 interpolation_matrix(2, 2) = 1.0;
1550 interpolation_matrix(3, 2) = 0.5;
1551 interpolation_matrix(3, 3) = 0.5;
1553 for (
unsigned int i = 0; i < this->
degree - 1;)
1555 for (
unsigned int line = 0;
1556 line < GeometryInfo<3>::lines_per_face;
1558 interpolation_matrix(1,
1559 i + line * (this->degree - 1) +
1562 for (
unsigned int j = 0; j < this->degree - 1;)
1564 interpolation_matrix(1,
1565 i + (j + 4) * this->degree - j) =
1570 interpolation_matrix(0, i + 4) = -1.0;
1571 interpolation_matrix(3, i + 3 * this->degree + 1) = -1.0;
1575 for (
unsigned int vertex = 0;
1576 vertex < GeometryInfo<3>::vertices_per_face;
1578 interpolation_matrix(1, vertex) = 0.25;
1580 int factorial_i = 1;
1582 for (
int i = 2; i <= (int)this->degree; ++i)
1584 double tmp = std::pow(0.5, i);
1585 interpolation_matrix(i + 2, i + 2) = tmp;
1586 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1587 i + 3 * this->degree - 1) = tmp;
1589 interpolation_matrix(i + source_fe.
degree + 1, i + 2) =
1591 interpolation_matrix(i + source_fe.
degree + 1,
1592 i + this->degree + 1) = tmp;
1593 interpolation_matrix(i + 2 * source_fe.
degree,
1594 i + 2 * this->degree) = tmp;
1595 interpolation_matrix(i + 2 * source_fe.
degree,
1596 i + 3 * this->degree - 1) = tmp;
1599 for (
unsigned int j = 0; j < this->degree - 1;)
1601 interpolation_matrix(i + source_fe.
degree + 1,
1602 j + (i + 2) * this->degree + 2 -
1604 interpolation_matrix(i + 2 * source_fe.
degree,
1605 i + (j + 4) * this->degree - j -
1610 int factorial_k = 1;
1612 for (
int j = 2; j <= (int)this->degree; ++j)
1614 interpolation_matrix(i + (j + 2) * source_fe.
degree -
1616 i + (j + 2) * this->degree - j) =
1617 std::pow(0.5, i + j);
1619 int factorial_kl = 1;
1620 int factorial_l = factorial_k;
1622 for (
int k = j + 1; k <= (int)this->degree; ++k)
1624 factorial_kl *= k - j;
1626 interpolation_matrix(
1627 i + (j + 2) * source_fe.
degree - j,
1628 i + (k + 2) * this->degree - k) =
1629 std::pow(0.5, i + k) * factorial_l /
1630 (factorial_k * factorial_kl);
1635 int factorial_j = factorial_i;
1636 int factorial_ij = 1;
1638 for (
int j = i + 1; j <= (int)this->degree; ++j)
1640 factorial_ij *= j - i;
1642 tmp = std::pow(0.5, j) * factorial_j /
1643 (factorial_i * factorial_ij);
1644 interpolation_matrix(i + 2, j + 2) = tmp;
1647 for (
unsigned int k = 0; k < this->degree - 1;)
1649 interpolation_matrix(i + source_fe.
degree + 1,
1650 k + (j + 2) * this->degree +
1656 interpolation_matrix(i + source_fe.
degree + 1,
1658 interpolation_matrix(i + source_fe.
degree + 1,
1659 j + this->degree + 1) = tmp;
1664 interpolation_matrix(i + 2 * source_fe.
degree,
1665 j + 2 * this->degree) = tmp;
1666 interpolation_matrix(i + 2 * source_fe.
degree,
1667 j + 3 * this->degree - 1) = tmp;
1669 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1670 j + 3 * this->degree - 1) = tmp;
1671 int factorial_k = 1;
1673 for (
int k = 2; k <= (int)this->degree; ++k)
1675 interpolation_matrix(
1676 i + (k + 2) * source_fe.
degree - k,
1677 j + (k + 2) * this->degree - k) =
1678 tmp * std::pow(0.5, k);
1680 int factorial_l = factorial_k;
1681 int factorial_kl = 1;
1683 for (
int l = k + 1; l <= (int)this->degree; ++l)
1685 factorial_kl *= l - k;
1687 interpolation_matrix(
1688 i + (k + 2) * source_fe.
degree - k,
1689 j + (l + 2) * this->degree - l) =
1690 tmp * std::pow(0.5, l) * factorial_l /
1691 (factorial_k * factorial_kl);
1697 for (
unsigned int k = 0; k < this->degree - 1;)
1699 interpolation_matrix(i + 2 * source_fe.
degree,
1700 j + (k + 4) * this->degree -
1712 for (
unsigned int vertex = 0;
1713 vertex < GeometryInfo<3>::vertices_per_face;
1715 interpolation_matrix(0, vertex) = 0.25;
1717 for (
unsigned int i = 0; i < this->
degree - 1;)
1719 for (
unsigned int line = 0;
1720 line < GeometryInfo<3>::lines_per_face;
1722 interpolation_matrix(0,
1723 i + line * (this->degree - 1) +
1726 for (
unsigned int j = 0; j < this->degree - 1;)
1728 interpolation_matrix(0,
1729 i + (j + 4) * this->degree - j) =
1734 interpolation_matrix(1, i + 4) = -1.0;
1735 interpolation_matrix(2, i + 3 * this->degree + 1) = -1.0;
1739 interpolation_matrix(1, 0) = 0.5;
1740 interpolation_matrix(1, 1) = 0.5;
1741 interpolation_matrix(2, 2) = 0.5;
1742 interpolation_matrix(2, 3) = 0.5;
1743 interpolation_matrix(3, 3) = 1.0;
1745 int factorial_i = 1;
1747 for (
int i = 2; i <= (int)this->degree; ++i)
1749 double tmp = std::pow(0.5, i + 1);
1750 interpolation_matrix(i + 2, i + 2) = tmp;
1751 interpolation_matrix(i + 2, i + this->degree + 1) = tmp;
1752 interpolation_matrix(i + 2 * source_fe.
degree,
1753 i + 2 * this->degree) = tmp;
1754 interpolation_matrix(i + 2 * source_fe.
degree,
1755 i + 3 * this->degree - 1) = tmp;
1758 for (
unsigned int j = 0; j < this->degree - 1;)
1760 interpolation_matrix(i + 2,
1761 j + (i + 2) * this->degree + 2 -
1763 interpolation_matrix(i + 2 * source_fe.
degree,
1764 i + (j + 4) * this->degree - 2) =
1770 interpolation_matrix(i + source_fe.
degree + 1,
1771 i + this->degree + 1) = tmp;
1772 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1773 i + 3 * this->degree - 1) = tmp;
1774 int factorial_k = 1;
1776 for (
int j = 2; j <= (int)this->degree; ++j)
1778 interpolation_matrix(i + (j + 2) * source_fe.
degree -
1780 i + (j + 2) * this->degree - j) =
1781 std::pow(0.5, i + j);
1783 int factorial_l = factorial_k;
1784 int factorial_kl = 1;
1786 for (
int k = j + 1; k <= (int)this->degree; ++k)
1788 factorial_kl *= k - j;
1790 interpolation_matrix(
1791 i + (j + 2) * source_fe.
degree - j,
1792 i + (k + 2) * this->degree - k) =
1793 std::pow(0.5, i + k) * factorial_l /
1794 (factorial_k * factorial_kl);
1799 int factorial_j = factorial_i;
1800 int factorial_ij = 1;
1802 for (
int j = i + 1; j <= (int)this->degree; ++j)
1804 factorial_ij *= j - i;
1806 tmp = std::pow(0.5, j + 1) * factorial_j /
1807 (factorial_i * factorial_ij);
1808 interpolation_matrix(i + 2, j + 2) = tmp;
1809 interpolation_matrix(i + 2, j + this->degree + 1) =
1811 interpolation_matrix(i + 2 * source_fe.
degree,
1812 j + 2 * this->degree) = tmp;
1813 interpolation_matrix(i + 2 * source_fe.
degree,
1814 j + 3 * this->degree - 1) = tmp;
1816 interpolation_matrix(i + source_fe.
degree + 1,
1817 j + this->degree + 1) = tmp;
1818 interpolation_matrix(i + 3 * source_fe.
degree - 1,
1819 j + 3 * this->degree - 1) = tmp;
1820 int factorial_k = 1;
1822 for (
int k = 2; k <= (int)this->degree; ++k)
1824 interpolation_matrix(
1825 i + (k + 2) * source_fe.
degree - k,
1826 j + (k + 2) * this->degree - k) =
1827 tmp * std::pow(0.5, k);
1829 int factorial_l = factorial_k;
1830 int factorial_kl = 1;
1832 for (
int l = k + 1; l <= (int)this->degree; ++l)
1834 factorial_kl *= l - k;
1836 interpolation_matrix(
1837 i + (k + 2) * source_fe.
degree - k,
1838 j + (l + 2) * this->degree - l) =
1839 tmp * std::pow(0.5, l) * factorial_l /
1840 (factorial_k * factorial_kl);
1846 for (
unsigned int k = 0; k < this->degree - 1;)
1848 interpolation_matrix(i + 2,
1849 k + (j + 2) * this->degree +
1851 interpolation_matrix(i + 2 * source_fe.
degree,
1852 j + (k + 4) * this->degree -
1870 const unsigned int codim = dim - 1;
1873 unsigned int n = this->
degree + 1;
1874 for (
unsigned int i = 1; i < codim; ++i)
1882 for (
unsigned int iz = 0; iz <= ((codim > 2) ? this->
degree : 0); ++iz)
1883 for (
unsigned int iy = 0; iy <= ((codim > 1) ? this->
degree : 0); ++iy)
1884 for (
unsigned int ix = 0; ix <= this->
degree; ++ix)
1917 std::vector<unsigned int>
1920 std::vector<unsigned int> dpo(dim + 1, 1U);
1921 for (
unsigned int i = 1; i < dpo.size(); ++i)
1922 dpo[i] = dpo[i - 1] * (deg - 1);
1929 std::vector<unsigned int>
1940 const unsigned int n = degree + 1;
1979 unsigned int next_index = 0;
1981 h2l[next_index++] = 0;
1982 h2l[next_index++] = 1;
1983 h2l[next_index++] = n;
1984 h2l[next_index++] = n + 1;
1987 h2l[next_index++] = (2 + i) * n;
1990 h2l[next_index++] = (2 + i) * n + 1;
1993 h2l[next_index++] = 2 + i;
1996 h2l[next_index++] = n + 2 + i;
2002 h2l[next_index++] = (2 + i) * n + 2 + j;
2011 unsigned int next_index = 0;
2012 const unsigned int n2 = n * n;
2015 h2l[next_index++] = 0;
2016 h2l[next_index++] = 1;
2017 h2l[next_index++] = n;
2018 h2l[next_index++] = n + 1;
2020 h2l[next_index++] = n2;
2021 h2l[next_index++] = n2 + 1;
2022 h2l[next_index++] = n2 + n;
2023 h2l[next_index++] = n2 + n + 1;
2028 h2l[next_index++] = (2 + i) * n;
2030 h2l[next_index++] = (2 + i) * n + 1;
2032 h2l[next_index++] = 2 + i;
2034 h2l[next_index++] = n + 2 + i;
2037 h2l[next_index++] = n2 + (2 + i) * n;
2039 h2l[next_index++] = n2 + (2 + i) * n + 1;
2041 h2l[next_index++] = n2 + 2 + i;
2043 h2l[next_index++] = n2 + n + 2 + i;
2046 h2l[next_index++] = (2 + i) * n2;
2048 h2l[next_index++] = (2 + i) * n2 + 1;
2050 h2l[next_index++] = (2 + i) * n2 + n;
2052 h2l[next_index++] = (2 + i) * n2 + n + 1;
2060 h2l[next_index++] = (2 + i) * n2 + (2 + j) * n;
2064 h2l[next_index++] = (2 + i) * n2 + (2 + j) * n + 1;
2068 h2l[next_index++] = (2 + i) * n2 + 2 + j;
2072 h2l[next_index++] = (2 + i) * n2 + n + 2 + j;
2076 h2l[next_index++] = (2 + i) * n + 2 + j;
2080 h2l[next_index++] = n2 + (2 + i) * n + 2 + j;
2088 h2l[next_index++] = (2 + i) * n2 + (2 + j) * n + 2 + k;
2103 std::vector<unsigned int>
2105 const unsigned int degree)
2109 return internal::FE_Q_Hierarchical::invert_numbering(
2117 std::vector<unsigned int>
2121 return std::vector<unsigned int>();
2128 const unsigned int face_index)
const 2142 return (((shape_index == 0) && (face_index == 0)) ||
2143 ((shape_index == 1) && (face_index == 1)));
2151 const unsigned int face_index)
const 2175 const unsigned int vertex_no = shape_index;
2178 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_face; ++i)
2187 const unsigned int line_index =
2192 for (
unsigned int i = 0; i < GeometryInfo<dim>::lines_per_face; ++i)
2200 const unsigned int quad_index =
2202 Assert(static_cast<signed int>(quad_index) <
2215 return (quad_index == face_index);
2237 std::vector<unsigned int>
2240 Assert((sub_degree > 0) && (sub_degree <= this->
degree),
2245 std::vector<unsigned int> embedding_dofs(sub_degree + 1);
2246 for (
unsigned int i = 0; i < (sub_degree + 1); ++i)
2247 embedding_dofs[i] = i;
2249 return embedding_dofs;
2252 if (sub_degree == 1)
2254 std::vector<unsigned int> embedding_dofs(
2256 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
2257 embedding_dofs[i] = i;
2259 return embedding_dofs;
2261 else if (sub_degree == this->degree)
2263 std::vector<unsigned int> embedding_dofs(this->
dofs_per_cell);
2265 embedding_dofs[i] = i;
2267 return embedding_dofs;
2270 if ((dim == 2) || (dim == 3))
2272 std::vector<unsigned int> embedding_dofs(
2273 (dim == 2) ? (sub_degree + 1) * (sub_degree + 1) :
2274 (sub_degree + 1) * (sub_degree + 1) * (sub_degree + 1));
2276 for (
unsigned int i = 0;
2278 (sub_degree + 1) * (sub_degree + 1) :
2279 (sub_degree + 1) * (sub_degree + 1) * (sub_degree + 1));
2284 embedding_dofs[i] = i;
2289 const unsigned int j =
2291 const unsigned int line =
2296 line * (this->degree - 1) + j;
2304 const unsigned int j =
2308 const unsigned int k =
2313 const unsigned int face =
2316 k * (sub_degree - 1) - j) /
2317 ((sub_degree - 1) * (sub_degree - 1));
2322 face * (this->degree - 1) * (this->degree - 1) +
2323 k * (this->degree - 1) + j;
2331 (sub_degree - 1) * (sub_degree - 1))
2333 const unsigned int j =
2339 const unsigned int k =
2347 const unsigned int l =
2352 j - k * (sub_degree - 1)) /
2353 ((sub_degree - 1) * (sub_degree - 1));
2359 (this->degree - 1) +
2360 l * (this->degree - 1) * (this->degree - 1) +
2361 k * (this->degree - 1) + j;
2365 return embedding_dofs;
2370 return std::vector<unsigned int>();
2377 std::pair<Table<2, bool>, std::vector<unsigned int>>
2381 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
2382 constant_modes(0, i) =
true;
2386 constant_modes(0, i) =
false;
2387 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
2388 constant_modes, std::vector<unsigned int>(1, 0));
2404 #include "fe_q_hierarchical.inst" 2407 DEAL_II_NAMESPACE_CLOSE
const unsigned int first_hex_index
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
std::vector< std::vector< FullMatrix< double > > > restriction
std::vector< Point< dim > > generalized_support_points
FullMatrix< double > interface_constraints
void initialize_generalized_support_points()
const unsigned int dofs_per_quad
const unsigned int degree
void set_numbering(const std::vector< unsigned int > &renumber)
TableIndices< 2 > interface_constraints_size() const
const std::vector< unsigned int > face_renumber
#define AssertThrow(cond, exc)
void build_dofs_cell(std::vector< FullMatrix< double >> &dofs_cell, std::vector< FullMatrix< double >> &dofs_subcell) const
std::vector< Point< dim-1 > > generalized_face_support_points
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
const unsigned int dofs_per_line
const std::vector< unsigned int > & get_numbering_inverse() const
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const override
virtual void get_subface_interpolation_matrix(const FiniteElement< dim > &source, const unsigned int subface, FullMatrix< double > &matrix) const override
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim > &fe_other) const override
static::ExceptionBase & ExcMessage(std::string arg1)
static::ExceptionBase & ExcImpossibleInDim(int arg1)
const unsigned int first_quad_index
static std::vector< unsigned int > face_fe_q_hierarchical_to_hierarchic_numbering(const unsigned int degree)
std::vector< std::vector< FullMatrix< double > > > prolongation
const unsigned int dofs_per_hex
virtual std::string get_name() const override
#define Assert(cond, exc)
virtual void get_interpolation_matrix(const FiniteElement< dim > &source, FullMatrix< double > &matrix) const override
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim > &fe_other) const override
void initialize_constraints(const std::vector< FullMatrix< double >> &dofs_subcell)
virtual std::size_t memory_consumption() const override
virtual std::string get_name() const =0
std::vector< unsigned int > get_embedding_dofs(const unsigned int sub_degree) const
unsigned int n_components() const
virtual void get_face_interpolation_matrix(const FiniteElement< dim > &source, FullMatrix< double > &matrix) const override
const unsigned int dofs_per_cell
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim > &fe_other) const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim > &fe_other) const override
virtual std::unique_ptr< FiniteElement< dim, dim > > clone() const override
friend class FE_Q_Hierarchical
static std::vector< unsigned int > hierarchic_to_fe_q_hierarchical_numbering(const FiniteElementData< dim > &fe)
void initialize_embedding_and_restriction(const std::vector< FullMatrix< double >> &dofs_cell, const std::vector< FullMatrix< double >> &dofs_subcell)
const unsigned int dofs_per_face
const unsigned int first_line_index
static::ExceptionBase & ExcNotImplemented()
const unsigned int dofs_per_vertex
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
const std::vector< unsigned int > & get_numbering() const
TensorProductPolynomials< dim > poly_space
void initialize_generalized_face_support_points()
virtual bool hp_constraints_are_implemented() const override
static::ExceptionBase & ExcInternalError()