321 static const int c_swap_table_0 = 0;
323 static const int c_swap_table_1[8][3][2] = {
349 static const int c_swap_table_2[8][3][6] = {
350 {{-1, -1, -1, -1, -1, -1},
359 {{-1, -1, -1, -1, -1, -1},
362 {{-1, -1, -1, -1, -1, -1},
371 {{-1, -1, -1, -1, -1, -1},
373 {0, 0, 0, 1, 1, 1}}};
375 static const int c_swap_table_3[8][3][12] = {
377 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
378 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
379 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
380 {{0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11},
381 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
382 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
383 {{0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11},
384 {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0},
385 {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}},
386 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
387 {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0},
388 {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}},
389 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
390 {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
391 {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0}},
392 {{0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11},
393 {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
394 {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0}},
395 {{0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11},
396 {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0},
397 {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}},
398 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
399 {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0},
400 {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}}};
402 static const int c_swap_table_4[8][3][20] = {
406 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
407 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
408 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
409 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
410 {{0, 5, 10, 15, 1, 6, 11, 16, 2, 7,
411 12, 17, 3, 8, 13, 18, 4, 9, 14, 19},
412 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
413 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
414 {{0, 5, 10, 15, 1, 6, 11, 16, 2, 7,
415 12, 17, 3, 8, 13, 18, 4, 9, 14, 19},
416 {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1},
417 {1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1}},
418 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
419 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
420 {1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1},
421 {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}},
422 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
423 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
424 {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
425 {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0}},
426 {{0, 5, 10, 15, 1, 6, 11, 16, 2, 7,
427 12, 17, 3, 8, 13, 18, 4, 9, 14, 19},
428 {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
429 {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0}},
430 {{0, 5, 10, 15, 1, 6, 11, 16, 2, 7,
431 12, 17, 3, 8, 13, 18, 4, 9, 14, 19},
432 {1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1},
433 {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}},
434 {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
435 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
436 {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1},
437 {1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1}}};
439 static const int *swap_table_array[5] = {&c_swap_table_0,
440 &c_swap_table_1[0][0][0],
441 &c_swap_table_2[0][0][0],
442 &c_swap_table_3[0][0][0],
443 &c_swap_table_4[0][0][0]};
445 static const int row_length[5] = {0, 2, 6, 12, 20};
446 static const int table_size[5] = {
447 0, 8 * 3 * 2, 8 * 3 * 6, 8 * 3 * 12, 8 * 3 * 20};
459 const unsigned int k = this->tensor_degree() - 1;
471 const unsigned int face_no = 0;
474 this->adjust_quad_dof_index_for_face_orientation_table[0].n_elements() ==
475 this->reference_cell().n_face_orientations(face_no) *
476 this->n_dofs_per_quad(face_no),
480 this->adjust_quad_dof_sign_for_face_orientation_table[0].n_elements() ==
481 this->reference_cell().n_face_orientations(face_no) *
482 this->n_dofs_per_quad(face_no),
488 const int *swap_table = swap_table_array[k];
490 const unsigned int half_dofs = k * (k + 1);
492 const int rl = row_length[k];
494 combined_orientation <
495 this->reference_cell().n_face_orientations(face_no);
496 ++combined_orientation)
506 for (
unsigned int index_x = 0; index_x < half_dofs; index_x++)
508 int offset = 3 * rl * combined_orientation + 0 * rl + index_x;
510 int value = *(swap_table + offset);
516 const unsigned int index_y =
517 half_dofs +
static_cast<unsigned int>(value);
520 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
521 index_x, combined_orientation) = index_y - index_x;
523 this->adjust_quad_dof_index_for_face_orientation_table[face_no](
524 index_y, combined_orientation) = index_x - index_y;
528 offset = 3 * rl * combined_orientation + 1 * rl + index_x;
530 value = *(swap_table + offset);
533 this->adjust_quad_dof_sign_for_face_orientation_table[face_no](
534 index_x, combined_orientation) =
static_cast<bool>(value);
537 offset = 3 * rl * combined_orientation + 2 * rl + index_x;
539 value = *(swap_table + offset);
542 this->adjust_quad_dof_sign_for_face_orientation_table[face_no](
543 index_x + half_dofs, combined_orientation) =
544 static_cast<bool>(value);
897 const QGauss<1> edge_quadrature(2 * this->degree);
898 const std::vector<Point<1>> &edge_quadrature_points =
899 edge_quadrature.get_points();
900 const unsigned int n_edge_quadrature_points = edge_quadrature.size();
911 for (
unsigned int dof = 0; dof < this->n_dofs_per_cell(); ++dof)
912 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
915 const double weight = 2.0 * edge_quadrature.weight(q_point);
917 if (edge_quadrature_points[q_point][0] < 0.5)
920 0.0, 2.0 * edge_quadrature_points[q_point][0]);
922 this->restriction[index][0](0, dof) +=
924 this->shape_value_component(dof, quadrature_point, 1);
925 quadrature_point[0] = 1.0;
926 this->restriction[index][1](this->degree, dof) +=
928 this->shape_value_component(dof, quadrature_point, 1);
929 quadrature_point[0] = quadrature_point[1];
930 quadrature_point[1] = 0.0;
931 this->restriction[index][0](2 * this->degree, dof) +=
933 this->shape_value_component(dof, quadrature_point, 0);
934 quadrature_point[1] = 1.0;
935 this->restriction[index][2](3 * this->degree, dof) +=
937 this->shape_value_component(dof, quadrature_point, 0);
943 0.0, 2.0 * edge_quadrature_points[q_point][0] - 1.0);
945 this->restriction[index][2](0, dof) +=
947 this->shape_value_component(dof, quadrature_point, 1);
948 quadrature_point[0] = 1.0;
949 this->restriction[index][3](this->degree, dof) +=
951 this->shape_value_component(dof, quadrature_point, 1);
952 quadrature_point[0] = quadrature_point[1];
953 quadrature_point[1] = 0.0;
954 this->restriction[index][1](2 * this->degree, dof) +=
956 this->shape_value_component(dof, quadrature_point, 0);
957 quadrature_point[1] = 1.0;
958 this->restriction[index][3](3 * this->degree, dof) +=
960 this->shape_value_component(dof, quadrature_point, 0);
968 if (this->degree > 1)
970 const unsigned int deg = this->degree - 1;
971 const std::vector<Polynomials::Polynomial<double>>
972 &legendre_polynomials =
978 n_edge_quadrature_points);
980 for (
unsigned int q_point = 0;
981 q_point < n_edge_quadrature_points;
984 const double weight =
985 std::sqrt(edge_quadrature.weight(q_point));
987 for (
unsigned int i = 0; i < deg; ++i)
988 assembling_matrix(i, q_point) =
989 weight * legendre_polynomials[i + 1].value(
990 edge_quadrature_points[q_point][0]);
995 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
996 system_matrix_inv.
invert(system_matrix);
1003 for (
unsigned int dof = 0; dof < this->n_dofs_per_cell(); ++dof)
1004 for (
unsigned int i = 0; i < 2; ++i)
1008 for (
unsigned int q_point = 0;
1009 q_point < n_edge_quadrature_points;
1012 const double weight = edge_quadrature.weight(q_point);
1014 i, edge_quadrature_points[q_point][0]);
1016 edge_quadrature_points[q_point][0], i);
1018 if (edge_quadrature_points[q_point][0] < 0.5)
1021 i, 2.0 * edge_quadrature_points[q_point][0]);
1025 (2.0 * this->shape_value_component(
1026 dof, quadrature_point_2, 1) -
1027 this->restriction[index][i](i * this->degree,
1029 this->shape_value_component(i * this->degree,
1034 this->restriction[index][i + 2](i * this->degree,
1036 this->shape_value_component(i * this->degree,
1040 2.0 * edge_quadrature_points[q_point][0], i);
1043 (2.0 * this->shape_value_component(
1044 dof, quadrature_point_2, 0) -
1045 this->restriction[index][2 * i]((i + 2) *
1048 this->shape_value_component((i + 2) *
1054 this->restriction[index][2 * i + 1](
1055 (i + 2) * this->degree, dof) *
1056 this->shape_value_component(
1057 (i + 2) * this->degree, quadrature_point_1, 0);
1064 this->restriction[index][i](i * this->degree,
1066 this->shape_value_component(i * this->degree,
1072 2.0 * edge_quadrature_points[q_point][0] - 1.0);
1076 (2.0 * this->shape_value_component(
1077 dof, quadrature_point_2, 1) -
1078 this->restriction[index][i + 2](i * this->degree,
1080 this->shape_value_component(i * this->degree,
1085 this->restriction[index][2 * i]((i + 2) *
1088 this->shape_value_component(
1089 (i + 2) * this->degree, quadrature_point_1, 0);
1091 2.0 * edge_quadrature_points[q_point][0] - 1.0,
1095 (2.0 * this->shape_value_component(
1096 dof, quadrature_point_2, 0) -
1097 this->restriction[index][2 * i + 1](
1098 (i + 2) * this->degree, dof) *
1099 this->shape_value_component((i + 2) *
1105 for (
unsigned int j = 0; j < this->degree - 1; ++j)
1108 legendre_polynomials[j + 1].value(
1109 edge_quadrature_points[q_point][0]);
1111 for (
unsigned int k = 0; k < tmp.
size(); ++k)
1112 system_rhs(j, k) += tmp(k) * L_j;
1116 system_matrix_inv.
mmult(solution, system_rhs);
1118 for (
unsigned int j = 0; j < this->degree - 1; ++j)
1119 for (
unsigned int k = 0; k < 2; ++k)
1121 if (
std::abs(solution(j, k)) > 1e-14)
1122 this->restriction[index][i + 2 * k](
1123 i * this->degree + j + 1, dof) = solution(j, k);
1125 if (
std::abs(solution(j, k + 2)) > 1e-14)
1126 this->restriction[index][2 * i + k](
1127 (i + 2) * this->degree + j + 1, dof) =
1133 const std::vector<Point<dim>> &quadrature_points =
1134 quadrature.get_points();
1135 const std::vector<Polynomials::Polynomial<double>>
1136 &lobatto_polynomials =
1138 const unsigned int n_boundary_dofs =
1140 const unsigned int n_quadrature_points = quadrature.size();
1145 n_quadrature_points);
1147 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
1150 const double weight =
std::sqrt(quadrature.weight(q_point));
1152 for (
unsigned int i = 0; i < this->degree; ++i)
1155 weight * legendre_polynomials[i].value(
1156 quadrature_points[q_point][0]);
1158 for (
unsigned int j = 0; j < this->degree - 1; ++j)
1159 assembling_matrix(i * (this->degree - 1) + j,
1161 L_i * lobatto_polynomials[j + 2].value(
1162 quadrature_points[q_point][1]);
1167 assembling_matrix.
m());
1169 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
1170 system_matrix_inv.reinit(system_matrix.
m(), system_matrix.
m());
1171 system_matrix_inv.
invert(system_matrix);
1174 solution.reinit(system_matrix_inv.
m(), 8);
1175 system_rhs.reinit(system_matrix_inv.
m(), 8);
1178 for (
unsigned int dof = 0; dof < this->n_dofs_per_cell(); ++dof)
1182 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
1187 if (quadrature_points[q_point][0] < 0.5)
1189 if (quadrature_points[q_point][1] < 0.5)
1192 2.0 * quadrature_points[q_point][0],
1193 2.0 * quadrature_points[q_point][1]);
1195 tmp(0) += 2.0 * this->shape_value_component(
1196 dof, quadrature_point, 0);
1197 tmp(1) += 2.0 * this->shape_value_component(
1198 dof, quadrature_point, 1);
1204 2.0 * quadrature_points[q_point][0],
1205 2.0 * quadrature_points[q_point][1] - 1.0);
1207 tmp(4) += 2.0 * this->shape_value_component(
1208 dof, quadrature_point, 0);
1209 tmp(5) += 2.0 * this->shape_value_component(
1210 dof, quadrature_point, 1);
1214 else if (quadrature_points[q_point][1] < 0.5)
1217 2.0 * quadrature_points[q_point][0] - 1.0,
1218 2.0 * quadrature_points[q_point][1]);
1221 2.0 * this->shape_value_component(dof,
1225 2.0 * this->shape_value_component(dof,
1233 2.0 * quadrature_points[q_point][0] - 1.0,
1234 2.0 * quadrature_points[q_point][1] - 1.0);
1237 2.0 * this->shape_value_component(dof,
1241 2.0 * this->shape_value_component(dof,
1246 for (
unsigned int i = 0; i < 2; ++i)
1247 for (
unsigned int j = 0; j < this->degree; ++j)
1250 this->restriction[index][i](j + 2 * this->degree,
1252 this->shape_value_component(
1253 j + 2 * this->degree,
1254 quadrature_points[q_point],
1257 this->restriction[index][i](i * this->degree + j,
1259 this->shape_value_component(
1260 i * this->degree + j,
1261 quadrature_points[q_point],
1263 tmp(2 * (i + 2)) -= this->restriction[index][i + 2](
1264 j + 3 * this->degree, dof) *
1265 this->shape_value_component(
1266 j + 3 * this->degree,
1267 quadrature_points[q_point],
1269 tmp(2 * i + 5) -= this->restriction[index][i + 2](
1270 i * this->degree + j, dof) *
1271 this->shape_value_component(
1272 i * this->degree + j,
1273 quadrature_points[q_point],
1277 tmp *= quadrature.weight(q_point);
1279 for (
unsigned int i = 0; i < this->degree; ++i)
1281 const double L_i_0 = legendre_polynomials[i].value(
1282 quadrature_points[q_point][0]);
1283 const double L_i_1 = legendre_polynomials[i].value(
1284 quadrature_points[q_point][1]);
1286 for (
unsigned int j = 0; j < this->degree - 1; ++j)
1288 const double l_j_0 =
1289 L_i_0 * lobatto_polynomials[j + 2].value(
1290 quadrature_points[q_point][1]);
1291 const double l_j_1 =
1292 L_i_1 * lobatto_polynomials[j + 2].value(
1293 quadrature_points[q_point][0]);
1295 for (
unsigned int k = 0; k < 4; ++k)
1297 system_rhs(i * (this->degree - 1) + j,
1298 2 * k) += tmp(2 * k) * l_j_0;
1299 system_rhs(i * (this->degree - 1) + j,
1301 tmp(2 * k + 1) * l_j_1;
1307 system_matrix_inv.
mmult(solution, system_rhs);
1309 for (
unsigned int i = 0; i < this->degree; ++i)
1310 for (
unsigned int j = 0; j < this->degree - 1; ++j)
1311 for (
unsigned int k = 0; k < 4; ++k)
1313 if (
std::abs(solution(i * (this->degree - 1) + j,
1315 this->restriction[index][k](i * (this->degree - 1) +
1316 j + n_boundary_dofs,
1318 solution(i * (this->degree - 1) + j, 2 * k);
1320 if (
std::abs(solution(i * (this->degree - 1) + j,
1321 2 * k + 1)) > 1e-14)
1322 this->restriction[index][k](
1323 i + (this->degree - 1 + j) * this->degree +
1326 solution(i * (this->degree - 1) + j, 2 * k + 1);
1340 for (
unsigned int dof = 0; dof < this->n_dofs_per_cell(); ++dof)
1341 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
1344 const double weight = 2.0 * edge_quadrature.weight(q_point);
1346 if (edge_quadrature_points[q_point][0] < 0.5)
1347 for (
unsigned int i = 0; i < 2; ++i)
1348 for (
unsigned int j = 0; j < 2; ++j)
1351 i, 2.0 * edge_quadrature_points[q_point][0], j);
1353 this->restriction[index][i + 4 * j]((i + 4 * j) *
1357 this->shape_value_component(dof, quadrature_point, 1);
1359 Point<dim>(2.0 * edge_quadrature_points[q_point][0],
1362 this->restriction[index][2 * (i + 2 * j)](
1363 (i + 4 * j + 2) * this->degree, dof) +=
1365 this->shape_value_component(dof, quadrature_point, 0);
1369 2.0 * edge_quadrature_points[q_point][0]);
1370 this->restriction[index][i + 2 * j]((i + 2 * (j + 4)) *
1374 this->shape_value_component(dof, quadrature_point, 2);
1378 for (
unsigned int i = 0; i < 2; ++i)
1379 for (
unsigned int j = 0; j < 2; ++j)
1382 i, 2.0 * edge_quadrature_points[q_point][0] - 1.0, j);
1384 this->restriction[index][i + 4 * j + 2]((i + 4 * j) *
1388 this->shape_value_component(dof, quadrature_point, 1);
1390 2.0 * edge_quadrature_points[q_point][0] - 1.0, i, j);
1391 this->restriction[index][2 * (i + 2 * j) + 1](
1392 (i + 4 * j + 2) * this->degree, dof) +=
1394 this->shape_value_component(dof, quadrature_point, 0);
1396 i, j, 2.0 * edge_quadrature_points[q_point][0] - 1.0);
1397 this->restriction[index][i + 2 * (j + 2)](
1398 (i + 2 * (j + 4)) * this->degree, dof) +=
1400 this->shape_value_component(dof, quadrature_point, 2);
1408 if (this->degree > 1)
1410 const unsigned int deg = this->degree - 1;
1411 const std::vector<Polynomials::Polynomial<double>>
1412 &legendre_polynomials =
1418 n_edge_quadrature_points);
1420 for (
unsigned int q_point = 0;
1421 q_point < n_edge_quadrature_points;
1424 const double weight =
1425 std::sqrt(edge_quadrature.weight(q_point));
1427 for (
unsigned int i = 0; i < deg; ++i)
1428 assembling_matrix(i, q_point) =
1429 weight * legendre_polynomials[i + 1].value(
1430 edge_quadrature_points[q_point][0]);
1435 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
1436 system_matrix_inv.
invert(system_matrix);
1443 for (
unsigned int i = 0; i < 2; ++i)
1444 for (
unsigned int j = 0; j < 2; ++j)
1445 for (
unsigned int dof = 0; dof < this->n_dofs_per_cell();
1450 for (
unsigned int q_point = 0;
1451 q_point < n_edge_quadrature_points;
1454 const double weight = edge_quadrature.weight(q_point);
1456 i, edge_quadrature_points[q_point][0], j);
1458 edge_quadrature_points[q_point][0], i, j);
1460 i, j, edge_quadrature_points[q_point][0]);
1462 if (edge_quadrature_points[q_point][0] < 0.5)
1465 i, 2.0 * edge_quadrature_points[q_point][0], j);
1468 weight * (2.0 * this->shape_value_component(
1469 dof, quadrature_point_3, 1) -
1470 this->restriction[index][i + 4 * j](
1471 (i + 4 * j) * this->degree, dof) *
1472 this->shape_value_component(
1473 (i + 4 * j) * this->degree,
1478 this->restriction[index][i + 4 * j + 2](
1479 (i + 4 * j) * this->degree, dof) *
1480 this->shape_value_component((i + 4 * j) *
1485 2.0 * edge_quadrature_points[q_point][0], i, j);
1488 (2.0 * this->shape_value_component(
1489 dof, quadrature_point_3, 0) -
1490 this->restriction[index][2 * (i + 2 * j)](
1491 (i + 4 * j + 2) * this->degree, dof) *
1492 this->shape_value_component(
1493 (i + 4 * j + 2) * this->degree,
1498 this->restriction[index][2 * (i + 2 * j) + 1](
1499 (i + 4 * j + 2) * this->degree, dof) *
1500 this->shape_value_component((i + 4 * j + 2) *
1505 i, j, 2.0 * edge_quadrature_points[q_point][0]);
1508 (2.0 * this->shape_value_component(
1509 dof, quadrature_point_3, 2) -
1510 this->restriction[index][i + 2 * j](
1511 (i + 2 * (j + 4)) * this->degree, dof) *
1512 this->shape_value_component(
1513 (i + 2 * (j + 4)) * this->degree,
1518 this->restriction[index][i + 2 * (j + 2)](
1519 (i + 2 * (j + 4)) * this->degree, dof) *
1520 this->shape_value_component((i + 2 * (j + 4)) *
1530 this->restriction[index][i + 4 * j](
1531 (i + 4 * j) * this->degree, dof) *
1532 this->shape_value_component((i + 4 * j) *
1539 2.0 * edge_quadrature_points[q_point][0] - 1.0,
1543 (2.0 * this->shape_value_component(
1544 dof, quadrature_point_3, 1) -
1545 this->restriction[index][i + 4 * j + 2](
1546 (i + 4 * j) * this->degree, dof) *
1547 this->shape_value_component(
1548 (i + 4 * j) * this->degree,
1553 this->restriction[index][2 * (i + 2 * j)](
1554 (i + 4 * j + 2) * this->degree, dof) *
1555 this->shape_value_component((i + 4 * j + 2) *
1560 2.0 * edge_quadrature_points[q_point][0] - 1.0,
1565 (2.0 * this->shape_value_component(
1566 dof, quadrature_point_3, 0) -
1567 this->restriction[index][2 * (i + 2 * j) + 1](
1568 (i + 4 * j + 2) * this->degree, dof) *
1569 this->shape_value_component(
1570 (i + 4 * j + 2) * this->degree,
1575 this->restriction[index][i + 2 * j](
1576 (i + 2 * (j + 4)) * this->degree, dof) *
1577 this->shape_value_component((i + 2 * (j + 4)) *
1584 2.0 * edge_quadrature_points[q_point][0] - 1.0);
1587 (2.0 * this->shape_value_component(
1588 dof, quadrature_point_3, 2) -
1589 this->restriction[index][i + 2 * (j + 2)](
1590 (i + 2 * (j + 4)) * this->degree, dof) *
1591 this->shape_value_component(
1592 (i + 2 * (j + 4)) * this->degree,
1597 for (
unsigned int k = 0; k < deg; ++k)
1600 legendre_polynomials[k + 1].value(
1601 edge_quadrature_points[q_point][0]);
1603 for (
unsigned int l = 0; l < tmp.
size(); ++l)
1604 system_rhs(k, l) += tmp(l) * L_k;
1608 system_matrix_inv.
mmult(solution, system_rhs);
1610 for (
unsigned int k = 0; k < 2; ++k)
1611 for (
unsigned int l = 0; l < deg; ++l)
1613 if (
std::abs(solution(l, k)) > 1e-14)
1614 this->restriction[index][i + 2 * (2 * j + k)](
1615 (i + 4 * j) * this->degree + l + 1, dof) =
1618 if (
std::abs(solution(l, k + 2)) > 1e-14)
1619 this->restriction[index][2 * (i + 2 * j) + k](
1620 (i + 4 * j + 2) * this->degree + l + 1, dof) =
1623 if (
std::abs(solution(l, k + 4)) > 1e-14)
1624 this->restriction[index][i + 2 * (j + 2 * k)](
1625 (i + 2 * (j + 4)) * this->degree + l + 1, dof) =
1630 const QGauss<2> face_quadrature(2 * this->degree);
1631 const std::vector<Point<2>> &face_quadrature_points =
1632 face_quadrature.get_points();
1633 const std::vector<Polynomials::Polynomial<double>>
1634 &lobatto_polynomials =
1636 const unsigned int n_edge_dofs =
1638 const unsigned int n_face_quadrature_points =
1639 face_quadrature.size();
1643 n_face_quadrature_points);
1645 for (
unsigned int q_point = 0;
1646 q_point < n_face_quadrature_points;
1649 const double weight =
1650 std::sqrt(face_quadrature.weight(q_point));
1652 for (
unsigned int i = 0; i <= deg; ++i)
1655 weight * legendre_polynomials[i].value(
1656 face_quadrature_points[q_point][0]);
1658 for (
unsigned int j = 0; j < deg; ++j)
1659 assembling_matrix(i * deg + j, q_point) =
1660 L_i * lobatto_polynomials[j + 2].value(
1661 face_quadrature_points[q_point][1]);
1666 assembling_matrix.
m());
1668 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
1669 system_matrix_inv.reinit(system_matrix.
m(), system_matrix.
m());
1670 system_matrix_inv.
invert(system_matrix);
1673 solution.reinit(system_matrix_inv.
m(), 24);
1674 system_rhs.reinit(system_matrix_inv.
m(), 24);
1677 for (
unsigned int i = 0; i < 2; ++i)
1678 for (
unsigned int dof = 0; dof < this->n_dofs_per_cell(); ++dof)
1682 for (
unsigned int q_point = 0;
1683 q_point < n_face_quadrature_points;
1688 if (face_quadrature_points[q_point][0] < 0.5)
1690 if (face_quadrature_points[q_point][1] < 0.5)
1694 2.0 * face_quadrature_points[q_point][0],
1695 2.0 * face_quadrature_points[q_point][1]);
1697 tmp(0) += 2.0 * this->shape_value_component(
1698 dof, quadrature_point_0, 1);
1699 tmp(1) += 2.0 * this->shape_value_component(
1700 dof, quadrature_point_0, 2);
1702 2.0 * face_quadrature_points[q_point][0],
1704 2.0 * face_quadrature_points[q_point][1]);
1705 tmp(8) += 2.0 * this->shape_value_component(
1706 dof, quadrature_point_0, 2);
1707 tmp(9) += 2.0 * this->shape_value_component(
1708 dof, quadrature_point_0, 0);
1710 2.0 * face_quadrature_points[q_point][0],
1711 2.0 * face_quadrature_points[q_point][1],
1713 tmp(16) += 2.0 * this->shape_value_component(
1714 dof, quadrature_point_0, 0);
1715 tmp(17) += 2.0 * this->shape_value_component(
1716 dof, quadrature_point_0, 1);
1723 2.0 * face_quadrature_points[q_point][0],
1724 2.0 * face_quadrature_points[q_point][1] -
1727 tmp(2) += 2.0 * this->shape_value_component(
1728 dof, quadrature_point_0, 1);
1729 tmp(3) += 2.0 * this->shape_value_component(
1730 dof, quadrature_point_0, 2);
1732 2.0 * face_quadrature_points[q_point][0],
1734 2.0 * face_quadrature_points[q_point][1] -
1736 tmp(10) += 2.0 * this->shape_value_component(
1737 dof, quadrature_point_0, 2);
1738 tmp(11) += 2.0 * this->shape_value_component(
1739 dof, quadrature_point_0, 0);
1741 2.0 * face_quadrature_points[q_point][0],
1742 2.0 * face_quadrature_points[q_point][1] -
1745 tmp(18) += 2.0 * this->shape_value_component(
1746 dof, quadrature_point_0, 0);
1747 tmp(19) += 2.0 * this->shape_value_component(
1748 dof, quadrature_point_0, 1);
1752 else if (face_quadrature_points[q_point][1] < 0.5)
1756 2.0 * face_quadrature_points[q_point][0] - 1.0,
1757 2.0 * face_quadrature_points[q_point][1]);
1759 tmp(4) += 2.0 * this->shape_value_component(
1760 dof, quadrature_point_0, 1);
1761 tmp(5) += 2.0 * this->shape_value_component(
1762 dof, quadrature_point_0, 2);
1764 2.0 * face_quadrature_points[q_point][0] - 1.0,
1766 2.0 * face_quadrature_points[q_point][1]);
1767 tmp(12) += 2.0 * this->shape_value_component(
1768 dof, quadrature_point_0, 2);
1769 tmp(13) += 2.0 * this->shape_value_component(
1770 dof, quadrature_point_0, 0);
1772 2.0 * face_quadrature_points[q_point][0] - 1.0,
1773 2.0 * face_quadrature_points[q_point][1],
1775 tmp(20) += 2.0 * this->shape_value_component(
1776 dof, quadrature_point_0, 0);
1777 tmp(21) += 2.0 * this->shape_value_component(
1778 dof, quadrature_point_0, 1);
1785 2.0 * face_quadrature_points[q_point][0] - 1.0,
1786 2.0 * face_quadrature_points[q_point][1] - 1.0);
1788 tmp(6) += 2.0 * this->shape_value_component(
1789 dof, quadrature_point_0, 1);
1790 tmp(7) += 2.0 * this->shape_value_component(
1791 dof, quadrature_point_0, 2);
1793 2.0 * face_quadrature_points[q_point][0] - 1.0,
1795 2.0 * face_quadrature_points[q_point][1] - 1.0);
1796 tmp(14) += 2.0 * this->shape_value_component(
1797 dof, quadrature_point_0, 2);
1798 tmp(15) += 2.0 * this->shape_value_component(
1799 dof, quadrature_point_0, 0);
1801 2.0 * face_quadrature_points[q_point][0] - 1.0,
1802 2.0 * face_quadrature_points[q_point][1] - 1.0,
1804 tmp(22) += 2.0 * this->shape_value_component(
1805 dof, quadrature_point_0, 0);
1806 tmp(23) += 2.0 * this->shape_value_component(
1807 dof, quadrature_point_0, 1);
1812 face_quadrature_points[q_point][0],
1813 face_quadrature_points[q_point][1]);
1815 face_quadrature_points[q_point][0],
1817 face_quadrature_points[q_point][1]);
1819 face_quadrature_points[q_point][0],
1820 face_quadrature_points[q_point][1],
1823 for (
unsigned int j = 0; j < 2; ++j)
1824 for (
unsigned int k = 0; k < 2; ++k)
1825 for (
unsigned int l = 0; l <= deg; ++l)
1827 tmp(2 * (j + 2 * k)) -=
1828 this->restriction[index][i + 2 * (2 * j + k)](
1829 (i + 4 * j) * this->degree + l, dof) *
1830 this->shape_value_component(
1831 (i + 4 * j) * this->degree + l,
1834 tmp(2 * (j + 2 * k) + 1) -=
1835 this->restriction[index][i + 2 * (2 * j + k)](
1836 (i + 2 * (k + 4)) * this->degree + l, dof) *
1837 this->shape_value_component(
1838 (i + 2 * (k + 4)) * this->degree + l,
1841 tmp(2 * (j + 2 * (k + 2))) -=
1842 this->restriction[index][2 * (i + 2 * j) + k](
1843 (2 * (i + 4) + k) * this->degree + l, dof) *
1844 this->shape_value_component(
1845 (2 * (i + 4) + k) * this->degree + l,
1848 tmp(2 * (j + 2 * k) + 9) -=
1849 this->restriction[index][2 * (i + 2 * j) + k](
1850 (i + 4 * j + 2) * this->degree + l, dof) *
1851 this->shape_value_component(
1852 (i + 4 * j + 2) * this->degree + l,
1855 tmp(2 * (j + 2 * (k + 4))) -=
1856 this->restriction[index][2 * (2 * i + j) + k](
1857 (4 * i + j + 2) * this->degree + l, dof) *
1858 this->shape_value_component(
1859 (4 * i + j + 2) * this->degree + l,
1862 tmp(2 * (j + 2 * k) + 17) -=
1863 this->restriction[index][2 * (2 * i + j) + k](
1864 (4 * i + k) * this->degree + l, dof) *
1865 this->shape_value_component(
1866 (4 * i + k) * this->degree + l,
1871 tmp *= face_quadrature.weight(q_point);
1873 for (
unsigned int j = 0; j <= deg; ++j)
1875 const double L_j_0 = legendre_polynomials[j].value(
1876 face_quadrature_points[q_point][0]);
1877 const double L_j_1 = legendre_polynomials[j].value(
1878 face_quadrature_points[q_point][1]);
1880 for (
unsigned int k = 0; k < deg; ++k)
1882 const double l_k_0 =
1883 L_j_0 * lobatto_polynomials[k + 2].value(
1884 face_quadrature_points[q_point][1]);
1885 const double l_k_1 =
1886 L_j_1 * lobatto_polynomials[k + 2].value(
1887 face_quadrature_points[q_point][0]);
1889 for (
unsigned int l = 0; l < 4; ++l)
1891 system_rhs(j * deg + k, 2 * l) +=
1893 system_rhs(j * deg + k, 2 * l + 1) +=
1894 tmp(2 * l + 1) * l_k_1;
1895 system_rhs(j * deg + k, 2 * (l + 4)) +=
1896 tmp(2 * (l + 4)) * l_k_1;
1897 system_rhs(j * deg + k, 2 * l + 9) +=
1898 tmp(2 * l + 9) * l_k_0;
1899 system_rhs(j * deg + k, 2 * (l + 8)) +=
1900 tmp(2 * (l + 8)) * l_k_0;
1901 system_rhs(j * deg + k, 2 * l + 17) +=
1902 tmp(2 * l + 17) * l_k_1;
1908 system_matrix_inv.
mmult(solution, system_rhs);
1910 for (
unsigned int j = 0; j < 2; ++j)
1911 for (
unsigned int k = 0; k < 2; ++k)
1912 for (
unsigned int l = 0; l <= deg; ++l)
1913 for (
unsigned int m = 0; m < deg; ++m)
1916 2 * (j + 2 * k))) > 1e-14)
1917 this->restriction[index][i + 2 * (2 * j + k)](
1918 (2 * i * this->degree + l) * deg + m +
1920 dof) = solution(l * deg + m, 2 * (j + 2 * k));
1923 2 * (j + 2 * k) + 1)) >
1925 this->restriction[index][i + 2 * (2 * j + k)](
1926 ((2 * i + 1) * deg + m) * this->degree + l +
1929 solution(l * deg + m, 2 * (j + 2 * k) + 1);
1932 2 * (j + 2 * (k + 2)))) >
1934 this->restriction[index][2 * (i + 2 * j) + k](
1935 (2 * (i + 2) * this->degree + l) * deg + m +
1938 solution(l * deg + m, 2 * (j + 2 * (k + 2)));
1941 2 * (j + 2 * k) + 9)) >
1943 this->restriction[index][2 * (i + 2 * j) + k](
1944 ((2 * i + 5) * deg + m) * this->degree + l +
1947 solution(l * deg + m, 2 * (j + 2 * k) + 9);
1950 2 * (j + 2 * (k + 4)))) >
1952 this->restriction[index][2 * (2 * i + j) + k](
1953 (2 * (i + 4) * this->degree + l) * deg + m +
1956 solution(l * deg + m, 2 * (j + 2 * (k + 4)));
1959 2 * (j + 2 * k) + 17)) >
1961 this->restriction[index][2 * (2 * i + j) + k](
1962 ((2 * i + 9) * deg + m) * this->degree + l +
1965 solution(l * deg + m, 2 * (j + 2 * k) + 17);
1970 const std::vector<Point<dim>> &quadrature_points =
1971 quadrature.get_points();
1972 const unsigned int n_boundary_dofs =
1975 const unsigned int n_quadrature_points = quadrature.size();
1979 n_quadrature_points);
1981 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
1984 const double weight =
std::sqrt(quadrature.weight(q_point));
1986 for (
unsigned int i = 0; i <= deg; ++i)
1989 weight * legendre_polynomials[i].value(
1990 quadrature_points[q_point][0]);
1992 for (
unsigned int j = 0; j < deg; ++j)
1995 L_i * lobatto_polynomials[j + 2].value(
1996 quadrature_points[q_point][1]);
1998 for (
unsigned int k = 0; k < deg; ++k)
1999 assembling_matrix((i * deg + j) * deg + k,
2001 l_j * lobatto_polynomials[k + 2].value(
2002 quadrature_points[q_point][2]);
2008 assembling_matrix.
m());
2010 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
2011 system_matrix_inv.reinit(system_matrix.
m(), system_matrix.
m());
2012 system_matrix_inv.
invert(system_matrix);
2015 solution.reinit(system_matrix_inv.
m(), 24);
2016 system_rhs.reinit(system_matrix_inv.
m(), 24);
2019 for (
unsigned int dof = 0; dof < this->n_dofs_per_cell(); ++dof)
2023 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
2028 if (quadrature_points[q_point][0] < 0.5)
2030 if (quadrature_points[q_point][1] < 0.5)
2032 if (quadrature_points[q_point][2] < 0.5)
2035 2.0 * quadrature_points[q_point][0],
2036 2.0 * quadrature_points[q_point][1],
2037 2.0 * quadrature_points[q_point][2]);
2039 tmp(0) += 2.0 * this->shape_value_component(
2040 dof, quadrature_point, 0);
2041 tmp(1) += 2.0 * this->shape_value_component(
2042 dof, quadrature_point, 1);
2043 tmp(2) += 2.0 * this->shape_value_component(
2044 dof, quadrature_point, 2);
2050 2.0 * quadrature_points[q_point][0],
2051 2.0 * quadrature_points[q_point][1],
2052 2.0 * quadrature_points[q_point][2] - 1.0);
2054 tmp(3) += 2.0 * this->shape_value_component(
2055 dof, quadrature_point, 0);
2056 tmp(4) += 2.0 * this->shape_value_component(
2057 dof, quadrature_point, 1);
2058 tmp(5) += 2.0 * this->shape_value_component(
2059 dof, quadrature_point, 2);
2063 else if (quadrature_points[q_point][2] < 0.5)
2066 2.0 * quadrature_points[q_point][0],
2067 2.0 * quadrature_points[q_point][1] - 1.0,
2068 2.0 * quadrature_points[q_point][2]);
2070 tmp(6) += 2.0 * this->shape_value_component(
2071 dof, quadrature_point, 0);
2072 tmp(7) += 2.0 * this->shape_value_component(
2073 dof, quadrature_point, 1);
2074 tmp(8) += 2.0 * this->shape_value_component(
2075 dof, quadrature_point, 2);
2081 2.0 * quadrature_points[q_point][0],
2082 2.0 * quadrature_points[q_point][1] - 1.0,
2083 2.0 * quadrature_points[q_point][2] - 1.0);
2085 tmp(9) += 2.0 * this->shape_value_component(
2086 dof, quadrature_point, 0);
2087 tmp(10) += 2.0 * this->shape_value_component(
2088 dof, quadrature_point, 1);
2089 tmp(11) += 2.0 * this->shape_value_component(
2090 dof, quadrature_point, 2);
2094 else if (quadrature_points[q_point][1] < 0.5)
2096 if (quadrature_points[q_point][2] < 0.5)
2099 2.0 * quadrature_points[q_point][0] - 1.0,
2100 2.0 * quadrature_points[q_point][1],
2101 2.0 * quadrature_points[q_point][2]);
2103 tmp(12) += 2.0 * this->shape_value_component(
2104 dof, quadrature_point, 0);
2105 tmp(13) += 2.0 * this->shape_value_component(
2106 dof, quadrature_point, 1);
2107 tmp(14) += 2.0 * this->shape_value_component(
2108 dof, quadrature_point, 2);
2114 2.0 * quadrature_points[q_point][0] - 1.0,
2115 2.0 * quadrature_points[q_point][1],
2116 2.0 * quadrature_points[q_point][2] - 1.0);
2118 tmp(15) += 2.0 * this->shape_value_component(
2119 dof, quadrature_point, 0);
2120 tmp(16) += 2.0 * this->shape_value_component(
2121 dof, quadrature_point, 1);
2122 tmp(17) += 2.0 * this->shape_value_component(
2123 dof, quadrature_point, 2);
2127 else if (quadrature_points[q_point][2] < 0.5)
2130 2.0 * quadrature_points[q_point][0] - 1.0,
2131 2.0 * quadrature_points[q_point][1] - 1.0,
2132 2.0 * quadrature_points[q_point][2]);
2135 2.0 * this->shape_value_component(dof,
2139 2.0 * this->shape_value_component(dof,
2143 2.0 * this->shape_value_component(dof,
2151 2.0 * quadrature_points[q_point][0] - 1.0,
2152 2.0 * quadrature_points[q_point][1] - 1.0,
2153 2.0 * quadrature_points[q_point][2] - 1.0);
2156 2.0 * this->shape_value_component(dof,
2160 2.0 * this->shape_value_component(dof,
2164 2.0 * this->shape_value_component(dof,
2169 for (
unsigned int i = 0; i < 2; ++i)
2170 for (
unsigned int j = 0; j < 2; ++j)
2171 for (
unsigned int k = 0; k < 2; ++k)
2172 for (
unsigned int l = 0; l <= deg; ++l)
2174 tmp(3 * (i + 2 * (j + 2 * k))) -=
2175 this->restriction[index][2 * (2 * i + j) + k](
2176 (4 * i + j + 2) * this->degree + l, dof) *
2177 this->shape_value_component(
2178 (4 * i + j + 2) * this->degree + l,
2179 quadrature_points[q_point],
2181 tmp(3 * (i + 2 * (j + 2 * k)) + 1) -=
2182 this->restriction[index][2 * (2 * i + j) + k](
2183 (4 * i + k) * this->degree + l, dof) *
2184 this->shape_value_component(
2185 (4 * i + k) * this->degree + l,
2186 quadrature_points[q_point],
2188 tmp(3 * (i + 2 * (j + 2 * k)) + 2) -=
2189 this->restriction[index][2 * (2 * i + j) + k](
2190 (2 * (j + 4) + k) * this->degree + l, dof) *
2191 this->shape_value_component(
2192 (2 * (j + 4) + k) * this->degree + l,
2193 quadrature_points[q_point],
2196 for (
unsigned int m = 0; m < deg; ++m)
2198 tmp(3 * (i + 2 * (j + 2 * k))) -=
2199 this->restriction[index][2 * (2 * i + j) +
2201 ((2 * j + 5) * deg + m) * this->degree +
2204 this->shape_value_component(
2205 ((2 * j + 5) * deg + m) * this->degree +
2207 quadrature_points[q_point],
2209 tmp(3 * (i + 2 * (j + 2 * k))) -=
2210 this->restriction[index][2 * (2 * i + j) +
2212 (2 * (i + 4) * this->degree + l) * deg +
2215 this->shape_value_component(
2216 (2 * (i + 4) * this->degree + l) * deg +
2218 quadrature_points[q_point],
2220 tmp(3 * (i + 2 * (j + 2 * k)) + 1) -=
2221 this->restriction[index][2 * (2 * i + j) +
2223 (2 * k * this->degree + l) * deg + m +
2226 this->shape_value_component(
2227 (2 * k * this->degree + l) * deg + m +
2229 quadrature_points[q_point],
2231 tmp(3 * (i + 2 * (j + 2 * k)) + 1) -=
2232 this->restriction[index][2 * (2 * i + j) +
2234 ((2 * i + 9) * deg + m) * this->degree +
2237 this->shape_value_component(
2238 ((2 * i + 9) * deg + m) * this->degree +
2240 quadrature_points[q_point],
2242 tmp(3 * (i + 2 * (j + 2 * k)) + 2) -=
2243 this->restriction[index][2 * (2 * i + j) +
2245 ((2 * k + 1) * deg + m) * this->degree +
2248 this->shape_value_component(
2249 ((2 * k + 1) * deg + m) * this->degree +
2251 quadrature_points[q_point],
2253 tmp(3 * (i + 2 * (j + 2 * k)) + 2) -=
2254 this->restriction[index][2 * (2 * i + j) +
2256 (2 * (j + 2) * this->degree + l) * deg +
2259 this->shape_value_component(
2260 (2 * (j + 2) * this->degree + l) * deg +
2262 quadrature_points[q_point],
2267 tmp *= quadrature.weight(q_point);
2269 for (
unsigned int i = 0; i <= deg; ++i)
2271 const double L_i_0 = legendre_polynomials[i].value(
2272 quadrature_points[q_point][0]);
2273 const double L_i_1 = legendre_polynomials[i].value(
2274 quadrature_points[q_point][1]);
2275 const double L_i_2 = legendre_polynomials[i].value(
2276 quadrature_points[q_point][2]);
2278 for (
unsigned int j = 0; j < deg; ++j)
2280 const double l_j_0 =
2281 L_i_0 * lobatto_polynomials[j + 2].value(
2282 quadrature_points[q_point][1]);
2283 const double l_j_1 =
2284 L_i_1 * lobatto_polynomials[j + 2].value(
2285 quadrature_points[q_point][0]);
2286 const double l_j_2 =
2287 L_i_2 * lobatto_polynomials[j + 2].value(
2288 quadrature_points[q_point][0]);
2290 for (
unsigned int k = 0; k < deg; ++k)
2292 const double l_k_0 =
2293 l_j_0 * lobatto_polynomials[k + 2].value(
2294 quadrature_points[q_point][2]);
2295 const double l_k_1 =
2296 l_j_1 * lobatto_polynomials[k + 2].value(
2297 quadrature_points[q_point][2]);
2298 const double l_k_2 =
2299 l_j_2 * lobatto_polynomials[k + 2].value(
2300 quadrature_points[q_point][1]);
2302 for (
unsigned int l = 0; l < 8; ++l)
2304 system_rhs((i * deg + j) * deg + k,
2305 3 * l) += tmp(3 * l) * l_k_0;
2306 system_rhs((i * deg + j) * deg + k,
2308 tmp(3 * l + 1) * l_k_1;
2309 system_rhs((i * deg + j) * deg + k,
2311 tmp(3 * l + 2) * l_k_2;
2318 system_matrix_inv.
mmult(solution, system_rhs);
2320 for (
unsigned int i = 0; i < 2; ++i)
2321 for (
unsigned int j = 0; j < 2; ++j)
2322 for (
unsigned int k = 0; k < 2; ++k)
2323 for (
unsigned int l = 0; l <= deg; ++l)
2324 for (
unsigned int m = 0; m < deg; ++m)
2325 for (
unsigned int n = 0; n < deg; ++n)
2328 solution((l * deg + m) * deg + n,
2329 3 * (i + 2 * (j + 2 * k)))) >
2331 this->restriction[index][2 * (2 * i + j) + k](
2332 (l * deg + m) * deg + n + n_boundary_dofs,
2333 dof) = solution((l * deg + m) * deg + n,
2334 3 * (i + 2 * (j + 2 * k)));
2337 solution((l * deg + m) * deg + n,
2338 3 * (i + 2 * (j + 2 * k)) + 1)) >
2340 this->restriction[index][2 * (2 * i + j) + k](
2341 (l + (m + deg) * this->degree) * deg + n +
2344 solution((l * deg + m) * deg + n,
2345 3 * (i + 2 * (j + 2 * k)) + 1);
2348 solution((l * deg + m) * deg + n,
2349 3 * (i + 2 * (j + 2 * k)) + 2)) >
2351 this->restriction[index][2 * (2 * i + j) + k](
2353 ((m + 2 * deg) * deg + n) * this->degree +
2356 solution((l * deg + m) * deg + n,
2357 3 * (i + 2 * (j + 2 * k)) + 2);
3466 std::vector<double> &nodal_values)
const
3471 const unsigned int face_no = 0;
3473 const unsigned int deg = this->degree - 1;
3474 Assert(support_point_values.size() == this->generalized_support_points.size(),
3476 this->generalized_support_points.size()));
3477 Assert(support_point_values[0].
size() == this->n_components(),
3479 this->n_components()));
3480 Assert(nodal_values.size() == this->n_dofs_per_cell(),
3482 std::fill(nodal_values.begin(), nodal_values.end(), 0.0);
3490 const QGauss<1> reference_edge_quadrature(this->degree);
3491 const unsigned int n_edge_points = reference_edge_quadrature.size();
3493 for (
unsigned int i = 0; i < 2; ++i)
3494 for (
unsigned int j = 0; j < 2; ++j)
3496 for (
unsigned int q_point = 0; q_point < n_edge_points;
3498 nodal_values[(i + 2 * j) * this->degree] +=
3499 reference_edge_quadrature.weight(q_point) *
3500 support_point_values[q_point + (i + 2 * j) * n_edge_points]
3506 if (
std::abs(nodal_values[(i + 2 * j) * this->degree]) < 1e-14)
3507 nodal_values[(i + 2 * j) * this->degree] = 0.0;
3520 if (this->degree > 1)
3525 const std::vector<Polynomials::Polynomial<double>>
3526 &lobatto_polynomials =
3530 std::vector<Polynomials::Polynomial<double>>
3531 lobatto_polynomials_grad(this->degree);
3533 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size(); ++i)
3534 lobatto_polynomials_grad[i] =
3535 lobatto_polynomials[i + 1].derivative();
3540 for (
unsigned int i = 0; i < system_matrix.
m(); ++i)
3541 for (
unsigned int j = 0; j < system_matrix.
n(); ++j)
3542 for (
unsigned int q_point = 0; q_point < n_edge_points;
3544 system_matrix(i, j) +=
3545 boundary_weights(q_point, j) *
3546 lobatto_polynomials_grad[i + 1].value(
3547 this->generalized_face_support_points[face_no][q_point]
3553 system_matrix_inv.
invert(system_matrix);
3560 for (
unsigned int line = 0;
3561 line < GeometryInfo<dim>::lines_per_cell;
3567 for (
unsigned int q_point = 0; q_point < n_edge_points;
3571 support_point_values[line * n_edge_points + q_point]
3572 [line_coordinate[line]] -
3573 nodal_values[line * this->degree] *
3574 this->shape_value_component(
3575 line * this->degree,
3576 this->generalized_support_points[line *
3579 line_coordinate[line]);
3581 for (
unsigned int i = 0; i < system_rhs.
size(); ++i)
3582 system_rhs(i) += boundary_weights(q_point, i) * tmp;
3585 system_matrix_inv.
vmult(solution, system_rhs);
3591 for (
unsigned int i = 0; i < solution.
size(); ++i)
3593 nodal_values[line * this->degree + i + 1] = solution(i);
3605 const QGauss<dim> reference_quadrature(this->degree);
3606 const unsigned int n_interior_points =
3607 reference_quadrature.size();
3608 const std::vector<Polynomials::Polynomial<double>>
3609 &legendre_polynomials =
3613 system_matrix.reinit((this->degree - 1) * this->degree,
3614 (this->degree - 1) * this->degree);
3617 for (
unsigned int i = 0; i < this->degree; ++i)
3618 for (
unsigned int j = 0; j < this->degree - 1; ++j)
3619 for (
unsigned int k = 0; k < this->degree; ++k)
3620 for (
unsigned int l = 0; l < this->degree - 1; ++l)
3621 for (
unsigned int q_point = 0;
3622 q_point < n_interior_points;
3624 system_matrix(i * (this->degree - 1) + j,
3625 k * (this->degree - 1) + l) +=
3626 reference_quadrature.weight(q_point) *
3627 legendre_polynomials[i].value(
3628 this->generalized_support_points
3630 n_edge_points][0]) *
3631 lobatto_polynomials[j + 2].value(
3632 this->generalized_support_points
3634 n_edge_points][1]) *
3635 lobatto_polynomials_grad[k].value(
3636 this->generalized_support_points
3638 n_edge_points][0]) *
3639 lobatto_polynomials[l + 2].value(
3640 this->generalized_support_points
3644 system_matrix_inv.reinit(system_matrix.
m(), system_matrix.
m());
3645 system_matrix_inv.
invert(system_matrix);
3649 system_rhs.
reinit(system_matrix_inv.
m());
3652 for (
unsigned int q_point = 0; q_point < n_interior_points;
3656 support_point_values[q_point +
3660 for (
unsigned int i = 0; i < 2; ++i)
3661 for (
unsigned int j = 0; j <= deg; ++j)
3662 tmp -= nodal_values[(i + 2) * this->degree + j] *
3663 this->shape_value_component(
3664 (i + 2) * this->degree + j,
3665 this->generalized_support_points
3670 for (
unsigned int i = 0; i <= deg; ++i)
3671 for (
unsigned int j = 0; j < deg; ++j)
3672 system_rhs(i * deg + j) +=
3673 reference_quadrature.weight(q_point) * tmp *
3674 lobatto_polynomials_grad[i].value(
3675 this->generalized_support_points
3677 n_edge_points][0]) *
3678 lobatto_polynomials[j + 2].value(
3679 this->generalized_support_points
3684 solution.
reinit(system_matrix.
m());
3685 system_matrix_inv.
vmult(solution, system_rhs);
3691 for (
unsigned int i = 0; i <= deg; ++i)
3692 for (
unsigned int j = 0; j < deg; ++j)
3693 if (
std::abs(solution(i * deg + j)) > 1e-14)
3696 solution(i * deg + j);
3703 for (
unsigned int q_point = 0; q_point < n_interior_points;
3707 support_point_values[q_point +
3711 for (
unsigned int i = 0; i < 2; ++i)
3712 for (
unsigned int j = 0; j <= deg; ++j)
3713 tmp -= nodal_values[i * this->degree + j] *
3714 this->shape_value_component(
3715 i * this->degree + j,
3716 this->generalized_support_points
3721 for (
unsigned int i = 0; i <= deg; ++i)
3722 for (
unsigned int j = 0; j < deg; ++j)
3723 system_rhs(i * deg + j) +=
3724 reference_quadrature.weight(q_point) * tmp *
3725 lobatto_polynomials_grad[i].value(
3726 this->generalized_support_points
3728 n_edge_points][1]) *
3729 lobatto_polynomials[j + 2].value(
3730 this->generalized_support_points
3735 system_matrix_inv.
vmult(solution, system_rhs);
3741 for (
unsigned int i = 0; i <= deg; ++i)
3742 for (
unsigned int j = 0; j < deg; ++j)
3743 if (
std::abs(solution(i * deg + j)) > 1e-14)
3746 this->degree] = solution(i * deg + j);
3756 const QGauss<1> reference_edge_quadrature(this->degree);
3757 const unsigned int n_edge_points = reference_edge_quadrature.size();
3759 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
3761 for (
unsigned int i = 0; i < 4; ++i)
3762 nodal_values[(i + 8) * this->degree] +=
3763 reference_edge_quadrature.weight(q_point) *
3764 support_point_values[q_point + (i + 8) * n_edge_points][2];
3766 for (
unsigned int i = 0; i < 2; ++i)
3767 for (
unsigned int j = 0; j < 2; ++j)
3768 for (
unsigned int k = 0; k < 2; ++k)
3769 nodal_values[(i + 2 * (2 * j + k)) * this->degree] +=
3770 reference_edge_quadrature.weight(q_point) *
3771 support_point_values[q_point + (i + 2 * (2 * j + k)) *
3772 n_edge_points][1 - k];
3779 for (
unsigned int i = 0; i < 4; ++i)
3780 if (
std::abs(nodal_values[(i + 8) * this->degree]) < 1e-14)
3781 nodal_values[(i + 8) * this->degree] = 0.0;
3783 for (
unsigned int i = 0; i < 2; ++i)
3784 for (
unsigned int j = 0; j < 2; ++j)
3785 for (
unsigned int k = 0; k < 2; ++k)
3787 nodal_values[(i + 2 * (2 * j + k)) * this->degree]) <
3789 nodal_values[(i + 2 * (2 * j + k)) * this->degree] = 0.0;
3800 if (this->degree > 1)
3805 const std::vector<Polynomials::Polynomial<double>>
3806 &lobatto_polynomials =
3810 std::vector<Polynomials::Polynomial<double>>
3811 lobatto_polynomials_grad(this->degree);
3813 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size(); ++i)
3814 lobatto_polynomials_grad[i] =
3815 lobatto_polynomials[i + 1].derivative();
3820 for (
unsigned int i = 0; i < system_matrix.
m(); ++i)
3821 for (
unsigned int j = 0; j < system_matrix.
n(); ++j)
3822 for (
unsigned int q_point = 0; q_point < n_edge_points;
3824 system_matrix(i, j) +=
3825 boundary_weights(q_point, j) *
3826 lobatto_polynomials_grad[i + 1].value(
3827 this->generalized_face_support_points[face_no][q_point]
3833 system_matrix_inv.
invert(system_matrix);
3837 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2};
3841 for (
unsigned int line = 0;
3842 line < GeometryInfo<dim>::lines_per_cell;
3848 for (
unsigned int q_point = 0; q_point < this->degree;
3852 support_point_values[line * this->degree + q_point]
3853 [line_coordinate[line]] -
3854 nodal_values[line * this->degree] *
3855 this->shape_value_component(
3856 line * this->degree,
3858 ->generalized_support_points[line * this->degree +
3860 line_coordinate[line]);
3862 for (
unsigned int i = 0; i < system_rhs.
size(); ++i)
3863 system_rhs(i) += boundary_weights(q_point, i) * tmp;
3866 system_matrix_inv.
vmult(solution, system_rhs);
3872 for (
unsigned int i = 0; i < solution.
size(); ++i)
3874 nodal_values[line * this->degree + i + 1] = solution(i);
3885 const std::vector<Polynomials::Polynomial<double>>
3886 &legendre_polynomials =
3889 const unsigned int n_face_points = n_edge_points * n_edge_points;
3891 system_matrix.reinit((this->degree - 1) * this->degree,
3892 (this->degree - 1) * this->degree);
3895 for (
unsigned int i = 0; i < this->degree; ++i)
3896 for (
unsigned int j = 0; j < this->degree - 1; ++j)
3897 for (
unsigned int k = 0; k < this->degree; ++k)
3898 for (
unsigned int l = 0; l < this->degree - 1; ++l)
3899 for (
unsigned int q_point = 0; q_point < n_face_points;
3901 system_matrix(i * (this->degree - 1) + j,
3902 k * (this->degree - 1) + l) +=
3903 boundary_weights(q_point + n_edge_points,
3904 2 * (k * (this->degree - 1) + l)) *
3905 legendre_polynomials[i].value(
3906 this->generalized_face_support_points
3907 [face_no][q_point + 4 * n_edge_points][0]) *
3908 lobatto_polynomials[j + 2].value(
3909 this->generalized_face_support_points
3910 [face_no][q_point + 4 * n_edge_points][1]);
3912 system_matrix_inv.reinit(system_matrix.
m(), system_matrix.
m());
3913 system_matrix_inv.
invert(system_matrix);
3914 solution.
reinit(system_matrix.
m());
3915 system_rhs.
reinit(system_matrix.
m());
3919 {1, 2}, {1, 2}, {2, 0}, {2, 0}, {0, 1}, {0, 1}};
3936 for (
unsigned int q_point = 0; q_point < n_face_points;
3940 support_point_values[q_point +
3943 [face_coordinates[face][0]];
3945 for (
unsigned int i = 0; i < 2; ++i)
3946 for (
unsigned int j = 0; j <= deg; ++j)
3950 this->shape_value_component(
3952 this->generalized_support_points
3955 face_coordinates[face][0]);
3957 for (
unsigned int i = 0; i <= deg; ++i)
3958 for (
unsigned int j = 0; j < deg; ++j)
3959 system_rhs(i * deg + j) +=
3960 boundary_weights(q_point + n_edge_points,
3961 2 * (i * deg + j)) *
3965 system_matrix_inv.
vmult(solution, system_rhs);
3971 for (
unsigned int i = 0; i <= deg; ++i)
3972 for (
unsigned int j = 0; j < deg; ++j)
3973 if (
std::abs(solution(i * deg + j)) > 1e-14)
3974 nodal_values[(2 * face * this->degree + i +
3978 solution(i * deg + j);
3985 for (
unsigned int q_point = 0; q_point < n_face_points;
3989 support_point_values[q_point +
3992 [face_coordinates[face][1]];
3994 for (
unsigned int i = 2;
3995 i < GeometryInfo<dim>::lines_per_face;
3997 for (
unsigned int j = 0; j <= deg; ++j)
4001 this->shape_value_component(
4003 this->generalized_support_points
4006 face_coordinates[face][1]);
4008 for (
unsigned int i = 0; i <= deg; ++i)
4009 for (
unsigned int j = 0; j < deg; ++j)
4010 system_rhs(i * deg + j) +=
4011 boundary_weights(q_point + n_edge_points,
4012 2 * (i * deg + j) + 1) *
4016 system_matrix_inv.
vmult(solution, system_rhs);
4022 for (
unsigned int i = 0; i <= deg; ++i)
4023 for (
unsigned int j = 0; j < deg; ++j)
4024 if (
std::abs(solution(i * deg + j)) > 1e-14)
4025 nodal_values[((2 * face + 1) * deg + j +
4028 i] = solution(i * deg + j);
4036 const QGauss<dim> reference_quadrature(this->degree);
4037 const unsigned int n_interior_points =
4038 reference_quadrature.size();
4042 system_matrix.reinit(this->degree * deg * deg,
4043 this->degree * deg * deg);
4046 for (
unsigned int i = 0; i <= deg; ++i)
4047 for (
unsigned int j = 0; j < deg; ++j)
4048 for (
unsigned int k = 0; k < deg; ++k)
4049 for (
unsigned int l = 0; l <= deg; ++l)
4050 for (
unsigned int m = 0; m < deg; ++m)
4051 for (
unsigned int n = 0; n < deg; ++n)
4052 for (
unsigned int q_point = 0;
4053 q_point < n_interior_points;
4055 system_matrix((i * deg + j) * deg + k,
4056 (l * deg + m) * deg + n) +=
4057 reference_quadrature.weight(q_point) *
4058 legendre_polynomials[i].value(
4059 this->generalized_support_points
4064 n_face_points][0]) *
4065 lobatto_polynomials[j + 2].value(
4066 this->generalized_support_points
4071 n_face_points][1]) *
4072 lobatto_polynomials[k + 2].value(
4073 this->generalized_support_points
4078 n_face_points][2]) *
4079 lobatto_polynomials_grad[l].value(
4080 this->generalized_support_points
4085 n_face_points][0]) *
4086 lobatto_polynomials[m + 2].value(
4087 this->generalized_support_points
4092 n_face_points][1]) *
4093 lobatto_polynomials[n + 2].value(
4094 this->generalized_support_points
4101 system_matrix_inv.reinit(system_matrix.
m(), system_matrix.
m());
4102 system_matrix_inv.
invert(system_matrix);
4104 system_rhs.
reinit(system_matrix.
m());
4107 for (
unsigned int q_point = 0; q_point < n_interior_points;
4111 support_point_values[q_point +
4117 for (
unsigned int i = 0; i <= deg; ++i)
4119 for (
unsigned int j = 0; j < 2; ++j)
4120 for (
unsigned int k = 0; k < 2; ++k)
4122 nodal_values[i + (j + 4 * k + 2) * this->degree] *
4123 this->shape_value_component(
4124 i + (j + 4 * k + 2) * this->degree,
4125 this->generalized_support_points
4133 for (
unsigned int j = 0; j < deg; ++j)
4134 for (
unsigned int k = 0; k < 4; ++k)
4136 nodal_values[(i + 2 * (k + 2) * this->degree +
4141 this->shape_value_component(
4142 (i + 2 * (k + 2) * this->degree +
4146 this->generalized_support_points
4155 for (
unsigned int i = 0; i <= deg; ++i)
4156 for (
unsigned int j = 0; j < deg; ++j)
4157 for (
unsigned int k = 0; k < deg; ++k)
4158 system_rhs((i * deg + j) * deg + k) +=
4159 reference_quadrature.weight(q_point) * tmp *
4160 lobatto_polynomials_grad[i].value(
4161 this->generalized_support_points
4166 n_face_points][0]) *
4167 lobatto_polynomials[j + 2].value(
4168 this->generalized_support_points
4173 n_face_points][1]) *
4174 lobatto_polynomials[k + 2].value(
4175 this->generalized_support_points
4184 system_matrix_inv.
vmult(solution, system_rhs);
4190 for (
unsigned int i = 0; i <= deg; ++i)
4191 for (
unsigned int j = 0; j < deg; ++j)
4192 for (
unsigned int k = 0; k < deg; ++k)
4193 if (
std::abs(solution((i * deg + j) * deg + k)) > 1e-14)
4200 solution((i * deg + j) * deg + k);
4205 for (
unsigned int q_point = 0; q_point < n_interior_points;
4209 support_point_values[q_point +
4215 for (
unsigned int i = 0; i <= deg; ++i)
4216 for (
unsigned int j = 0; j < 2; ++j)
4218 for (
unsigned int k = 0; k < 2; ++k)
4219 tmp -= nodal_values[i + (4 * j + k) * this->degree] *
4220 this->shape_value_component(
4221 i + (4 * j + k) * this->degree,
4222 this->generalized_support_points
4230 for (
unsigned int k = 0; k < deg; ++k)
4232 nodal_values[(i + 2 * j * this->degree +
4237 this->shape_value_component(
4238 (i + 2 * j * this->degree +
4242 this->generalized_support_points
4250 ((2 * j + 9) * deg + k +
4253 this->shape_value_component(
4254 i + ((2 * j + 9) * deg + k +
4257 this->generalized_support_points
4266 for (
unsigned int i = 0; i <= deg; ++i)
4267 for (
unsigned int j = 0; j < deg; ++j)
4268 for (
unsigned int k = 0; k < deg; ++k)
4269 system_rhs((i * deg + j) * deg + k) +=
4270 reference_quadrature.weight(q_point) * tmp *
4271 lobatto_polynomials_grad[i].value(
4272 this->generalized_support_points
4277 n_face_points][1]) *
4278 lobatto_polynomials[j + 2].value(
4279 this->generalized_support_points
4284 n_face_points][0]) *
4285 lobatto_polynomials[k + 2].value(
4286 this->generalized_support_points
4294 system_matrix_inv.
vmult(solution, system_rhs);
4300 for (
unsigned int i = 0; i <= deg; ++i)
4301 for (
unsigned int j = 0; j < deg; ++j)
4302 for (
unsigned int k = 0; k < deg; ++k)
4303 if (
std::abs(solution((i * deg + j) * deg + k)) > 1e-14)
4304 nodal_values[((i + this->degree +
4311 solution((i * deg + j) * deg + k);
4316 for (
unsigned int q_point = 0; q_point < n_interior_points;
4320 support_point_values[q_point +
4326 for (
unsigned int i = 0; i <= deg; ++i)
4327 for (
unsigned int j = 0; j < 4; ++j)
4329 tmp -= nodal_values[i + (j + 8) * this->degree] *
4330 this->shape_value_component(
4331 i + (j + 8) * this->degree,
4332 this->generalized_support_points
4340 for (
unsigned int k = 0; k < deg; ++k)
4343 ((2 * j + 1) * deg + k +
4346 this->shape_value_component(
4347 i + ((2 * j + 1) * deg + k +
4350 this->generalized_support_points
4359 for (
unsigned int i = 0; i <= deg; ++i)
4360 for (
unsigned int j = 0; j < deg; ++j)
4361 for (
unsigned int k = 0; k < deg; ++k)
4362 system_rhs((i * deg + j) * deg + k) +=
4363 reference_quadrature.weight(q_point) * tmp *
4364 lobatto_polynomials_grad[i].value(
4365 this->generalized_support_points
4370 n_face_points][2]) *
4371 lobatto_polynomials[j + 2].value(
4372 this->generalized_support_points
4377 n_face_points][0]) *
4378 lobatto_polynomials[k + 2].value(
4379 this->generalized_support_points
4387 system_matrix_inv.
vmult(solution, system_rhs);
4393 for (
unsigned int i = 0; i <= deg; ++i)
4394 for (
unsigned int j = 0; j < deg; ++j)
4395 for (
unsigned int k = 0; k < deg; ++k)
4396 if (
std::abs(solution((i * deg + j) * deg + k)) > 1e-14)
4402 this->degree] = solution((i * deg + j) * deg + k);