16 #include <deal.II/base/logstream.h> 17 #include <deal.II/base/qprojector.h> 18 #include <deal.II/base/quadrature.h> 19 #include <deal.II/base/quadrature_lib.h> 20 #include <deal.II/base/std_cxx14/memory.h> 21 #include <deal.II/base/utilities.h> 23 #include <deal.II/dofs/dof_accessor.h> 25 #include <deal.II/fe/fe_nedelec.h> 26 #include <deal.II/fe/fe_nothing.h> 27 #include <deal.II/fe/fe_tools.h> 28 #include <deal.II/fe/fe_values.h> 29 #include <deal.II/fe/mapping.h> 31 #include <deal.II/grid/tria.h> 32 #include <deal.II/grid/tria_iterator.h> 34 #include <deal.II/lac/full_matrix.h> 35 #include <deal.II/lac/vector.h> 45 DEAL_II_NAMESPACE_OPEN
56 get_embedding_computation_tolerance(
const unsigned int p)
63 return 1.e-15 * std::exp(std::pow(p, 1.075));
80 std::vector<bool>(dim, true)))
107 deallog <<
"Face Embedding" << std::endl;
111 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face; ++i)
114 FETools::compute_face_embedding_matrices<dim, double>(
119 internal::FE_Nedelec::get_embedding_computation_tolerance(order));
134 for (
unsigned int i = 0; i < GeometryInfo<2>::max_children_per_face;
139 face_embeddings[i](j, k);
150 unsigned int target_row = 0;
152 for (
unsigned int i = 0; i < 2; ++i)
153 for (
unsigned int j = this->
degree; j < 2 * this->
degree;
157 face_embeddings[2 * i](j, k);
159 for (
unsigned int i = 0; i < 2; ++i)
160 for (
unsigned int j = 3 * this->degree;
161 j < GeometryInfo<3>::lines_per_face * this->
degree;
165 face_embeddings[i](j, k);
167 for (
unsigned int i = 0; i < 2; ++i)
168 for (
unsigned int j = 0; j < 2; ++j)
169 for (
unsigned int k = i * this->degree;
170 k < (i + 1) * this->degree;
174 face_embeddings[i + 2 * j](k, l);
176 for (
unsigned int i = 0; i < 2; ++i)
177 for (
unsigned int j = 0; j < 2; ++j)
178 for (
unsigned int k = (i + 2) * this->
degree;
179 k < (i + 3) * this->degree;
183 face_embeddings[2 * i + j](k, l);
185 for (
unsigned int i = 0; i < GeometryInfo<3>::max_children_per_face;
187 for (
unsigned int j =
193 face_embeddings[i](j, k);
216 std::ostringstream namebuf;
217 namebuf <<
"FE_Nedelec<" << dim <<
">(" << this->degree - 1 <<
")";
219 return namebuf.str();
224 std::unique_ptr<FiniteElement<dim, dim>>
227 return std_cxx14::make_unique<FE_Nedelec<dim>>(*this);
258 const std::vector<Polynomials::Polynomial<double>> &lobatto_polynomials =
260 std::vector<Polynomials::Polynomial<double>> lobatto_polynomials_grad(order +
263 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size(); ++i)
264 lobatto_polynomials_grad[i] = lobatto_polynomials[i + 1].derivative();
268 const QGauss<dim - 1> reference_edge_quadrature(order + 1);
269 const unsigned int n_edge_points = reference_edge_quadrature.size();
270 const unsigned int n_boundary_points =
275 this->generalized_face_support_points.resize(n_edge_points);
278 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
279 this->generalized_face_support_points[q_point] =
280 reference_edge_quadrature.point(q_point);
288 const unsigned int n_interior_points = quadrature.size();
290 this->generalized_support_points.resize(n_boundary_points +
292 boundary_weights.reinit(n_edge_points, order);
294 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
296 for (
unsigned int line = 0; line < GeometryInfo<dim>::lines_per_cell;
298 this->generalized_support_points[line * n_edge_points + q_point] =
300 line,
true,
false,
false, n_edge_points) +
303 for (
unsigned int i = 0; i < order; ++i)
304 boundary_weights(q_point, i) =
305 reference_edge_quadrature.weight(q_point) *
306 lobatto_polynomials_grad[i + 1].value(
307 this->generalized_face_support_points[q_point](0));
310 for (
unsigned int q_point = 0; q_point < n_interior_points; ++q_point)
311 this->generalized_support_points[q_point + n_boundary_points] =
312 quadrature.point(q_point);
319 this->generalized_support_points.resize(n_boundary_points);
321 for (
unsigned int line = 0; line < GeometryInfo<dim>::lines_per_cell;
323 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
324 this->generalized_support_points[line * n_edge_points + q_point] =
326 line,
true,
false,
false, n_edge_points) +
340 const std::vector<Polynomials::Polynomial<double>> &lobatto_polynomials =
342 std::vector<Polynomials::Polynomial<double>> lobatto_polynomials_grad(order +
345 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size(); ++i)
346 lobatto_polynomials_grad[i] = lobatto_polynomials[i + 1].derivative();
350 const QGauss<1> reference_edge_quadrature(order + 1);
351 const unsigned int n_edge_points = reference_edge_quadrature.size();
360 const QGauss<dim - 1> reference_face_quadrature(order + 1);
361 const unsigned int n_face_points = reference_face_quadrature.size();
362 const unsigned int n_boundary_points =
366 const unsigned int n_interior_points = quadrature.size();
368 boundary_weights.reinit(n_edge_points + n_face_points,
369 2 * (order + 1) * order);
370 this->generalized_face_support_points.resize(4 * n_edge_points +
372 this->generalized_support_points.resize(n_boundary_points +
376 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
378 for (
unsigned int line = 0;
381 this->generalized_face_support_points[line * n_edge_points +
383 edge_quadrature.point(
385 line,
true,
false,
false, n_edge_points) +
388 for (
unsigned int i = 0; i < 2; ++i)
389 for (
unsigned int j = 0; j < 2; ++j)
391 this->generalized_support_points[q_point +
392 (i + 4 * j) * n_edge_points] =
393 Point<dim>(i, reference_edge_quadrature.point(q_point)(0), j);
394 this->generalized_support_points[q_point + (i + 4 * j + 2) *
396 Point<dim>(reference_edge_quadrature.point(q_point)(0), i, j);
397 this->generalized_support_points[q_point + (i + 2 * (j + 4)) *
399 Point<dim>(i, j, reference_edge_quadrature.point(q_point)(0));
402 for (
unsigned int i = 0; i < order; ++i)
403 boundary_weights(q_point, i) =
404 reference_edge_quadrature.weight(q_point) *
405 lobatto_polynomials_grad[i + 1].value(
406 this->generalized_face_support_points[q_point](1));
410 for (
unsigned int q_point = 0; q_point < n_face_points; ++q_point)
412 this->generalized_face_support_points[q_point + 4 * n_edge_points] =
413 reference_face_quadrature.point(q_point);
415 for (
unsigned int i = 0; i <= order; ++i)
416 for (
unsigned int j = 0; j < order; ++j)
418 boundary_weights(q_point + n_edge_points, 2 * (i * order + j)) =
419 reference_face_quadrature.weight(q_point) *
420 lobatto_polynomials_grad[i].value(
421 this->generalized_face_support_points[q_point +
424 lobatto_polynomials[j + 2].value(
425 this->generalized_face_support_points[q_point +
428 boundary_weights(q_point + n_edge_points,
429 2 * (i * order + j) + 1) =
430 reference_face_quadrature.weight(q_point) *
431 lobatto_polynomials_grad[i].value(
432 this->generalized_face_support_points[q_point +
435 lobatto_polynomials[j + 2].value(
436 this->generalized_face_support_points[q_point +
445 for (
unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
447 for (
unsigned int q_point = 0; q_point < n_face_points; ++q_point)
449 this->generalized_support_points[face * n_face_points + q_point +
453 face,
true,
false,
false, n_face_points) +
458 for (
unsigned int q_point = 0; q_point < n_interior_points; ++q_point)
459 this->generalized_support_points[q_point + n_boundary_points] =
460 quadrature.point(q_point);
465 this->generalized_face_support_points.resize(4 * n_edge_points);
466 this->generalized_support_points.resize(
469 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
471 for (
unsigned int line = 0;
474 this->generalized_face_support_points[line * n_edge_points +
476 edge_quadrature.point(
478 line,
true,
false,
false, n_edge_points) +
481 for (
unsigned int i = 0; i < 2; ++i)
482 for (
unsigned int j = 0; j < 2; ++j)
484 this->generalized_support_points[q_point +
485 (i + 4 * j) * n_edge_points] =
486 Point<dim>(i, reference_edge_quadrature.point(q_point)(0), j);
487 this->generalized_support_points[q_point + (i + 4 * j + 2) *
489 Point<dim>(reference_edge_quadrature.point(q_point)(0), i, j);
490 this->generalized_support_points[q_point + (i + 2 * (j + 4)) *
492 Point<dim>(i, j, reference_edge_quadrature.point(q_point)(0));
507 for (
unsigned int i = 0; i < GeometryInfo<1>::max_children_per_cell; ++i)
508 this->restriction[0][i].reinit(0, 0);
524 const QGauss<1> edge_quadrature(2 * this->degree);
525 const std::vector<Point<1>> &edge_quadrature_points =
527 const unsigned int n_edge_quadrature_points = edge_quadrature.
size();
538 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
539 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
542 const double weight = 2.0 * edge_quadrature.
weight(q_point);
544 if (edge_quadrature_points[q_point](0) < 0.5)
547 0.0, 2.0 * edge_quadrature_points[q_point](0));
549 this->restriction[index][0](0, dof) +=
551 this->shape_value_component(dof, quadrature_point, 1);
552 quadrature_point(0) = 1.0;
553 this->restriction[index][1](this->degree, dof) +=
555 this->shape_value_component(dof, quadrature_point, 1);
556 quadrature_point(0) = quadrature_point(1);
557 quadrature_point(1) = 0.0;
558 this->restriction[index][0](2 * this->degree, dof) +=
560 this->shape_value_component(dof, quadrature_point, 0);
561 quadrature_point(1) = 1.0;
562 this->restriction[index][2](3 * this->degree, dof) +=
564 this->shape_value_component(dof, quadrature_point, 0);
570 0.0, 2.0 * edge_quadrature_points[q_point](0) - 1.0);
572 this->restriction[index][2](0, dof) +=
574 this->shape_value_component(dof, quadrature_point, 1);
575 quadrature_point(0) = 1.0;
576 this->restriction[index][3](this->degree, dof) +=
578 this->shape_value_component(dof, quadrature_point, 1);
579 quadrature_point(0) = quadrature_point(1);
580 quadrature_point(1) = 0.0;
581 this->restriction[index][1](2 * this->degree, dof) +=
583 this->shape_value_component(dof, quadrature_point, 0);
584 quadrature_point(1) = 1.0;
585 this->restriction[index][3](3 * this->degree, dof) +=
587 this->shape_value_component(dof, quadrature_point, 0);
595 if (this->degree > 1)
597 const unsigned int deg = this->degree - 1;
598 const std::vector<Polynomials::Polynomial<double>>
599 &legendre_polynomials =
605 n_edge_quadrature_points);
607 for (
unsigned int q_point = 0;
608 q_point < n_edge_quadrature_points;
611 const double weight =
612 std::sqrt(edge_quadrature.
weight(q_point));
614 for (
unsigned int i = 0; i < deg; ++i)
615 assembling_matrix(i, q_point) =
616 weight * legendre_polynomials[i + 1].value(
617 edge_quadrature_points[q_point](0));
622 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
623 system_matrix_inv.
invert(system_matrix);
630 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
631 for (
unsigned int i = 0; i < 2; ++i)
635 for (
unsigned int q_point = 0;
636 q_point < n_edge_quadrature_points;
639 const double weight = edge_quadrature.
weight(q_point);
641 i, edge_quadrature_points[q_point](0));
643 edge_quadrature_points[q_point](0), i);
645 if (edge_quadrature_points[q_point](0) < 0.5)
648 i, 2.0 * edge_quadrature_points[q_point](0));
652 (2.0 * this->shape_value_component(
653 dof, quadrature_point_2, 1) -
654 this->restriction[index][i](i * this->degree,
656 this->shape_value_component(i * this->degree,
661 this->restriction[index][i + 2](i * this->degree,
663 this->shape_value_component(i * this->degree,
667 2.0 * edge_quadrature_points[q_point](0), i);
670 (2.0 * this->shape_value_component(
671 dof, quadrature_point_2, 0) -
672 this->restriction[index][2 * i]((i + 2) *
675 this->shape_value_component((i + 2) *
681 this->restriction[index][2 * i + 1](
682 (i + 2) * this->degree, dof) *
683 this->shape_value_component(
684 (i + 2) * this->degree, quadrature_point_1, 0);
691 this->restriction[index][i](i * this->degree,
693 this->shape_value_component(i * this->degree,
699 2.0 * edge_quadrature_points[q_point](0) - 1.0);
703 (2.0 * this->shape_value_component(
704 dof, quadrature_point_2, 1) -
705 this->restriction[index][i + 2](i * this->degree,
707 this->shape_value_component(i * this->degree,
712 this->restriction[index][2 * i]((i + 2) *
715 this->shape_value_component(
716 (i + 2) * this->degree, quadrature_point_1, 0);
718 2.0 * edge_quadrature_points[q_point](0) - 1.0,
722 (2.0 * this->shape_value_component(
723 dof, quadrature_point_2, 0) -
724 this->restriction[index][2 * i + 1](
725 (i + 2) * this->degree, dof) *
726 this->shape_value_component((i + 2) *
732 for (
unsigned int j = 0; j < this->degree - 1; ++j)
735 legendre_polynomials[j + 1].value(
736 edge_quadrature_points[q_point](0));
738 for (
unsigned int k = 0; k < tmp.
size(); ++k)
739 system_rhs(j, k) += tmp(k) * L_j;
743 system_matrix_inv.
mmult(solution, system_rhs);
745 for (
unsigned int j = 0; j < this->degree - 1; ++j)
746 for (
unsigned int k = 0; k < 2; ++k)
748 if (std::abs(solution(j, k)) > 1e-14)
749 this->restriction[index][i + 2 * k](
750 i * this->degree + j + 1, dof) = solution(j, k);
752 if (std::abs(solution(j, k + 2)) > 1e-14)
753 this->restriction[index][2 * i + k](
754 (i + 2) * this->degree + j + 1, dof) =
760 const std::vector<Point<dim>> &quadrature_points =
762 const std::vector<Polynomials::Polynomial<double>>
763 &lobatto_polynomials =
765 const unsigned int n_boundary_dofs =
767 const unsigned int n_quadrature_points = quadrature.
size();
772 n_quadrature_points);
774 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
777 const double weight = std::sqrt(quadrature.
weight(q_point));
779 for (
unsigned int i = 0; i < this->degree; ++i)
782 weight * legendre_polynomials[i].value(
783 quadrature_points[q_point](0));
785 for (
unsigned int j = 0; j < this->degree - 1; ++j)
786 assembling_matrix(i * (this->degree - 1) + j,
788 L_i * lobatto_polynomials[j + 2].value(
789 quadrature_points[q_point](1));
794 assembling_matrix.
m());
796 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
797 system_matrix_inv.
reinit(system_matrix.m(), system_matrix.m());
798 system_matrix_inv.
invert(system_matrix);
801 solution.
reinit(system_matrix_inv.
m(), 8);
802 system_rhs.
reinit(system_matrix_inv.
m(), 8);
805 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
809 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
814 if (quadrature_points[q_point](0) < 0.5)
816 if (quadrature_points[q_point](1) < 0.5)
819 2.0 * quadrature_points[q_point](0),
820 2.0 * quadrature_points[q_point](1));
822 tmp(0) += 2.0 * this->shape_value_component(
823 dof, quadrature_point, 0);
824 tmp(1) += 2.0 * this->shape_value_component(
825 dof, quadrature_point, 1);
831 2.0 * quadrature_points[q_point](0),
832 2.0 * quadrature_points[q_point](1) - 1.0);
834 tmp(4) += 2.0 * this->shape_value_component(
835 dof, quadrature_point, 0);
836 tmp(5) += 2.0 * this->shape_value_component(
837 dof, quadrature_point, 1);
841 else if (quadrature_points[q_point](1) < 0.5)
844 2.0 * quadrature_points[q_point](0) - 1.0,
845 2.0 * quadrature_points[q_point](1));
848 2.0 * this->shape_value_component(dof,
852 2.0 * this->shape_value_component(dof,
860 2.0 * quadrature_points[q_point](0) - 1.0,
861 2.0 * quadrature_points[q_point](1) - 1.0);
864 2.0 * this->shape_value_component(dof,
868 2.0 * this->shape_value_component(dof,
873 for (
unsigned int i = 0; i < 2; ++i)
874 for (
unsigned int j = 0; j < this->degree; ++j)
877 this->restriction[index][i](j + 2 * this->degree,
879 this->shape_value_component(
880 j + 2 * this->degree,
881 quadrature_points[q_point],
884 this->restriction[index][i](i * this->degree + j,
886 this->shape_value_component(
887 i * this->degree + j,
888 quadrature_points[q_point],
890 tmp(2 * (i + 2)) -= this->restriction[index][i + 2](
891 j + 3 * this->degree, dof) *
892 this->shape_value_component(
893 j + 3 * this->degree,
894 quadrature_points[q_point],
896 tmp(2 * i + 5) -= this->restriction[index][i + 2](
897 i * this->degree + j, dof) *
898 this->shape_value_component(
899 i * this->degree + j,
900 quadrature_points[q_point],
904 tmp *= quadrature.
weight(q_point);
906 for (
unsigned int i = 0; i < this->degree; ++i)
908 const double L_i_0 = legendre_polynomials[i].value(
909 quadrature_points[q_point](0));
910 const double L_i_1 = legendre_polynomials[i].value(
911 quadrature_points[q_point](1));
913 for (
unsigned int j = 0; j < this->degree - 1; ++j)
916 L_i_0 * lobatto_polynomials[j + 2].value(
917 quadrature_points[q_point](1));
919 L_i_1 * lobatto_polynomials[j + 2].value(
920 quadrature_points[q_point](0));
922 for (
unsigned int k = 0; k < 4; ++k)
924 system_rhs(i * (this->degree - 1) + j,
925 2 * k) += tmp(2 * k) * l_j_0;
926 system_rhs(i * (this->degree - 1) + j,
928 tmp(2 * k + 1) * l_j_1;
934 system_matrix_inv.
mmult(solution, system_rhs);
936 for (
unsigned int i = 0; i < this->degree; ++i)
937 for (
unsigned int j = 0; j < this->degree - 1; ++j)
938 for (
unsigned int k = 0; k < 4; ++k)
940 if (std::abs(solution(i * (this->degree - 1) + j,
942 this->restriction[index][k](i * (this->degree - 1) +
945 solution(i * (this->degree - 1) + j, 2 * k);
947 if (std::abs(solution(i * (this->degree - 1) + j,
949 this->restriction[index][k](
950 i + (this->degree - 1 + j) * this->degree +
953 solution(i * (this->degree - 1) + j, 2 * k + 1);
967 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
968 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
971 const double weight = 2.0 * edge_quadrature.
weight(q_point);
973 if (edge_quadrature_points[q_point](0) < 0.5)
974 for (
unsigned int i = 0; i < 2; ++i)
975 for (
unsigned int j = 0; j < 2; ++j)
978 i, 2.0 * edge_quadrature_points[q_point](0), j);
980 this->restriction[index][i + 4 * j]((i + 4 * j) *
984 this->shape_value_component(dof, quadrature_point, 1);
986 Point<dim>(2.0 * edge_quadrature_points[q_point](0),
989 this->restriction[index][2 * (i + 2 * j)](
990 (i + 4 * j + 2) * this->degree, dof) +=
992 this->shape_value_component(dof, quadrature_point, 0);
996 2.0 * edge_quadrature_points[q_point](0));
997 this->restriction[index][i + 2 * j]((i + 2 * (j + 4)) *
1001 this->shape_value_component(dof, quadrature_point, 2);
1005 for (
unsigned int i = 0; i < 2; ++i)
1006 for (
unsigned int j = 0; j < 2; ++j)
1009 i, 2.0 * edge_quadrature_points[q_point](0) - 1.0, j);
1011 this->restriction[index][i + 4 * j + 2]((i + 4 * j) *
1015 this->shape_value_component(dof, quadrature_point, 1);
1017 2.0 * edge_quadrature_points[q_point](0) - 1.0, i, j);
1018 this->restriction[index][2 * (i + 2 * j) + 1](
1019 (i + 4 * j + 2) * this->degree, dof) +=
1021 this->shape_value_component(dof, quadrature_point, 0);
1023 i, j, 2.0 * edge_quadrature_points[q_point](0) - 1.0);
1024 this->restriction[index][i + 2 * (j + 2)](
1025 (i + 2 * (j + 4)) * this->degree, dof) +=
1027 this->shape_value_component(dof, quadrature_point, 2);
1035 if (this->degree > 1)
1037 const unsigned int deg = this->degree - 1;
1038 const std::vector<Polynomials::Polynomial<double>>
1039 &legendre_polynomials =
1045 n_edge_quadrature_points);
1047 for (
unsigned int q_point = 0;
1048 q_point < n_edge_quadrature_points;
1051 const double weight =
1052 std::sqrt(edge_quadrature.
weight(q_point));
1054 for (
unsigned int i = 0; i < deg; ++i)
1055 assembling_matrix(i, q_point) =
1056 weight * legendre_polynomials[i + 1].value(
1057 edge_quadrature_points[q_point](0));
1062 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
1063 system_matrix_inv.
invert(system_matrix);
1070 for (
unsigned int i = 0; i < 2; ++i)
1071 for (
unsigned int j = 0; j < 2; ++j)
1072 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
1076 for (
unsigned int q_point = 0;
1077 q_point < n_edge_quadrature_points;
1080 const double weight = edge_quadrature.
weight(q_point);
1082 i, edge_quadrature_points[q_point](0), j);
1084 edge_quadrature_points[q_point](0), i, j);
1086 i, j, edge_quadrature_points[q_point](0));
1088 if (edge_quadrature_points[q_point](0) < 0.5)
1091 i, 2.0 * edge_quadrature_points[q_point](0), j);
1094 weight * (2.0 * this->shape_value_component(
1095 dof, quadrature_point_3, 1) -
1096 this->restriction[index][i + 4 * j](
1097 (i + 4 * j) * this->degree, dof) *
1098 this->shape_value_component(
1099 (i + 4 * j) * this->degree,
1104 this->restriction[index][i + 4 * j + 2](
1105 (i + 4 * j) * this->degree, dof) *
1106 this->shape_value_component((i + 4 * j) *
1111 2.0 * edge_quadrature_points[q_point](0), i, j);
1114 (2.0 * this->shape_value_component(
1115 dof, quadrature_point_3, 0) -
1116 this->restriction[index][2 * (i + 2 * j)](
1117 (i + 4 * j + 2) * this->degree, dof) *
1118 this->shape_value_component(
1119 (i + 4 * j + 2) * this->degree,
1124 this->restriction[index][2 * (i + 2 * j) + 1](
1125 (i + 4 * j + 2) * this->degree, dof) *
1126 this->shape_value_component((i + 4 * j + 2) *
1131 i, j, 2.0 * edge_quadrature_points[q_point](0));
1134 (2.0 * this->shape_value_component(
1135 dof, quadrature_point_3, 2) -
1136 this->restriction[index][i + 2 * j](
1137 (i + 2 * (j + 4)) * this->degree, dof) *
1138 this->shape_value_component(
1139 (i + 2 * (j + 4)) * this->degree,
1144 this->restriction[index][i + 2 * (j + 2)](
1145 (i + 2 * (j + 4)) * this->degree, dof) *
1146 this->shape_value_component((i + 2 * (j + 4)) *
1156 this->restriction[index][i + 4 * j](
1157 (i + 4 * j) * this->degree, dof) *
1158 this->shape_value_component((i + 4 * j) *
1165 2.0 * edge_quadrature_points[q_point](0) - 1.0,
1169 (2.0 * this->shape_value_component(
1170 dof, quadrature_point_3, 1) -
1171 this->restriction[index][i + 4 * j + 2](
1172 (i + 4 * j) * this->degree, dof) *
1173 this->shape_value_component(
1174 (i + 4 * j) * this->degree,
1179 this->restriction[index][2 * (i + 2 * j)](
1180 (i + 4 * j + 2) * this->degree, dof) *
1181 this->shape_value_component((i + 4 * j + 2) *
1186 2.0 * edge_quadrature_points[q_point](0) - 1.0,
1191 (2.0 * this->shape_value_component(
1192 dof, quadrature_point_3, 0) -
1193 this->restriction[index][2 * (i + 2 * j) + 1](
1194 (i + 4 * j + 2) * this->degree, dof) *
1195 this->shape_value_component(
1196 (i + 4 * j + 2) * this->degree,
1201 this->restriction[index][i + 2 * j](
1202 (i + 2 * (j + 4)) * this->degree, dof) *
1203 this->shape_value_component((i + 2 * (j + 4)) *
1210 2.0 * edge_quadrature_points[q_point](0) - 1.0);
1213 (2.0 * this->shape_value_component(
1214 dof, quadrature_point_3, 2) -
1215 this->restriction[index][i + 2 * (j + 2)](
1216 (i + 2 * (j + 4)) * this->degree, dof) *
1217 this->shape_value_component(
1218 (i + 2 * (j + 4)) * this->degree,
1223 for (
unsigned int k = 0; k < deg; ++k)
1226 legendre_polynomials[k + 1].value(
1227 edge_quadrature_points[q_point](0));
1229 for (
unsigned int l = 0; l < tmp.
size(); ++l)
1230 system_rhs(k, l) += tmp(l) * L_k;
1234 system_matrix_inv.
mmult(solution, system_rhs);
1236 for (
unsigned int k = 0; k < 2; ++k)
1237 for (
unsigned int l = 0; l < deg; ++l)
1239 if (std::abs(solution(l, k)) > 1e-14)
1240 this->restriction[index][i + 2 * (2 * j + k)](
1241 (i + 4 * j) * this->degree + l + 1, dof) =
1244 if (std::abs(solution(l, k + 2)) > 1e-14)
1245 this->restriction[index][2 * (i + 2 * j) + k](
1246 (i + 4 * j + 2) * this->degree + l + 1, dof) =
1249 if (std::abs(solution(l, k + 4)) > 1e-14)
1250 this->restriction[index][i + 2 * (j + 2 * k)](
1251 (i + 2 * (j + 4)) * this->degree + l + 1, dof) =
1256 const QGauss<2> face_quadrature(2 * this->degree);
1257 const std::vector<Point<2>> &face_quadrature_points =
1259 const std::vector<Polynomials::Polynomial<double>>
1260 &lobatto_polynomials =
1262 const unsigned int n_edge_dofs =
1264 const unsigned int n_face_quadrature_points =
1265 face_quadrature.
size();
1269 n_face_quadrature_points);
1271 for (
unsigned int q_point = 0;
1272 q_point < n_face_quadrature_points;
1275 const double weight =
1276 std::sqrt(face_quadrature.
weight(q_point));
1278 for (
unsigned int i = 0; i <= deg; ++i)
1281 weight * legendre_polynomials[i].value(
1282 face_quadrature_points[q_point](0));
1284 for (
unsigned int j = 0; j < deg; ++j)
1285 assembling_matrix(i * deg + j, q_point) =
1286 L_i * lobatto_polynomials[j + 2].value(
1287 face_quadrature_points[q_point](1));
1292 assembling_matrix.
m());
1294 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
1295 system_matrix_inv.
reinit(system_matrix.m(), system_matrix.m());
1296 system_matrix_inv.
invert(system_matrix);
1299 solution.
reinit(system_matrix_inv.
m(), 24);
1300 system_rhs.
reinit(system_matrix_inv.
m(), 24);
1303 for (
unsigned int i = 0; i < 2; ++i)
1304 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
1308 for (
unsigned int q_point = 0;
1309 q_point < n_face_quadrature_points;
1314 if (face_quadrature_points[q_point](0) < 0.5)
1316 if (face_quadrature_points[q_point](1) < 0.5)
1320 2.0 * face_quadrature_points[q_point](0),
1321 2.0 * face_quadrature_points[q_point](1));
1323 tmp(0) += 2.0 * this->shape_value_component(
1324 dof, quadrature_point_0, 1);
1325 tmp(1) += 2.0 * this->shape_value_component(
1326 dof, quadrature_point_0, 2);
1328 2.0 * face_quadrature_points[q_point](0),
1330 2.0 * face_quadrature_points[q_point](1));
1331 tmp(8) += 2.0 * this->shape_value_component(
1332 dof, quadrature_point_0, 2);
1333 tmp(9) += 2.0 * this->shape_value_component(
1334 dof, quadrature_point_0, 0);
1336 2.0 * face_quadrature_points[q_point](0),
1337 2.0 * face_quadrature_points[q_point](1),
1339 tmp(16) += 2.0 * this->shape_value_component(
1340 dof, quadrature_point_0, 0);
1341 tmp(17) += 2.0 * this->shape_value_component(
1342 dof, quadrature_point_0, 1);
1349 2.0 * face_quadrature_points[q_point](0),
1350 2.0 * face_quadrature_points[q_point](1) -
1353 tmp(2) += 2.0 * this->shape_value_component(
1354 dof, quadrature_point_0, 1);
1355 tmp(3) += 2.0 * this->shape_value_component(
1356 dof, quadrature_point_0, 2);
1358 2.0 * face_quadrature_points[q_point](0),
1360 2.0 * face_quadrature_points[q_point](1) -
1362 tmp(10) += 2.0 * this->shape_value_component(
1363 dof, quadrature_point_0, 2);
1364 tmp(11) += 2.0 * this->shape_value_component(
1365 dof, quadrature_point_0, 0);
1367 2.0 * face_quadrature_points[q_point](0),
1368 2.0 * face_quadrature_points[q_point](1) -
1371 tmp(18) += 2.0 * this->shape_value_component(
1372 dof, quadrature_point_0, 0);
1373 tmp(19) += 2.0 * this->shape_value_component(
1374 dof, quadrature_point_0, 1);
1378 else if (face_quadrature_points[q_point](1) < 0.5)
1382 2.0 * face_quadrature_points[q_point](0) - 1.0,
1383 2.0 * face_quadrature_points[q_point](1));
1385 tmp(4) += 2.0 * this->shape_value_component(
1386 dof, quadrature_point_0, 1);
1387 tmp(5) += 2.0 * this->shape_value_component(
1388 dof, quadrature_point_0, 2);
1390 2.0 * face_quadrature_points[q_point](0) - 1.0,
1392 2.0 * face_quadrature_points[q_point](1));
1393 tmp(12) += 2.0 * this->shape_value_component(
1394 dof, quadrature_point_0, 2);
1395 tmp(13) += 2.0 * this->shape_value_component(
1396 dof, quadrature_point_0, 0);
1398 2.0 * face_quadrature_points[q_point](0) - 1.0,
1399 2.0 * face_quadrature_points[q_point](1),
1401 tmp(20) += 2.0 * this->shape_value_component(
1402 dof, quadrature_point_0, 0);
1403 tmp(21) += 2.0 * this->shape_value_component(
1404 dof, quadrature_point_0, 1);
1411 2.0 * face_quadrature_points[q_point](0) - 1.0,
1412 2.0 * face_quadrature_points[q_point](1) - 1.0);
1414 tmp(6) += 2.0 * this->shape_value_component(
1415 dof, quadrature_point_0, 1);
1416 tmp(7) += 2.0 * this->shape_value_component(
1417 dof, quadrature_point_0, 2);
1419 2.0 * face_quadrature_points[q_point](0) - 1.0,
1421 2.0 * face_quadrature_points[q_point](1) - 1.0);
1422 tmp(14) += 2.0 * this->shape_value_component(
1423 dof, quadrature_point_0, 2);
1424 tmp(15) += 2.0 * this->shape_value_component(
1425 dof, quadrature_point_0, 0);
1427 2.0 * face_quadrature_points[q_point](0) - 1.0,
1428 2.0 * face_quadrature_points[q_point](1) - 1.0,
1430 tmp(22) += 2.0 * this->shape_value_component(
1431 dof, quadrature_point_0, 0);
1432 tmp(23) += 2.0 * this->shape_value_component(
1433 dof, quadrature_point_0, 1);
1438 face_quadrature_points[q_point](0),
1439 face_quadrature_points[q_point](1));
1441 face_quadrature_points[q_point](0),
1443 face_quadrature_points[q_point](1));
1445 face_quadrature_points[q_point](0),
1446 face_quadrature_points[q_point](1),
1449 for (
unsigned int j = 0; j < 2; ++j)
1450 for (
unsigned int k = 0; k < 2; ++k)
1451 for (
unsigned int l = 0; l <= deg; ++l)
1453 tmp(2 * (j + 2 * k)) -=
1454 this->restriction[index][i + 2 * (2 * j + k)](
1455 (i + 4 * j) * this->degree + l, dof) *
1456 this->shape_value_component(
1457 (i + 4 * j) * this->degree + l,
1460 tmp(2 * (j + 2 * k) + 1) -=
1461 this->restriction[index][i + 2 * (2 * j + k)](
1462 (i + 2 * (k + 4)) * this->degree + l, dof) *
1463 this->shape_value_component(
1464 (i + 2 * (k + 4)) * this->degree + l,
1467 tmp(2 * (j + 2 * (k + 2))) -=
1468 this->restriction[index][2 * (i + 2 * j) + k](
1469 (2 * (i + 4) + k) * this->degree + l, dof) *
1470 this->shape_value_component(
1471 (2 * (i + 4) + k) * this->degree + l,
1474 tmp(2 * (j + 2 * k) + 9) -=
1475 this->restriction[index][2 * (i + 2 * j) + k](
1476 (i + 4 * j + 2) * this->degree + l, dof) *
1477 this->shape_value_component(
1478 (i + 4 * j + 2) * this->degree + l,
1481 tmp(2 * (j + 2 * (k + 4))) -=
1482 this->restriction[index][2 * (2 * i + j) + k](
1483 (4 * i + j + 2) * this->degree + l, dof) *
1484 this->shape_value_component(
1485 (4 * i + j + 2) * this->degree + l,
1488 tmp(2 * (j + 2 * k) + 17) -=
1489 this->restriction[index][2 * (2 * i + j) + k](
1490 (4 * i + k) * this->degree + l, dof) *
1491 this->shape_value_component(
1492 (4 * i + k) * this->degree + l,
1497 tmp *= face_quadrature.
weight(q_point);
1499 for (
unsigned int j = 0; j <= deg; ++j)
1501 const double L_j_0 = legendre_polynomials[j].value(
1502 face_quadrature_points[q_point](0));
1503 const double L_j_1 = legendre_polynomials[j].value(
1504 face_quadrature_points[q_point](1));
1506 for (
unsigned int k = 0; k < deg; ++k)
1508 const double l_k_0 =
1509 L_j_0 * lobatto_polynomials[k + 2].value(
1510 face_quadrature_points[q_point](1));
1511 const double l_k_1 =
1512 L_j_1 * lobatto_polynomials[k + 2].value(
1513 face_quadrature_points[q_point](0));
1515 for (
unsigned int l = 0; l < 4; ++l)
1517 system_rhs(j * deg + k, 2 * l) +=
1519 system_rhs(j * deg + k, 2 * l + 1) +=
1520 tmp(2 * l + 1) * l_k_1;
1521 system_rhs(j * deg + k, 2 * (l + 4)) +=
1522 tmp(2 * (l + 4)) * l_k_1;
1523 system_rhs(j * deg + k, 2 * l + 9) +=
1524 tmp(2 * l + 9) * l_k_0;
1525 system_rhs(j * deg + k, 2 * (l + 8)) +=
1526 tmp(2 * (l + 8)) * l_k_0;
1527 system_rhs(j * deg + k, 2 * l + 17) +=
1528 tmp(2 * l + 17) * l_k_1;
1534 system_matrix_inv.
mmult(solution, system_rhs);
1536 for (
unsigned int j = 0; j < 2; ++j)
1537 for (
unsigned int k = 0; k < 2; ++k)
1538 for (
unsigned int l = 0; l <= deg; ++l)
1539 for (
unsigned int m = 0; m < deg; ++m)
1541 if (std::abs(solution(l * deg + m,
1542 2 * (j + 2 * k))) > 1e-14)
1543 this->restriction[index][i + 2 * (2 * j + k)](
1544 (2 * i * this->degree + l) * deg + m +
1546 dof) = solution(l * deg + m, 2 * (j + 2 * k));
1548 if (std::abs(solution(l * deg + m,
1549 2 * (j + 2 * k) + 1)) >
1551 this->restriction[index][i + 2 * (2 * j + k)](
1552 ((2 * i + 1) * deg + m) * this->degree + l +
1555 solution(l * deg + m, 2 * (j + 2 * k) + 1);
1557 if (std::abs(solution(l * deg + m,
1558 2 * (j + 2 * (k + 2)))) >
1560 this->restriction[index][2 * (i + 2 * j) + k](
1561 (2 * (i + 2) * this->degree + l) * deg + m +
1564 solution(l * deg + m, 2 * (j + 2 * (k + 2)));
1566 if (std::abs(solution(l * deg + m,
1567 2 * (j + 2 * k) + 9)) >
1569 this->restriction[index][2 * (i + 2 * j) + k](
1570 ((2 * i + 5) * deg + m) * this->degree + l +
1573 solution(l * deg + m, 2 * (j + 2 * k) + 9);
1575 if (std::abs(solution(l * deg + m,
1576 2 * (j + 2 * (k + 4)))) >
1578 this->restriction[index][2 * (2 * i + j) + k](
1579 (2 * (i + 4) * this->degree + l) * deg + m +
1582 solution(l * deg + m, 2 * (j + 2 * (k + 4)));
1584 if (std::abs(solution(l * deg + m,
1585 2 * (j + 2 * k) + 17)) >
1587 this->restriction[index][2 * (2 * i + j) + k](
1588 ((2 * i + 9) * deg + m) * this->degree + l +
1591 solution(l * deg + m, 2 * (j + 2 * k) + 17);
1596 const std::vector<Point<dim>> &quadrature_points =
1598 const unsigned int n_boundary_dofs =
1601 const unsigned int n_quadrature_points = quadrature.
size();
1605 n_quadrature_points);
1607 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
1610 const double weight = std::sqrt(quadrature.
weight(q_point));
1612 for (
unsigned int i = 0; i <= deg; ++i)
1615 weight * legendre_polynomials[i].value(
1616 quadrature_points[q_point](0));
1618 for (
unsigned int j = 0; j < deg; ++j)
1621 L_i * lobatto_polynomials[j + 2].value(
1622 quadrature_points[q_point](1));
1624 for (
unsigned int k = 0; k < deg; ++k)
1625 assembling_matrix((i * deg + j) * deg + k,
1627 l_j * lobatto_polynomials[k + 2].value(
1628 quadrature_points[q_point](2));
1634 assembling_matrix.
m());
1636 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
1637 system_matrix_inv.
reinit(system_matrix.m(), system_matrix.m());
1638 system_matrix_inv.
invert(system_matrix);
1641 solution.
reinit(system_matrix_inv.
m(), 24);
1642 system_rhs.
reinit(system_matrix_inv.
m(), 24);
1645 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
1649 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
1654 if (quadrature_points[q_point](0) < 0.5)
1656 if (quadrature_points[q_point](1) < 0.5)
1658 if (quadrature_points[q_point](2) < 0.5)
1661 2.0 * quadrature_points[q_point](0),
1662 2.0 * quadrature_points[q_point](1),
1663 2.0 * quadrature_points[q_point](2));
1665 tmp(0) += 2.0 * this->shape_value_component(
1666 dof, quadrature_point, 0);
1667 tmp(1) += 2.0 * this->shape_value_component(
1668 dof, quadrature_point, 1);
1669 tmp(2) += 2.0 * this->shape_value_component(
1670 dof, quadrature_point, 2);
1676 2.0 * quadrature_points[q_point](0),
1677 2.0 * quadrature_points[q_point](1),
1678 2.0 * quadrature_points[q_point](2) - 1.0);
1680 tmp(3) += 2.0 * this->shape_value_component(
1681 dof, quadrature_point, 0);
1682 tmp(4) += 2.0 * this->shape_value_component(
1683 dof, quadrature_point, 1);
1684 tmp(5) += 2.0 * this->shape_value_component(
1685 dof, quadrature_point, 2);
1689 else if (quadrature_points[q_point](2) < 0.5)
1692 2.0 * quadrature_points[q_point](0),
1693 2.0 * quadrature_points[q_point](1) - 1.0,
1694 2.0 * quadrature_points[q_point](2));
1696 tmp(6) += 2.0 * this->shape_value_component(
1697 dof, quadrature_point, 0);
1698 tmp(7) += 2.0 * this->shape_value_component(
1699 dof, quadrature_point, 1);
1700 tmp(8) += 2.0 * this->shape_value_component(
1701 dof, quadrature_point, 2);
1707 2.0 * quadrature_points[q_point](0),
1708 2.0 * quadrature_points[q_point](1) - 1.0,
1709 2.0 * quadrature_points[q_point](2) - 1.0);
1711 tmp(9) += 2.0 * this->shape_value_component(
1712 dof, quadrature_point, 0);
1713 tmp(10) += 2.0 * this->shape_value_component(
1714 dof, quadrature_point, 1);
1715 tmp(11) += 2.0 * this->shape_value_component(
1716 dof, quadrature_point, 2);
1720 else if (quadrature_points[q_point](1) < 0.5)
1722 if (quadrature_points[q_point](2) < 0.5)
1725 2.0 * quadrature_points[q_point](0) - 1.0,
1726 2.0 * quadrature_points[q_point](1),
1727 2.0 * quadrature_points[q_point](2));
1729 tmp(12) += 2.0 * this->shape_value_component(
1730 dof, quadrature_point, 0);
1731 tmp(13) += 2.0 * this->shape_value_component(
1732 dof, quadrature_point, 1);
1733 tmp(14) += 2.0 * this->shape_value_component(
1734 dof, quadrature_point, 2);
1740 2.0 * quadrature_points[q_point](0) - 1.0,
1741 2.0 * quadrature_points[q_point](1),
1742 2.0 * quadrature_points[q_point](2) - 1.0);
1744 tmp(15) += 2.0 * this->shape_value_component(
1745 dof, quadrature_point, 0);
1746 tmp(16) += 2.0 * this->shape_value_component(
1747 dof, quadrature_point, 1);
1748 tmp(17) += 2.0 * this->shape_value_component(
1749 dof, quadrature_point, 2);
1753 else if (quadrature_points[q_point](2) < 0.5)
1756 2.0 * quadrature_points[q_point](0) - 1.0,
1757 2.0 * quadrature_points[q_point](1) - 1.0,
1758 2.0 * quadrature_points[q_point](2));
1761 2.0 * this->shape_value_component(dof,
1765 2.0 * this->shape_value_component(dof,
1769 2.0 * this->shape_value_component(dof,
1777 2.0 * quadrature_points[q_point](0) - 1.0,
1778 2.0 * quadrature_points[q_point](1) - 1.0,
1779 2.0 * quadrature_points[q_point](2) - 1.0);
1782 2.0 * this->shape_value_component(dof,
1786 2.0 * this->shape_value_component(dof,
1790 2.0 * this->shape_value_component(dof,
1795 for (
unsigned int i = 0; i < 2; ++i)
1796 for (
unsigned int j = 0; j < 2; ++j)
1797 for (
unsigned int k = 0; k < 2; ++k)
1798 for (
unsigned int l = 0; l <= deg; ++l)
1800 tmp(3 * (i + 2 * (j + 2 * k))) -=
1801 this->restriction[index][2 * (2 * i + j) + k](
1802 (4 * i + j + 2) * this->degree + l, dof) *
1803 this->shape_value_component(
1804 (4 * i + j + 2) * this->degree + l,
1805 quadrature_points[q_point],
1807 tmp(3 * (i + 2 * (j + 2 * k)) + 1) -=
1808 this->restriction[index][2 * (2 * i + j) + k](
1809 (4 * i + k) * this->degree + l, dof) *
1810 this->shape_value_component(
1811 (4 * i + k) * this->degree + l,
1812 quadrature_points[q_point],
1814 tmp(3 * (i + 2 * (j + 2 * k)) + 2) -=
1815 this->restriction[index][2 * (2 * i + j) + k](
1816 (2 * (j + 4) + k) * this->degree + l, dof) *
1817 this->shape_value_component(
1818 (2 * (j + 4) + k) * this->degree + l,
1819 quadrature_points[q_point],
1822 for (
unsigned int m = 0; m < deg; ++m)
1824 tmp(3 * (i + 2 * (j + 2 * k))) -=
1825 this->restriction[index][2 * (2 * i + j) +
1827 ((2 * j + 5) * deg + m) * this->degree +
1830 this->shape_value_component(
1831 ((2 * j + 5) * deg + m) * this->degree +
1833 quadrature_points[q_point],
1835 tmp(3 * (i + 2 * (j + 2 * k))) -=
1836 this->restriction[index][2 * (2 * i + j) +
1838 (2 * (i + 4) * this->degree + l) * deg +
1841 this->shape_value_component(
1842 (2 * (i + 4) * this->degree + l) * deg +
1844 quadrature_points[q_point],
1846 tmp(3 * (i + 2 * (j + 2 * k)) + 1) -=
1847 this->restriction[index][2 * (2 * i + j) +
1849 (2 * k * this->degree + l) * deg + m +
1852 this->shape_value_component(
1853 (2 * k * this->degree + l) * deg + m +
1855 quadrature_points[q_point],
1857 tmp(3 * (i + 2 * (j + 2 * k)) + 1) -=
1858 this->restriction[index][2 * (2 * i + j) +
1860 ((2 * i + 9) * deg + m) * this->degree +
1863 this->shape_value_component(
1864 ((2 * i + 9) * deg + m) * this->degree +
1866 quadrature_points[q_point],
1868 tmp(3 * (i + 2 * (j + 2 * k)) + 2) -=
1869 this->restriction[index][2 * (2 * i + j) +
1871 ((2 * k + 1) * deg + m) * this->degree +
1874 this->shape_value_component(
1875 ((2 * k + 1) * deg + m) * this->degree +
1877 quadrature_points[q_point],
1879 tmp(3 * (i + 2 * (j + 2 * k)) + 2) -=
1880 this->restriction[index][2 * (2 * i + j) +
1882 (2 * (j + 2) * this->degree + l) * deg +
1885 this->shape_value_component(
1886 (2 * (j + 2) * this->degree + l) * deg +
1888 quadrature_points[q_point],
1893 tmp *= quadrature.
weight(q_point);
1895 for (
unsigned int i = 0; i <= deg; ++i)
1897 const double L_i_0 = legendre_polynomials[i].value(
1898 quadrature_points[q_point](0));
1899 const double L_i_1 = legendre_polynomials[i].value(
1900 quadrature_points[q_point](1));
1901 const double L_i_2 = legendre_polynomials[i].value(
1902 quadrature_points[q_point](2));
1904 for (
unsigned int j = 0; j < deg; ++j)
1906 const double l_j_0 =
1907 L_i_0 * lobatto_polynomials[j + 2].value(
1908 quadrature_points[q_point](1));
1909 const double l_j_1 =
1910 L_i_1 * lobatto_polynomials[j + 2].value(
1911 quadrature_points[q_point](0));
1912 const double l_j_2 =
1913 L_i_2 * lobatto_polynomials[j + 2].value(
1914 quadrature_points[q_point](0));
1916 for (
unsigned int k = 0; k < deg; ++k)
1918 const double l_k_0 =
1919 l_j_0 * lobatto_polynomials[k + 2].value(
1920 quadrature_points[q_point](2));
1921 const double l_k_1 =
1922 l_j_1 * lobatto_polynomials[k + 2].value(
1923 quadrature_points[q_point](2));
1924 const double l_k_2 =
1925 l_j_2 * lobatto_polynomials[k + 2].value(
1926 quadrature_points[q_point](1));
1928 for (
unsigned int l = 0; l < 8; ++l)
1930 system_rhs((i * deg + j) * deg + k,
1931 3 * l) += tmp(3 * l) * l_k_0;
1932 system_rhs((i * deg + j) * deg + k,
1934 tmp(3 * l + 1) * l_k_1;
1935 system_rhs((i * deg + j) * deg + k,
1937 tmp(3 * l + 2) * l_k_2;
1944 system_matrix_inv.
mmult(solution, system_rhs);
1946 for (
unsigned int i = 0; i < 2; ++i)
1947 for (
unsigned int j = 0; j < 2; ++j)
1948 for (
unsigned int k = 0; k < 2; ++k)
1949 for (
unsigned int l = 0; l <= deg; ++l)
1950 for (
unsigned int m = 0; m < deg; ++m)
1951 for (
unsigned int n = 0; n < deg; ++n)
1954 solution((l * deg + m) * deg + n,
1955 3 * (i + 2 * (j + 2 * k)))) >
1957 this->restriction[index][2 * (2 * i + j) + k](
1958 (l * deg + m) * deg + n + n_boundary_dofs,
1959 dof) = solution((l * deg + m) * deg + n,
1960 3 * (i + 2 * (j + 2 * k)));
1963 solution((l * deg + m) * deg + n,
1964 3 * (i + 2 * (j + 2 * k)) + 1)) >
1966 this->restriction[index][2 * (2 * i + j) + k](
1967 (l + (m + deg) * this->degree) * deg + n +
1970 solution((l * deg + m) * deg + n,
1971 3 * (i + 2 * (j + 2 * k)) + 1);
1974 solution((l * deg + m) * deg + n,
1975 3 * (i + 2 * (j + 2 * k)) + 2)) >
1977 this->restriction[index][2 * (2 * i + j) + k](
1979 ((m + 2 * deg) * deg + n) * this->degree +
1982 solution((l * deg + m) * deg + n,
1983 3 * (i + 2 * (j + 2 * k)) + 2);
1999 std::vector<unsigned int>
2002 std::vector<unsigned int> dpo(dim + 1);
2011 dpo[1] = degree + 1;
2012 dpo[2] = 2 * degree * (degree + 1);
2015 dpo[3] = 3 * degree * degree * (degree + 1);
2037 const unsigned int face_index)
const 2039 Assert(shape_index < this->dofs_per_cell,
2044 const unsigned int deg = this->degree - 1;
2051 if (!((shape_index > deg) && (shape_index < 2 * this->degree)))
2058 if ((shape_index > deg) &&
2067 if (shape_index < 3 * this->degree)
2074 if (!((shape_index >= 2 * this->degree) &&
2075 (shape_index < 3 * this->degree)))
2092 if (((shape_index > deg) && (shape_index < 2 * this->degree)) ||
2093 ((shape_index >= 5 * this->degree) &&
2094 (shape_index < 6 * this->degree)) ||
2095 ((shape_index >= 9 * this->degree) &&
2096 (shape_index < 10 * this->degree)) ||
2097 ((shape_index >= 11 * this->degree) &&
2123 if (((shape_index > deg) && (shape_index < 4 * this->degree)) ||
2124 ((shape_index >= 5 * this->degree) &&
2125 (shape_index < 8 * this->degree)) ||
2126 ((shape_index >= 9 * this->degree) &&
2127 (shape_index < 10 * this->degree)) ||
2128 ((shape_index >= 11 * this->degree) &&
2154 if ((shape_index < 3 * this->degree) ||
2155 ((shape_index >= 4 * this->degree) &&
2156 (shape_index < 7 * this->degree)) ||
2157 ((shape_index >= 8 * this->degree) &&
2158 (shape_index < 10 * this->degree)) ||
2182 if ((shape_index < 2 * this->degree) ||
2183 ((shape_index >= 3 * this->degree) &&
2184 (shape_index < 6 * this->degree)) ||
2185 ((shape_index >= 7 * this->degree) &&
2186 (shape_index < 8 * this->degree)) ||
2187 ((shape_index >= 10 * this->degree) &&
2213 if ((shape_index < 4 * this->degree) ||
2214 ((shape_index >= 8 * this->degree) &&
2235 if (((shape_index >= 4 * this->degree) &&
2278 const unsigned int codim)
const 2288 if (this->degree < fe_nedelec_other->degree)
2290 else if (this->degree == fe_nedelec_other->degree)
2298 if (fe_nothing->is_dominating())
2319 std::vector<std::pair<unsigned int, unsigned int>>
2324 return std::vector<std::pair<unsigned int, unsigned int>>();
2328 std::vector<std::pair<unsigned int, unsigned int>>
2343 std::vector<std::pair<unsigned int, unsigned int>> identities;
2345 for (
unsigned int i = 0;
2346 i < std::min(fe_nedelec_other->degree, this->degree);
2348 identities.emplace_back(i, i);
2359 return std::vector<std::pair<unsigned int, unsigned int>>();
2365 return std::vector<std::pair<unsigned int, unsigned int>>();
2370 std::vector<std::pair<unsigned int, unsigned int>>
2385 const unsigned int p = fe_nedelec_other->degree;
2386 const unsigned int q = this->degree;
2387 const unsigned int p_min = std::min(p, q);
2388 std::vector<std::pair<unsigned int, unsigned int>> identities;
2390 for (
unsigned int i = 0; i < p_min; ++i)
2391 for (
unsigned int j = 0; j < p_min - 1; ++j)
2393 identities.emplace_back(i * (q - 1) + j, i * (p - 1) + j);
2394 identities.emplace_back(i + (j + q - 1) * q, i + (j + p - 1) * p);
2406 return std::vector<std::pair<unsigned int, unsigned int>>();
2412 return std::vector<std::pair<unsigned int, unsigned int>>();
2437 Assert(interpolation_matrix.
n() == this->dofs_per_face,
2458 interpolation_matrix = 0;
2462 for (
unsigned int i = 0; i < this->degree; ++i)
2463 interpolation_matrix(i, i) = 1.0;
2473 const unsigned int p = source_fe.
degree;
2474 const unsigned int q = this->degree;
2476 for (
unsigned int i = 0; i < q; ++i)
2478 for (
unsigned int j = 1; j < GeometryInfo<dim>::lines_per_face; ++j)
2479 interpolation_matrix(j * p + i, j * q + i) = 1.0;
2481 for (
unsigned int j = 0; j < q - 1; ++j)
2486 i * (q - 1) + j) = 1.0;
2490 (j + q - 1) * q) = 1.0;
2529 const unsigned int subface,
2540 Assert(interpolation_matrix.
n() == this->dofs_per_face,
2561 interpolation_matrix = 0.0;
2565 const std::vector<Point<1>> &edge_quadrature_points =
2567 const unsigned int n_edge_quadrature_points = edge_quadrature.
size();
2573 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2574 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
2578 0.0, 0.5 * (edge_quadrature_points[q_point](0) + subface));
2580 interpolation_matrix(0, dof) +=
2581 0.5 * edge_quadrature.
weight(q_point) *
2582 this->shape_value_component(dof, quadrature_point, 1);
2585 if (source_fe.
degree > 1)
2587 const std::vector<Polynomials::Polynomial<double>>
2588 &legendre_polynomials =
2596 n_edge_quadrature_points);
2598 for (
unsigned int q_point = 0;
2599 q_point < n_edge_quadrature_points;
2602 const double weight =
2603 std::sqrt(edge_quadrature.
weight(q_point));
2605 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2606 assembling_matrix(i, q_point) =
2607 weight * legendre_polynomials[i + 1].value(
2608 edge_quadrature_points[q_point](0));
2614 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
2615 system_matrix_inv.
invert(system_matrix);
2621 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2625 for (
unsigned int q_point = 0;
2626 q_point < n_edge_quadrature_points;
2631 0.5 * (edge_quadrature_points[q_point](0) + subface));
2633 0.0, edge_quadrature_points[q_point](0));
2635 edge_quadrature.
weight(q_point) *
2636 (0.5 * this->shape_value_component(dof,
2639 interpolation_matrix(0, dof) *
2644 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2646 tmp * legendre_polynomials[i + 1].value(
2647 edge_quadrature_points[q_point](0));
2650 system_matrix_inv.
vmult(solution, system_rhs);
2652 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2653 if (std::abs(solution(i)) > 1e-14)
2654 interpolation_matrix(i + 1, dof) = solution(i);
2663 const double shifts[4][2] = {{0.0, 0.0},
2668 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2669 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
2672 const double weight = 0.5 * edge_quadrature.
weight(q_point);
2674 for (
unsigned int i = 0; i < 2; ++i)
2677 0.5 * (i + shifts[subface][0]),
2678 0.5 * (edge_quadrature_points[q_point](0) +
2679 shifts[subface][1]),
2682 interpolation_matrix(i * source_fe.
degree, dof) +=
2684 this->shape_value_component(
2685 this->face_to_cell_index(dof, 4), quadrature_point, 1);
2687 Point<dim>(0.5 * (edge_quadrature_points[q_point](0) +
2688 shifts[subface][0]),
2689 0.5 * (i + shifts[subface][1]),
2691 interpolation_matrix((i + 2) * source_fe.
degree, dof) +=
2693 this->shape_value_component(
2694 this->face_to_cell_index(dof, 4), quadrature_point, 0);
2698 if (source_fe.
degree > 1)
2700 const std::vector<Polynomials::Polynomial<double>>
2701 &legendre_polynomials =
2709 n_edge_quadrature_points);
2711 for (
unsigned int q_point = 0;
2712 q_point < n_edge_quadrature_points;
2715 const double weight =
2716 std::sqrt(edge_quadrature.
weight(q_point));
2718 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2719 assembling_matrix(i, q_point) =
2720 weight * legendre_polynomials[i + 1].value(
2721 edge_quadrature_points[q_point](0));
2727 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
2728 system_matrix_inv.
invert(system_matrix);
2737 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2741 for (
unsigned int q_point = 0;
2742 q_point < n_edge_quadrature_points;
2745 const double weight = edge_quadrature.
weight(q_point);
2747 for (
unsigned int i = 0; i < 2; ++i)
2750 0.5 * (i + shifts[subface][0]),
2751 0.5 * (edge_quadrature_points[q_point](0) +
2752 shifts[subface][1]),
2755 i, edge_quadrature_points[q_point](0), 0.0);
2759 (0.5 * this->shape_value_component(
2760 this->face_to_cell_index(dof, 4),
2763 interpolation_matrix(i * source_fe.
degree, dof) *
2765 i * source_fe.
degree, quadrature_point_1, 1));
2766 quadrature_point_0 =
2768 (edge_quadrature_points[q_point](0) +
2769 shifts[subface][0]),
2770 0.5 * (i + shifts[subface][1]),
2772 quadrature_point_1 =
2773 Point<dim>(edge_quadrature_points[q_point](0),
2778 (0.5 * this->shape_value_component(
2779 this->face_to_cell_index(dof, 4),
2782 interpolation_matrix((i + 2) * source_fe.
degree,
2785 (i + 2) * source_fe.
degree,
2790 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2792 const double L_i = legendre_polynomials[i + 1].value(
2793 edge_quadrature_points[q_point](0));
2795 for (
unsigned int j = 0;
2796 j < GeometryInfo<dim>::lines_per_face;
2798 system_rhs(i, j) += tmp(j) * L_i;
2802 system_matrix_inv.
mmult(solution, system_rhs);
2804 for (
unsigned int i = 0;
2805 i < GeometryInfo<dim>::lines_per_face;
2807 for (
unsigned int j = 0; j < source_fe.
degree - 1; ++j)
2808 if (std::abs(solution(j, i)) > 1e-14)
2809 interpolation_matrix(i * source_fe.
degree + j + 1,
2810 dof) = solution(j, i);
2814 const std::vector<Point<2>> &quadrature_points =
2816 const std::vector<Polynomials::Polynomial<double>>
2817 &lobatto_polynomials =
2820 const unsigned int n_boundary_dofs =
2822 const unsigned int n_quadrature_points = quadrature.
size();
2827 n_quadrature_points);
2829 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
2832 const double weight = std::sqrt(quadrature.
weight(q_point));
2834 for (
unsigned int i = 0; i < source_fe.
degree; ++i)
2837 weight * legendre_polynomials[i].value(
2838 quadrature_points[q_point](0));
2840 for (
unsigned int j = 0; j < source_fe.
degree - 1; ++j)
2841 assembling_matrix(i * (source_fe.
degree - 1) + j,
2843 L_i * lobatto_polynomials[j + 2].value(
2844 quadrature_points[q_point](1));
2849 assembling_matrix.
m());
2851 assembling_matrix.
mTmult(system_matrix, assembling_matrix);
2852 system_matrix_inv.
reinit(system_matrix.m(), system_matrix.m());
2853 system_matrix_inv.
invert(system_matrix);
2856 solution.
reinit(system_matrix_inv.
m(), 2);
2857 system_rhs.
reinit(system_matrix_inv.
m(), 2);
2860 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2864 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
2869 (quadrature_points[q_point](0) + shifts[subface][0]),
2871 (quadrature_points[q_point](1) + shifts[subface][1]),
2873 tmp(0) = 0.5 * this->shape_value_component(
2874 this->face_to_cell_index(dof, 4),
2877 tmp(1) = 0.5 * this->shape_value_component(
2878 this->face_to_cell_index(dof, 4),
2883 quadrature_points[q_point](1),
2886 for (
unsigned int i = 0; i < 2; ++i)
2887 for (
unsigned int j = 0; j < source_fe.
degree; ++j)
2889 tmp(0) -= interpolation_matrix(
2890 (i + 2) * source_fe.
degree + j, dof) *
2892 (i + 2) * source_fe.
degree + j,
2896 interpolation_matrix(i * source_fe.
degree + j,
2899 i * source_fe.
degree + j, quadrature_point, 1);
2902 tmp *= quadrature.
weight(q_point);
2904 for (
unsigned int i = 0; i < source_fe.
degree; ++i)
2906 const double L_i_0 = legendre_polynomials[i].value(
2907 quadrature_points[q_point](0));
2908 const double L_i_1 = legendre_polynomials[i].value(
2909 quadrature_points[q_point](1));
2911 for (
unsigned int j = 0; j < source_fe.
degree - 1;
2914 system_rhs(i * (source_fe.
degree - 1) + j, 0) +=
2916 lobatto_polynomials[j + 2].value(
2917 quadrature_points[q_point](1));
2918 system_rhs(i * (source_fe.
degree - 1) + j, 1) +=
2920 lobatto_polynomials[j + 2].value(
2921 quadrature_points[q_point](0));
2926 system_matrix_inv.
mmult(solution, system_rhs);
2928 for (
unsigned int i = 0; i < source_fe.
degree; ++i)
2929 for (
unsigned int j = 0; j < source_fe.
degree - 1; ++j)
2931 if (std::abs(solution(i * (source_fe.
degree - 1) + j,
2933 interpolation_matrix(i * (source_fe.
degree - 1) + j +
2936 solution(i * (source_fe.
degree - 1) + j, 0);
2938 if (std::abs(solution(i * (source_fe.
degree - 1) + j,
2940 interpolation_matrix(
2943 dof) = solution(i * (source_fe.
degree - 1) + j, 1);
2959 const unsigned int child,
2968 "Prolongation matrices are only available for refined cells!"));
2975 if (this->prolongation[refinement_case - 1][child].n() == 0)
2977 std::lock_guard<std::mutex> lock(this->mutex);
2980 if (this->prolongation[refinement_case - 1][child].n() ==
2981 this->dofs_per_cell)
2982 return this->prolongation[refinement_case - 1][child];
2993 #ifdef DEBUG_NEDELEC 2994 deallog <<
"Embedding" << std::endl;
3002 internal::FE_Nedelec::get_embedding_computation_tolerance(
3004 #ifdef DEBUG_NEDELEC 3005 deallog <<
"Restriction" << std::endl;
3013 return this->prolongation[refinement_case - 1][child];
3019 const unsigned int child,
3028 "Restriction matrices are only available for refined cells!"));
3037 if (this->restriction[refinement_case - 1][child].n() == 0)
3039 std::lock_guard<std::mutex> lock(this->mutex);
3042 if (this->restriction[refinement_case - 1][child].n() ==
3043 this->dofs_per_cell)
3044 return this->restriction[refinement_case - 1][child];
3055 #ifdef DEBUG_NEDELEC 3056 deallog <<
"Embedding" << std::endl;
3064 internal::FE_Nedelec::get_embedding_computation_tolerance(
3066 #ifdef DEBUG_NEDELEC 3067 deallog <<
"Restriction" << std::endl;
3075 return this->restriction[refinement_case - 1][child];
3089 std::vector<double> & nodal_values)
const 3091 const unsigned int deg = this->degree - 1;
3092 Assert(support_point_values.size() == this->generalized_support_points.size(),
3094 this->generalized_support_points.size()));
3098 Assert(nodal_values.size() == this->dofs_per_cell,
3100 std::fill(nodal_values.begin(), nodal_values.end(), 0.0);
3108 const QGauss<dim - 1> reference_edge_quadrature(this->degree);
3109 const unsigned int n_edge_points = reference_edge_quadrature.size();
3111 for (
unsigned int i = 0; i < 2; ++i)
3112 for (
unsigned int j = 0; j < 2; ++j)
3114 for (
unsigned int q_point = 0; q_point < n_edge_points;
3116 nodal_values[(i + 2 * j) * this->degree] +=
3117 reference_edge_quadrature.weight(q_point) *
3118 support_point_values[q_point + (i + 2 * j) * n_edge_points]
3124 if (std::abs(nodal_values[(i + 2 * j) * this->degree]) < 1e-14)
3125 nodal_values[(i + 2 * j) * this->degree] = 0.0;
3138 if (this->degree - 1 > 1)
3143 const std::vector<Polynomials::Polynomial<double>>
3144 &lobatto_polynomials =
3148 std::vector<Polynomials::Polynomial<double>>
3149 lobatto_polynomials_grad(this->degree);
3151 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size(); ++i)
3152 lobatto_polynomials_grad[i] =
3153 lobatto_polynomials[i + 1].derivative();
3158 for (
unsigned int i = 0; i < system_matrix.
m(); ++i)
3159 for (
unsigned int j = 0; j < system_matrix.
n(); ++j)
3160 for (
unsigned int q_point = 0; q_point < n_edge_points;
3162 system_matrix(i, j) +=
3163 boundary_weights(q_point, j) *
3164 lobatto_polynomials_grad[i + 1].value(
3165 this->generalized_face_support_points[q_point](0));
3170 system_matrix_inv.
invert(system_matrix);
3177 for (
unsigned int line = 0;
3178 line < GeometryInfo<dim>::lines_per_cell;
3184 for (
unsigned int q_point = 0; q_point < n_edge_points;
3188 support_point_values[line * n_edge_points + q_point]
3189 [line_coordinate[line]] -
3190 nodal_values[line * this->degree] *
3191 this->shape_value_component(
3192 line * this->degree,
3193 this->generalized_support_points[line *
3196 line_coordinate[line]);
3198 for (
unsigned int i = 0; i < system_rhs.size(); ++i)
3199 system_rhs(i) += boundary_weights(q_point, i) * tmp;
3202 system_matrix_inv.
vmult(solution, system_rhs);
3208 for (
unsigned int i = 0; i < solution.size(); ++i)
3209 if (std::abs(solution(i)) > 1e-14)
3210 nodal_values[line * this->degree + i + 1] = solution(i);
3222 const QGauss<dim> reference_quadrature(this->degree);
3223 const unsigned int n_interior_points =
3224 reference_quadrature.
size();
3225 const std::vector<Polynomials::Polynomial<double>>
3226 &legendre_polynomials =
3230 system_matrix.
reinit((this->degree - 1) * this->degree,
3231 (this->degree - 1) * this->degree);
3234 for (
unsigned int i = 0; i < this->degree; ++i)
3235 for (
unsigned int j = 0; j < this->degree - 1; ++j)
3236 for (
unsigned int k = 0; k < this->degree; ++k)
3237 for (
unsigned int l = 0; l < this->degree - 1; ++l)
3238 for (
unsigned int q_point = 0;
3239 q_point < n_interior_points;
3241 system_matrix(i * (this->degree - 1) + j,
3242 k * (this->degree - 1) + l) +=
3243 reference_quadrature.
weight(q_point) *
3244 legendre_polynomials[i].value(
3245 this->generalized_support_points
3247 n_edge_points](0)) *
3248 lobatto_polynomials[j + 2].value(
3249 this->generalized_support_points
3251 n_edge_points](1)) *
3252 lobatto_polynomials_grad[k].value(
3253 this->generalized_support_points
3255 n_edge_points](0)) *
3256 lobatto_polynomials[l + 2].value(
3257 this->generalized_support_points
3261 system_matrix_inv.
reinit(system_matrix.
m(), system_matrix.
m());
3262 system_matrix_inv.
invert(system_matrix);
3266 system_rhs.reinit(system_matrix_inv.
m());
3269 for (
unsigned int q_point = 0; q_point < n_interior_points;
3273 support_point_values[q_point +
3277 for (
unsigned int i = 0; i < 2; ++i)
3278 for (
unsigned int j = 0; j <= deg; ++j)
3279 tmp -= nodal_values[(i + 2) * this->degree + j] *
3280 this->shape_value_component(
3281 (i + 2) * this->degree + j,
3282 this->generalized_support_points
3287 for (
unsigned int i = 0; i <= deg; ++i)
3288 for (
unsigned int j = 0; j < deg; ++j)
3289 system_rhs(i * deg + j) +=
3290 reference_quadrature.
weight(q_point) * tmp *
3291 lobatto_polynomials_grad[i].value(
3292 this->generalized_support_points
3294 n_edge_points](0)) *
3295 lobatto_polynomials[j + 2].value(
3296 this->generalized_support_points
3301 solution.reinit(system_matrix.
m());
3302 system_matrix_inv.
vmult(solution, system_rhs);
3308 for (
unsigned int i = 0; i <= deg; ++i)
3309 for (
unsigned int j = 0; j < deg; ++j)
3310 if (std::abs(solution(i * deg + j)) > 1e-14)
3313 solution(i * deg + j);
3320 for (
unsigned int q_point = 0; q_point < n_interior_points;
3324 support_point_values[q_point +
3328 for (
unsigned int i = 0; i < 2; ++i)
3329 for (
unsigned int j = 0; j <= deg; ++j)
3330 tmp -= nodal_values[i * this->degree + j] *
3331 this->shape_value_component(
3332 i * this->degree + j,
3333 this->generalized_support_points
3338 for (
unsigned int i = 0; i <= deg; ++i)
3339 for (
unsigned int j = 0; j < deg; ++j)
3340 system_rhs(i * deg + j) +=
3341 reference_quadrature.
weight(q_point) * tmp *
3342 lobatto_polynomials_grad[i].value(
3343 this->generalized_support_points
3345 n_edge_points](1)) *
3346 lobatto_polynomials[j + 2].value(
3347 this->generalized_support_points
3352 system_matrix_inv.
vmult(solution, system_rhs);
3358 for (
unsigned int i = 0; i <= deg; ++i)
3359 for (
unsigned int j = 0; j < deg; ++j)
3360 if (std::abs(solution(i * deg + j)) > 1e-14)
3363 this->degree] = solution(i * deg + j);
3373 const QGauss<1> reference_edge_quadrature(this->degree);
3374 const unsigned int n_edge_points = reference_edge_quadrature.
size();
3376 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
3378 for (
unsigned int i = 0; i < 4; ++i)
3379 nodal_values[(i + 8) * this->degree] +=
3380 reference_edge_quadrature.
weight(q_point) *
3381 support_point_values[q_point + (i + 8) * n_edge_points][2];
3383 for (
unsigned int i = 0; i < 2; ++i)
3384 for (
unsigned int j = 0; j < 2; ++j)
3385 for (
unsigned int k = 0; k < 2; ++k)
3386 nodal_values[(i + 2 * (2 * j + k)) * this->degree] +=
3387 reference_edge_quadrature.
weight(q_point) *
3388 support_point_values[q_point + (i + 2 * (2 * j + k)) *
3389 n_edge_points][1 - k];
3396 for (
unsigned int i = 0; i < 4; ++i)
3397 if (std::abs(nodal_values[(i + 8) * this->degree]) < 1e-14)
3398 nodal_values[(i + 8) * this->degree] = 0.0;
3400 for (
unsigned int i = 0; i < 2; ++i)
3401 for (
unsigned int j = 0; j < 2; ++j)
3402 for (
unsigned int k = 0; k < 2; ++k)
3404 nodal_values[(i + 2 * (2 * j + k)) * this->degree]) <
3406 nodal_values[(i + 2 * (2 * j + k)) * this->degree] = 0.0;
3417 if (this->degree > 1)
3422 const std::vector<Polynomials::Polynomial<double>>
3423 &lobatto_polynomials =
3427 std::vector<Polynomials::Polynomial<double>>
3428 lobatto_polynomials_grad(this->degree);
3430 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size(); ++i)
3431 lobatto_polynomials_grad[i] =
3432 lobatto_polynomials[i + 1].derivative();
3437 for (
unsigned int i = 0; i < system_matrix.
m(); ++i)
3438 for (
unsigned int j = 0; j < system_matrix.
n(); ++j)
3439 for (
unsigned int q_point = 0; q_point < n_edge_points;
3441 system_matrix(i, j) +=
3442 boundary_weights(q_point, j) *
3443 lobatto_polynomials_grad[i + 1].value(
3444 this->generalized_face_support_points[q_point](1));
3449 system_matrix_inv.
invert(system_matrix);
3453 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2};
3457 for (
unsigned int line = 0;
3458 line < GeometryInfo<dim>::lines_per_cell;
3464 for (
unsigned int q_point = 0; q_point < this->degree;
3468 support_point_values[line * this->degree + q_point]
3469 [line_coordinate[line]] -
3470 nodal_values[line * this->degree] *
3471 this->shape_value_component(
3472 line * this->degree,
3474 ->generalized_support_points[line * this->degree +
3476 line_coordinate[line]);
3478 for (
unsigned int i = 0; i < system_rhs.size(); ++i)
3479 system_rhs(i) += boundary_weights(q_point, i) * tmp;
3482 system_matrix_inv.
vmult(solution, system_rhs);
3488 for (
unsigned int i = 0; i < solution.size(); ++i)
3489 if (std::abs(solution(i)) > 1e-14)
3490 nodal_values[line * this->degree + i + 1] = solution(i);
3501 const std::vector<Polynomials::Polynomial<double>>
3502 &legendre_polynomials =
3505 const unsigned int n_face_points = n_edge_points * n_edge_points;
3507 system_matrix.
reinit((this->degree - 1) * this->degree,
3508 (this->degree - 1) * this->degree);
3511 for (
unsigned int i = 0; i < this->degree; ++i)
3512 for (
unsigned int j = 0; j < this->degree - 1; ++j)
3513 for (
unsigned int k = 0; k < this->degree; ++k)
3514 for (
unsigned int l = 0; l < this->degree - 1; ++l)
3515 for (
unsigned int q_point = 0; q_point < n_face_points;
3517 system_matrix(i * (this->degree - 1) + j,
3518 k * (this->degree - 1) + l) +=
3519 boundary_weights(q_point + n_edge_points,
3520 2 * (k * (this->degree - 1) + l)) *
3521 legendre_polynomials[i].value(
3522 this->generalized_face_support_points
3523 [q_point + 4 * n_edge_points](0)) *
3524 lobatto_polynomials[j + 2].value(
3525 this->generalized_face_support_points
3526 [q_point + 4 * n_edge_points](1));
3528 system_matrix_inv.
reinit(system_matrix.
m(), system_matrix.
m());
3529 system_matrix_inv.
invert(system_matrix);
3530 solution.reinit(system_matrix.
m());
3531 system_rhs.reinit(system_matrix.
m());
3535 {1, 2}, {1, 2}, {2, 0}, {2, 0}, {0, 1}, {0, 1}};
3545 for (
unsigned int face = 0;
3546 face < GeometryInfo<dim>::faces_per_cell;
3554 for (
unsigned int q_point = 0; q_point < n_face_points;
3558 support_point_values[q_point +
3561 [face_coordinates[face][0]];
3563 for (
unsigned int i = 0; i < 2; ++i)
3564 for (
unsigned int j = 0; j <= deg; ++j)
3566 nodal_values[edge_indices[face][i] * this->degree +
3568 this->shape_value_component(
3569 edge_indices[face][i] * this->degree + j,
3570 this->generalized_support_points
3573 face_coordinates[face][0]);
3575 for (
unsigned int i = 0; i <= deg; ++i)
3576 for (
unsigned int j = 0; j < deg; ++j)
3577 system_rhs(i * deg + j) +=
3578 boundary_weights(q_point + n_edge_points,
3579 2 * (i * deg + j)) *
3583 system_matrix_inv.
vmult(solution, system_rhs);
3589 for (
unsigned int i = 0; i <= deg; ++i)
3590 for (
unsigned int j = 0; j < deg; ++j)
3591 if (std::abs(solution(i * deg + j)) > 1e-14)
3592 nodal_values[(2 * face * this->degree + i +
3596 solution(i * deg + j);
3603 for (
unsigned int q_point = 0; q_point < n_face_points;
3607 support_point_values[q_point +
3610 [face_coordinates[face][1]];
3612 for (
unsigned int i = 2;
3613 i < GeometryInfo<dim>::lines_per_face;
3615 for (
unsigned int j = 0; j <= deg; ++j)
3617 nodal_values[edge_indices[face][i] * this->degree +
3619 this->shape_value_component(
3620 edge_indices[face][i] * this->degree + j,
3621 this->generalized_support_points
3624 face_coordinates[face][1]);
3626 for (
unsigned int i = 0; i <= deg; ++i)
3627 for (
unsigned int j = 0; j < deg; ++j)
3628 system_rhs(i * deg + j) +=
3629 boundary_weights(q_point + n_edge_points,
3630 2 * (i * deg + j) + 1) *
3634 system_matrix_inv.
vmult(solution, system_rhs);
3640 for (
unsigned int i = 0; i <= deg; ++i)
3641 for (
unsigned int j = 0; j < deg; ++j)
3642 if (std::abs(solution(i * deg + j)) > 1e-14)
3643 nodal_values[((2 * face + 1) * deg + j +
3646 i] = solution(i * deg + j);
3654 const QGauss<dim> reference_quadrature(this->degree);
3655 const unsigned int n_interior_points =
3656 reference_quadrature.
size();
3660 system_matrix.
reinit(this->degree * deg * deg,
3661 this->degree * deg * deg);
3664 for (
unsigned int i = 0; i <= deg; ++i)
3665 for (
unsigned int j = 0; j < deg; ++j)
3666 for (
unsigned int k = 0; k < deg; ++k)
3667 for (
unsigned int l = 0; l <= deg; ++l)
3668 for (
unsigned int m = 0; m < deg; ++m)
3669 for (
unsigned int n = 0; n < deg; ++n)
3670 for (
unsigned int q_point = 0;
3671 q_point < n_interior_points;
3673 system_matrix((i * deg + j) * deg + k,
3674 (l * deg + m) * deg + n) +=
3675 reference_quadrature.
weight(q_point) *
3676 legendre_polynomials[i].value(
3677 this->generalized_support_points
3682 n_face_points](0)) *
3683 lobatto_polynomials[j + 2].value(
3684 this->generalized_support_points
3689 n_face_points](1)) *
3690 lobatto_polynomials[k + 2].value(
3691 this->generalized_support_points
3696 n_face_points](2)) *
3697 lobatto_polynomials_grad[l].value(
3698 this->generalized_support_points
3703 n_face_points](0)) *
3704 lobatto_polynomials[m + 2].value(
3705 this->generalized_support_points
3710 n_face_points](1)) *
3711 lobatto_polynomials[n + 2].value(
3712 this->generalized_support_points
3719 system_matrix_inv.
reinit(system_matrix.
m(), system_matrix.
m());
3720 system_matrix_inv.
invert(system_matrix);
3722 system_rhs.reinit(system_matrix.
m());
3725 for (
unsigned int q_point = 0; q_point < n_interior_points;
3729 support_point_values[q_point +
3735 for (
unsigned int i = 0; i <= deg; ++i)
3737 for (
unsigned int j = 0; j < 2; ++j)
3738 for (
unsigned int k = 0; k < 2; ++k)
3740 nodal_values[i + (j + 4 * k + 2) * this->degree] *
3741 this->shape_value_component(
3742 i + (j + 4 * k + 2) * this->degree,
3743 this->generalized_support_points
3751 for (
unsigned int j = 0; j < deg; ++j)
3752 for (
unsigned int k = 0; k < 4; ++k)
3754 nodal_values[(i + 2 * (k + 2) * this->degree +
3759 this->shape_value_component(
3760 (i + 2 * (k + 2) * this->degree +
3764 this->generalized_support_points
3773 for (
unsigned int i = 0; i <= deg; ++i)
3774 for (
unsigned int j = 0; j < deg; ++j)
3775 for (
unsigned int k = 0; k < deg; ++k)
3776 system_rhs((i * deg + j) * deg + k) +=
3777 reference_quadrature.
weight(q_point) * tmp *
3778 lobatto_polynomials_grad[i].value(
3779 this->generalized_support_points
3784 n_face_points](0)) *
3785 lobatto_polynomials[j + 2].value(
3786 this->generalized_support_points
3791 n_face_points](1)) *
3792 lobatto_polynomials[k + 2].value(
3793 this->generalized_support_points
3801 solution.reinit(system_rhs.size());
3802 system_matrix_inv.
vmult(solution, system_rhs);
3808 for (
unsigned int i = 0; i <= deg; ++i)
3809 for (
unsigned int j = 0; j < deg; ++j)
3810 for (
unsigned int k = 0; k < deg; ++k)
3811 if (std::abs(solution((i * deg + j) * deg + k)) > 1e-14)
3818 solution((i * deg + j) * deg + k);
3823 for (
unsigned int q_point = 0; q_point < n_interior_points;
3827 support_point_values[q_point +
3833 for (
unsigned int i = 0; i <= deg; ++i)
3834 for (
unsigned int j = 0; j < 2; ++j)
3836 for (
unsigned int k = 0; k < 2; ++k)
3837 tmp -= nodal_values[i + (4 * j + k) * this->degree] *
3838 this->shape_value_component(
3839 i + (4 * j + k) * this->degree,
3840 this->generalized_support_points
3848 for (
unsigned int k = 0; k < deg; ++k)
3850 nodal_values[(i + 2 * j * this->degree +
3855 this->shape_value_component(
3856 (i + 2 * j * this->degree +
3860 this->generalized_support_points
3868 ((2 * j + 9) * deg + k +
3871 this->shape_value_component(
3872 i + ((2 * j + 9) * deg + k +
3875 this->generalized_support_points
3884 for (
unsigned int i = 0; i <= deg; ++i)
3885 for (
unsigned int j = 0; j < deg; ++j)
3886 for (
unsigned int k = 0; k < deg; ++k)
3887 system_rhs((i * deg + j) * deg + k) +=
3888 reference_quadrature.
weight(q_point) * tmp *
3889 lobatto_polynomials_grad[i].value(
3890 this->generalized_support_points
3895 n_face_points](1)) *
3896 lobatto_polynomials[j + 2].value(
3897 this->generalized_support_points
3902 n_face_points](0)) *
3903 lobatto_polynomials[k + 2].value(
3904 this->generalized_support_points
3912 system_matrix_inv.
vmult(solution, system_rhs);
3918 for (
unsigned int i = 0; i <= deg; ++i)
3919 for (
unsigned int j = 0; j < deg; ++j)
3920 for (
unsigned int k = 0; k < deg; ++k)
3921 if (std::abs(solution((i * deg + j) * deg + k)) > 1e-14)
3922 nodal_values[((i + this->degree +
3929 solution((i * deg + j) * deg + k);
3934 for (
unsigned int q_point = 0; q_point < n_interior_points;
3938 support_point_values[q_point +
3944 for (
unsigned int i = 0; i <= deg; ++i)
3945 for (
unsigned int j = 0; j < 4; ++j)
3947 tmp -= nodal_values[i + (j + 8) * this->degree] *
3948 this->shape_value_component(
3949 i + (j + 8) * this->degree,
3950 this->generalized_support_points
3958 for (
unsigned int k = 0; k < deg; ++k)
3961 ((2 * j + 1) * deg + k +
3964 this->shape_value_component(
3965 i + ((2 * j + 1) * deg + k +
3968 this->generalized_support_points
3977 for (
unsigned int i = 0; i <= deg; ++i)
3978 for (
unsigned int j = 0; j < deg; ++j)
3979 for (
unsigned int k = 0; k < deg; ++k)
3980 system_rhs((i * deg + j) * deg + k) +=
3981 reference_quadrature.
weight(q_point) * tmp *
3982 lobatto_polynomials_grad[i].value(
3983 this->generalized_support_points
3988 n_face_points](2)) *
3989 lobatto_polynomials[j + 2].value(
3990 this->generalized_support_points
3995 n_face_points](0)) *
3996 lobatto_polynomials[k + 2].value(
3997 this->generalized_support_points
4005 system_matrix_inv.
vmult(solution, system_rhs);
4011 for (
unsigned int i = 0; i <= deg; ++i)
4012 for (
unsigned int j = 0; j < deg; ++j)
4013 for (
unsigned int k = 0; k < deg; ++k)
4014 if (std::abs(solution((i * deg + j) * deg + k)) > 1e-14)
4020 this->degree] = solution((i * deg + j) * deg + k);
4034 std::pair<Table<2, bool>, std::vector<unsigned int>>
4038 for (
unsigned int d = 0; d < dim; ++d)
4039 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
4040 constant_modes(d, i) =
true;
4041 std::vector<unsigned int> components;
4042 for (
unsigned int d = 0; d < dim; ++d)
4043 components.push_back(d);
4044 return std::pair<Table<2, bool>, std::vector<unsigned int>>(constant_modes,
4062 #include "fe_nedelec.inst" 4065 DEAL_II_NAMESPACE_CLOSE
virtual void get_subface_interpolation_matrix(const FiniteElement< dim > &source, const unsigned int subface, 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 void get_face_interpolation_matrix(const FiniteElement< dim > &source, FullMatrix< double > &matrix) const override
virtual bool hp_constraints_are_implemented() const override
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
FullMatrix< double > interface_constraints
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int p)
const std::vector< Point< dim > > & get_points() const
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int degree)
virtual FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim > &fe_other, const unsigned int codim=0) const override final
const unsigned int degree
const Point< dim > & point(const unsigned int i) const
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
#define AssertThrow(cond, exc)
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const override
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double >> &support_point_values, std::vector< double > &nodal_values) const override
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree, bool dg=false)
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim > &fe_other) const override
void initialize_support_points(const unsigned int order)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
std::vector< std::vector< FullMatrix< double > > > prolongation
void invert(const FullMatrix< number2 > &M)
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim > &fe_other) const override
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
virtual double shape_value_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const override
virtual std::string get_name() const =0
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim > &fe_other) const override
static unsigned int compute_n_pols(unsigned int degree)
unsigned int size() const
const unsigned int dofs_per_cell
void mmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
static Quadrature< dim > project_to_all_faces(const SubQuadrature &quadrature)
virtual std::size_t memory_consumption() const override
virtual std::string get_name() const override
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
const unsigned int dofs_per_face
void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false, const bool isotropic_prolongation_only=false)
static ::ExceptionBase & ExcNotImplemented()
void initialize_restriction()
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
FullMatrix< double > inverse_node_matrix
virtual std::unique_ptr< FiniteElement< dim, dim > > clone() const override
void fill(const FullMatrix< number2 > &src, const size_type dst_offset_i=0, const size_type dst_offset_j=0, const size_type src_offset_i=0, const size_type src_offset_j=0)
void mTmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
double weight(const unsigned int i) const
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override