16 #include <deal.II/base/logstream.h> 17 #include <deal.II/base/utilities.h> 18 #include <deal.II/base/quadrature.h> 19 #include <deal.II/base/quadrature_lib.h> 20 #include <deal.II/base/qprojector.h> 21 #include <deal.II/grid/tria.h> 22 #include <deal.II/grid/tria_iterator.h> 23 #include <deal.II/dofs/dof_accessor.h> 24 #include <deal.II/fe/mapping.h> 25 #include <deal.II/fe/fe_nedelec.h> 26 #include <deal.II/fe/fe_nothing.h> 27 #include <deal.II/fe/fe_values.h> 28 #include <deal.II/fe/fe_tools.h> 29 #include <deal.II/lac/full_matrix.h> 30 #include <deal.II/lac/vector.h> 34 #include <deal.II/base/std_cxx14/memory.h> 41 DEAL_II_NAMESPACE_OPEN
52 get_embedding_computation_tolerance(
const unsigned int p)
59 return 1.e-15*std::exp(std::pow(p,1.075));
76 std::vector<bool> (dim, true)))
104 deallog <<
"Face Embedding" << std::endl;
108 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face; ++i)
111 FETools::compute_face_embedding_matrices<dim,double>
112 (*
this, face_embeddings, 0, 0,
113 internal::FE_Nedelec::get_embedding_computation_tolerance(order));
128 for (
unsigned int i = 0; i < GeometryInfo<2>::max_children_per_face;
133 = face_embeddings[i] (j, k);
143 unsigned int target_row = 0;
145 for (
unsigned int i = 0; i < 2; ++i)
146 for (
unsigned int j = this->
degree; j < 2 * this->
degree;
150 = face_embeddings[2 * i] (j, k);
152 for (
unsigned int i = 0; i < 2; ++i)
153 for (
unsigned int j = 3 * this->degree;
154 j < GeometryInfo<3>::lines_per_face * this->
degree;
158 = face_embeddings[i] (j, k);
160 for (
unsigned int i = 0; i < 2; ++i)
161 for (
unsigned int j = 0; j < 2; ++j)
162 for (
unsigned int k = i * this->degree;
163 k < (i + 1) * this->degree; ++k, ++target_row)
166 = face_embeddings[i + 2 * j] (k, l);
168 for (
unsigned int i = 0; i < 2; ++i)
169 for (
unsigned int j = 0; j < 2; ++j)
170 for (
unsigned int k = (i + 2) * this->
degree;
171 k < (i + 3) * this->degree; ++k, ++target_row)
174 = face_embeddings[2 * i + j] (k, l);
176 for (
unsigned int i = 0; i < GeometryInfo<3>::max_children_per_face;
183 = face_embeddings[i] (j, k);
207 std::ostringstream namebuf;
208 namebuf <<
"FE_Nedelec<" << dim <<
">(" << this->degree-1 <<
")";
210 return namebuf.str();
215 std::unique_ptr<FiniteElement<dim,dim> >
218 return std_cxx14::make_unique<FE_Nedelec<dim> >(*this);
249 const std::vector<Polynomials::Polynomial<double> > &lobatto_polynomials
251 std::vector<Polynomials::Polynomial<double> >
252 lobatto_polynomials_grad (order + 1);
254 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size (); ++i)
255 lobatto_polynomials_grad[i] = lobatto_polynomials[i + 1].derivative ();
259 const QGauss<dim - 1> reference_edge_quadrature (order + 1);
260 const unsigned int n_edge_points = reference_edge_quadrature.size ();
261 const unsigned int n_boundary_points
266 this->generalized_face_support_points.resize (n_edge_points);
269 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
270 this->generalized_face_support_points[q_point]
271 = reference_edge_quadrature.point (q_point);
279 const unsigned int &n_interior_points = quadrature.size ();
281 this->generalized_support_points.resize
282 (n_boundary_points + n_interior_points);
283 boundary_weights.reinit (n_edge_points, order);
285 for (
unsigned int q_point = 0; q_point < n_edge_points;
288 for (
unsigned int line = 0;
289 line < GeometryInfo<dim>::lines_per_cell; ++line)
290 this->generalized_support_points[line * n_edge_points
292 = edge_quadrature.
point 294 (line,
true,
false,
false, n_edge_points) + q_point);
296 for (
unsigned int i = 0; i < order; ++i)
297 boundary_weights (q_point, i)
298 = reference_edge_quadrature.weight (q_point)
299 * lobatto_polynomials_grad[i + 1].value
300 (this->generalized_face_support_points[q_point] (0));
303 for (
unsigned int q_point = 0; q_point < n_interior_points;
305 this->generalized_support_points[q_point + n_boundary_points]
306 = quadrature.point (q_point);
313 this->generalized_support_points.resize (n_boundary_points);
315 for (
unsigned int line = 0;
316 line < GeometryInfo<dim>::lines_per_cell; ++line)
317 for (
unsigned int q_point = 0; q_point < n_edge_points;
319 this->generalized_support_points[line * n_edge_points
321 = edge_quadrature.
point 323 (line,
true,
false,
false, n_edge_points) + q_point);
336 const std::vector<Polynomials::Polynomial<double> > &lobatto_polynomials
338 std::vector<Polynomials::Polynomial<double> >
339 lobatto_polynomials_grad (order + 1);
341 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size (); ++i)
342 lobatto_polynomials_grad[i] = lobatto_polynomials[i + 1].derivative ();
346 const QGauss<1> reference_edge_quadrature (order + 1);
347 const unsigned int &n_edge_points = reference_edge_quadrature.size ();
350 (reference_edge_quadrature);
357 const QGauss<dim - 1> reference_face_quadrature (order + 1);
358 const unsigned int &n_face_points
359 = reference_face_quadrature.size ();
360 const unsigned int n_boundary_points
364 const unsigned int &n_interior_points = quadrature.size ();
366 boundary_weights.reinit (n_edge_points + n_face_points,
367 2 * (order + 1) * order);
368 this->generalized_face_support_points.resize
369 (4 * n_edge_points + n_face_points);
370 this->generalized_support_points.resize
371 (n_boundary_points + n_interior_points);
374 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
376 for (
unsigned int line = 0;
378 this->generalized_face_support_points[line * n_edge_points
380 = edge_quadrature.point
382 (line,
true,
false,
false, n_edge_points) + q_point);
384 for (
unsigned int i = 0; i < 2; ++i)
385 for (
unsigned int j = 0; j < 2; ++j)
387 this->generalized_support_points
388 [q_point + (i + 4 * j) * n_edge_points]
390 (i, reference_edge_quadrature.point (q_point) (0),
392 this->generalized_support_points
393 [q_point + (i + 4 * j + 2) * n_edge_points]
395 (reference_edge_quadrature.point (q_point) (0),
397 this->generalized_support_points
398 [q_point + (i + 2 * (j + 4)) * n_edge_points]
401 reference_edge_quadrature.point (q_point) (0));
404 for (
unsigned int i = 0; i < order; ++i)
405 boundary_weights (q_point, i)
406 = reference_edge_quadrature.weight (q_point)
407 * lobatto_polynomials_grad[i + 1].value
408 (this->generalized_face_support_points[q_point] (1));
412 for (
unsigned int q_point = 0; q_point < n_face_points;
415 this->generalized_face_support_points[q_point
417 = reference_face_quadrature.point (q_point);
419 for (
unsigned int i = 0; i <= order; ++i)
420 for (
unsigned int j = 0; j < order; ++j)
422 boundary_weights (q_point + n_edge_points,
424 = reference_face_quadrature.weight (q_point)
425 * lobatto_polynomials_grad[i].value
426 (this->generalized_face_support_points
427 [q_point + 4 * n_edge_points] (0))
428 * lobatto_polynomials[j + 2].value
429 (this->generalized_face_support_points
430 [q_point + 4 * n_edge_points] (1));
431 boundary_weights (q_point + n_edge_points,
432 2 * (i * order + j) + 1)
433 = reference_face_quadrature.weight (q_point)
434 * lobatto_polynomials_grad[i].value
435 (this->generalized_face_support_points
436 [q_point + 4 * n_edge_points] (1))
437 * lobatto_polynomials[j + 2].value
438 (this->generalized_face_support_points
439 [q_point + 4 * n_edge_points] (0));
445 (reference_face_quadrature);
447 for (
unsigned int face = 0;
448 face < GeometryInfo<dim>::faces_per_cell; ++face)
449 for (
unsigned int q_point = 0; q_point < n_face_points;
452 this->generalized_support_points
453 [face * n_face_points + q_point
455 = face_quadrature.
point 457 (face,
true,
false,
false, n_face_points) + q_point);
461 for (
unsigned int q_point = 0; q_point < n_interior_points;
463 this->generalized_support_points[q_point + n_boundary_points]
464 = quadrature.point (q_point);
469 this->generalized_face_support_points.resize (4 * n_edge_points);
470 this->generalized_support_points.resize
473 for (
unsigned int q_point = 0; q_point < n_edge_points;
476 for (
unsigned int line = 0;
478 this->generalized_face_support_points[line * n_edge_points
480 = edge_quadrature.point
482 (line,
true,
false,
false, n_edge_points) + q_point);
484 for (
unsigned int i = 0; i < 2; ++i)
485 for (
unsigned int j = 0; j < 2; ++j)
487 this->generalized_support_points
488 [q_point + (i + 4 * j) * n_edge_points]
490 (i, reference_edge_quadrature.point (q_point) (0),
492 this->generalized_support_points
493 [q_point + (i + 4 * j + 2) * n_edge_points]
495 (reference_edge_quadrature.point (q_point) (0),
497 this->generalized_support_points
498 [q_point + (i + 2 * (j + 4)) * n_edge_points]
501 reference_edge_quadrature.point (q_point) (0));
516 for (
unsigned int i = 0; i < GeometryInfo<1>::max_children_per_cell; ++i)
517 this->restriction[0][i].reinit(0, 0);
533 const QGauss<1> edge_quadrature (2 * this->degree);
534 const std::vector<Point<1> > &edge_quadrature_points
537 n_edge_quadrature_points = edge_quadrature.
size ();
549 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
550 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
553 const double weight = 2.0 * edge_quadrature.
weight (q_point);
555 if (edge_quadrature_points[q_point] (0) < 0.5)
558 2.0 * edge_quadrature_points[q_point] (0));
560 this->restriction[index][0] (0, dof) += weight
561 * this->shape_value_component
565 quadrature_point (0) = 1.0;
566 this->restriction[index][1] (this->degree, dof)
567 += weight * this->shape_value_component (dof,
570 quadrature_point (0) = quadrature_point (1);
571 quadrature_point (1) = 0.0;
572 this->restriction[index][0] (2 * this->degree, dof)
573 += weight * this->shape_value_component (dof,
576 quadrature_point (1) = 1.0;
577 this->restriction[index][2] (3 * this->degree, dof)
578 += weight * this->shape_value_component (dof,
586 2.0 * edge_quadrature_points[q_point] (0)
589 this->restriction[index][2] (0, dof) += weight
590 * this->shape_value_component
594 quadrature_point (0) = 1.0;
595 this->restriction[index][3] (this->degree, dof)
596 += weight * this->shape_value_component (dof,
599 quadrature_point (0) = quadrature_point (1);
600 quadrature_point (1) = 0.0;
601 this->restriction[index][1] (2 * this->degree, dof)
602 += weight * this->shape_value_component (dof,
605 quadrature_point (1) = 1.0;
606 this->restriction[index][3] (3 * this->degree, dof)
607 += weight * this->shape_value_component (dof,
617 if (this->degree > 1)
619 const unsigned int deg = this->degree-1;
620 const std::vector<Polynomials::Polynomial<double> > &
627 n_edge_quadrature_points);
629 for (
unsigned int q_point = 0;
630 q_point < n_edge_quadrature_points; ++q_point)
633 = std::sqrt (edge_quadrature.
weight (q_point));
635 for (
unsigned int i = 0; i < deg; ++i)
636 assembling_matrix (i, q_point) = weight
637 * legendre_polynomials[i + 1].value
638 (edge_quadrature_points[q_point] (0));
643 assembling_matrix.
mTmult (system_matrix, assembling_matrix);
644 system_matrix_inv.
invert (system_matrix);
651 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
652 for (
unsigned int i = 0; i < 2; ++i)
656 for (
unsigned int q_point = 0;
657 q_point < n_edge_quadrature_points; ++q_point)
660 = edge_quadrature.
weight (q_point);
662 edge_quadrature_points[q_point] (0));
664 (edge_quadrature_points[q_point] (0),
667 if (edge_quadrature_points[q_point] (0) < 0.5)
670 2.0 * edge_quadrature_points[q_point] (0));
673 * (2.0 * this->shape_value_component
674 (dof, quadrature_point_2, 1)
675 - this->restriction[index][i]
676 (i * this->degree, dof)
677 * this->shape_value_component
679 quadrature_point_0, 1));
680 tmp (1) = -1.0 * weight
681 * this->restriction[index][i + 2]
682 (i * this->degree, dof)
683 * this->shape_value_component
685 quadrature_point_0, 1);
687 =
Point<dim> (2.0 * edge_quadrature_points[q_point] (0),
690 * (2.0 * this->shape_value_component
691 (dof, quadrature_point_2, 0)
692 - this->restriction[index][2 * i]
693 ((i + 2) * this->degree, dof)
694 * this->shape_value_component
695 ((i + 2) * this->degree,
696 quadrature_point_1, 0));
697 tmp (3) = -1.0 * weight
698 * this->restriction[index][2 * i + 1]
699 ((i + 2) * this->degree, dof)
700 * this->shape_value_component
701 ((i + 2) * this->degree,
702 quadrature_point_1, 0);
707 tmp (0) = -1.0 * weight
708 * this->restriction[index][i]
709 (i * this->degree, dof)
710 * this->shape_value_component
712 quadrature_point_0, 1);
715 2.0 * edge_quadrature_points[q_point] (0)
719 * (2.0 * this->shape_value_component
720 (dof, quadrature_point_2, 1)
721 - this->restriction[index][i + 2]
722 (i * this->degree, dof)
723 * this->shape_value_component
725 quadrature_point_0, 1));
726 tmp (2) = -1.0 * weight
727 * this->restriction[index][2 * i]
728 ((i + 2) * this->degree, dof)
729 * this->shape_value_component
730 ((i + 2) * this->degree,
731 quadrature_point_1, 0);
733 =
Point<dim> (2.0 * edge_quadrature_points[q_point] (0)
736 * (2.0 * this->shape_value_component
737 (dof, quadrature_point_2, 0)
738 - this->restriction[index][2 * i + 1]
739 ((i + 2) * this->degree, dof)
740 * this->shape_value_component
741 ((i + 2) * this->degree,
742 quadrature_point_1, 0));
745 for (
unsigned int j = 0; j < this->degree-1; ++j)
748 = legendre_polynomials[j + 1].value
749 (edge_quadrature_points[q_point] (0));
751 for (
unsigned int k = 0; k < tmp.
size (); ++k)
752 system_rhs (j, k) += tmp (k) * L_j;
756 system_matrix_inv.
mmult (solution, system_rhs);
758 for (
unsigned int j = 0; j < this->degree-1; ++j)
759 for (
unsigned int k = 0; k < 2; ++k)
761 if (std::abs (solution (j, k)) > 1e-14)
762 this->restriction[index][i + 2 * k]
763 (i * this->degree + j + 1, dof)
766 if (std::abs (solution (j, k + 2)) > 1e-14)
767 this->restriction[index][2 * i + k]
768 ((i + 2) * this->degree + j + 1, dof)
769 = solution (j, k + 2);
774 const std::vector<Point<dim> > &
776 const std::vector<Polynomials::Polynomial<double> > &
780 const unsigned int n_boundary_dofs
782 const unsigned int &n_quadrature_points = quadrature.
size ();
786 n_quadrature_points);
788 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
792 = std::sqrt (quadrature.
weight (q_point));
794 for (
unsigned int i = 0; i < this->degree; ++i)
796 const double L_i = weight
797 * legendre_polynomials[i].value
798 (quadrature_points[q_point] (0));
800 for (
unsigned int j = 0; j < this->degree-1; ++j)
801 assembling_matrix (i * (this->degree-1) + j, q_point)
802 = L_i * lobatto_polynomials[j + 2].value
803 (quadrature_points[q_point] (1));
808 assembling_matrix.
m ());
810 assembling_matrix.
mTmult (system_matrix, assembling_matrix);
811 system_matrix_inv.
reinit (system_matrix.m (), system_matrix.m ());
812 system_matrix_inv.
invert (system_matrix);
815 solution.
reinit (system_matrix_inv.
m (), 8);
816 system_rhs.
reinit (system_matrix_inv.
m (), 8);
819 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
823 for (
unsigned int q_point = 0;
824 q_point < n_quadrature_points; ++q_point)
828 if (quadrature_points[q_point] (0) < 0.5)
830 if (quadrature_points[q_point] (1) < 0.5)
833 (2.0 * quadrature_points[q_point] (0),
834 2.0 * quadrature_points[q_point] (1));
836 tmp (0) += 2.0 * this->shape_value_component
837 (dof, quadrature_point, 0);
838 tmp (1) += 2.0 * this->shape_value_component
839 (dof, quadrature_point, 1);
845 (2.0 * quadrature_points[q_point] (0),
846 2.0 * quadrature_points[q_point] (1)
849 tmp (4) += 2.0 * this->shape_value_component
850 (dof, quadrature_point, 0);
851 tmp (5) += 2.0 * this->shape_value_component
852 (dof, quadrature_point, 1);
856 else if (quadrature_points[q_point] (1) < 0.5)
859 (2.0 * quadrature_points[q_point] (0)
861 2.0 * quadrature_points[q_point] (1));
863 tmp (2) += 2.0 * this->shape_value_component
864 (dof, quadrature_point, 0);
865 tmp (3) += 2.0 * this->shape_value_component
866 (dof, quadrature_point, 1);
872 (2.0 * quadrature_points[q_point] (0)
874 2.0 * quadrature_points[q_point] (1)
877 tmp (6) += 2.0 * this->shape_value_component
878 (dof, quadrature_point, 0);
879 tmp (7) += 2.0 * this->shape_value_component
880 (dof, quadrature_point, 1);
883 for (
unsigned int i = 0; i < 2; ++i)
884 for (
unsigned int j = 0; j < this->degree; ++j)
886 tmp (2 * i) -= this->restriction[index][i]
887 (j + 2 * this->degree, dof)
888 * this->shape_value_component
889 (j + 2 * this->degree,
890 quadrature_points[q_point], 0);
891 tmp (2 * i + 1) -= this->restriction[index][i]
892 (i * this->degree + j, dof)
893 * this->shape_value_component
894 (i * this->degree + j,
895 quadrature_points[q_point], 1);
896 tmp (2 * (i + 2)) -= this->restriction[index][i + 2]
897 (j + 3 * this->degree, dof)
898 * this->shape_value_component
899 (j + 3 * this->degree,
900 quadrature_points[q_point],
902 tmp (2 * i + 5) -= this->restriction[index][i + 2]
903 (i * this->degree + j, dof)
904 * this->shape_value_component
905 (i * this->degree + j,
906 quadrature_points[q_point], 1);
909 tmp *= quadrature.
weight (q_point);
911 for (
unsigned int i = 0; i < this->degree; ++i)
914 = legendre_polynomials[i].value
915 (quadrature_points[q_point] (0));
917 = legendre_polynomials[i].value
918 (quadrature_points[q_point] (1));
920 for (
unsigned int j = 0; j < this->degree-1; ++j)
923 = L_i_0 * lobatto_polynomials[j + 2].value
924 (quadrature_points[q_point] (1));
926 = L_i_1 * lobatto_polynomials[j + 2].value
927 (quadrature_points[q_point] (0));
929 for (
unsigned int k = 0; k < 4; ++k)
931 system_rhs (i * (this->degree-1) + j, 2 * k)
932 += tmp (2 * k) * l_j_0;
933 system_rhs (i * (this->degree-1) + j, 2 * k + 1)
934 += tmp (2 * k + 1) * l_j_1;
940 system_matrix_inv.
mmult (solution, system_rhs);
942 for (
unsigned int i = 0; i < this->degree; ++i)
943 for (
unsigned int j = 0; j < this->degree-1; ++j)
944 for (
unsigned int k = 0; k < 4; ++k)
946 if (std::abs (solution (i * (this->degree-1) + j, 2 * k))
948 this->restriction[index][k]
949 (i * (this->degree-1) + j + n_boundary_dofs, dof)
950 = solution (i * (this->degree-1) + j, 2 * k);
952 if (std::abs (solution (i * (this->degree-1) + j, 2 * k + 1))
954 this->restriction[index][k]
955 (i + (this->degree-1 + j) * this->degree + n_boundary_dofs,
957 = solution (i * (this->degree-1) + j, 2 * k + 1);
971 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
972 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
975 const double weight = 2.0 * edge_quadrature.
weight (q_point);
977 if (edge_quadrature_points[q_point] (0) < 0.5)
978 for (
unsigned int i = 0; i < 2; ++i)
979 for (
unsigned int j = 0; j < 2; ++j)
982 2.0 * edge_quadrature_points[q_point] (0),
985 this->restriction[index][i + 4 * j]
986 ((i + 4 * j) * this->degree, dof)
987 += weight * this->shape_value_component (dof,
991 =
Point<dim> (2.0 * edge_quadrature_points[q_point] (0),
993 this->restriction[index][2 * (i + 2 * j)]
994 ((i + 4 * j + 2) * this->degree, dof)
995 += weight * this->shape_value_component (dof,
999 2.0 * edge_quadrature_points[q_point] (0));
1000 this->restriction[index][i + 2 * j]
1001 ((i + 2 * (j + 4)) * this->degree, dof)
1002 += weight * this->shape_value_component (dof,
1008 for (
unsigned int i = 0; i < 2; ++i)
1009 for (
unsigned int j = 0; j < 2; ++j)
1012 2.0 * edge_quadrature_points[q_point] (0)
1015 this->restriction[index][i + 4 * j + 2]
1016 ((i + 4 * j) * this->degree, dof)
1017 += weight * this->shape_value_component (dof,
1021 =
Point<dim> (2.0 * edge_quadrature_points[q_point] (0)
1023 this->restriction[index][2 * (i + 2 * j) + 1]
1024 ((i + 4 * j + 2) * this->degree, dof)
1025 += weight * this->shape_value_component (dof,
1029 2.0 * edge_quadrature_points[q_point] (0)
1031 this->restriction[index][i + 2 * (j + 2)]
1032 ((i + 2 * (j + 4)) * this->degree, dof)
1033 += weight * this->shape_value_component (dof,
1043 if (this->degree > 1)
1045 const unsigned int deg = this->degree-1;
1046 const std::vector<Polynomials::Polynomial<double> > &
1047 legendre_polynomials
1053 n_edge_quadrature_points);
1055 for (
unsigned int q_point = 0;
1056 q_point < n_edge_quadrature_points; ++q_point)
1058 const double weight = std::sqrt (edge_quadrature.
weight 1061 for (
unsigned int i = 0; i < deg; ++i)
1062 assembling_matrix (i, q_point) = weight
1063 * legendre_polynomials[i + 1].value
1064 (edge_quadrature_points[q_point] (0));
1069 assembling_matrix.
mTmult (system_matrix, assembling_matrix);
1070 system_matrix_inv.
invert (system_matrix);
1077 for (
unsigned int i = 0; i < 2; ++i)
1078 for (
unsigned int j = 0; j < 2; ++j)
1079 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
1083 for (
unsigned int q_point = 0;
1084 q_point < n_edge_quadrature_points; ++q_point)
1086 const double weight = edge_quadrature.
weight 1089 edge_quadrature_points[q_point] (0),
1093 (edge_quadrature_points[q_point] (0), i, j);
1095 edge_quadrature_points[q_point] (0));
1097 if (edge_quadrature_points[q_point] (0) < 0.5)
1100 2.0 * edge_quadrature_points[q_point] (0),
1104 * (2.0 * this->shape_value_component
1105 (dof, quadrature_point_3, 1)
1106 - this->restriction[index][i + 4 * j]
1107 ((i + 4 * j) * this->degree,
1109 * this->shape_value_component
1110 ((i + 4 * j) * this->degree,
1111 quadrature_point_0, 1));
1112 tmp (1) = -1.0 * weight
1113 * this->restriction[index][i + 4 * j + 2]
1114 ((i + 4 * j) * this->degree,
1116 * this->shape_value_component
1117 ((i + 4 * j) * this->degree,
1118 quadrature_point_0, 1);
1120 =
Point<dim> (2.0 * edge_quadrature_points[q_point] (0),
1123 * (2.0 * this->shape_value_component
1124 (dof, quadrature_point_3, 0)
1125 - this->restriction[index][2 * (i + 2 * j)]
1126 ((i + 4 * j + 2) * this->degree,
1128 * this->shape_value_component
1129 ((i + 4 * j + 2) * this->degree,
1130 quadrature_point_1, 0));
1131 tmp (3) = -1.0 * weight
1132 * this->restriction[index][2 * (i + 2 * j) + 1]
1133 ((i + 4 * j + 2) * this->degree,
1135 * this->shape_value_component
1136 ((i + 4 * j + 2) * this->degree,
1137 quadrature_point_1, 0);
1139 2.0 * edge_quadrature_points[q_point] (0));
1141 * (2.0 * this->shape_value_component
1142 (dof, quadrature_point_3, 2)
1143 - this->restriction[index][i + 2 * j]
1144 ((i + 2 * (j + 4)) * this->degree,
1146 * this->shape_value_component
1147 ((i + 2 * (j + 4)) * this->degree,
1148 quadrature_point_2, 2));
1149 tmp (5) = -1.0 * weight
1150 * this->restriction[index][i + 2 * (j + 2)]
1151 ((i + 2 * (j + 4)) * this->degree,
1153 * this->shape_value_component
1154 ((i + 2 * (j + 4)) * this->degree,
1155 quadrature_point_2, 2);
1160 tmp (0) = -1.0 * weight
1161 * this->restriction[index][i + 4 * j]
1162 ((i + 4 * j) * this->degree,
1164 * this->shape_value_component
1165 ((i + 4 * j) * this->degree,
1166 quadrature_point_0, 1);
1169 2.0 * edge_quadrature_points[q_point] (0)
1173 * (2.0 * this->shape_value_component
1174 (dof, quadrature_point_3, 1)
1175 - this->restriction[index][i + 4 * j + 2]
1176 ((i + 4 * j) * this->degree,
1178 * this->shape_value_component
1179 ((i + 4 * j) * this->degree,
1180 quadrature_point_0, 1));
1181 tmp (2) = -1.0 * weight
1182 * this->restriction[index][2 * (i + 2 * j)]
1183 ((i + 4 * j + 2) * this->degree,
1185 * this->shape_value_component
1186 ((i + 4 * j + 2) * this->degree,
1187 quadrature_point_1, 0);
1189 =
Point<dim> (2.0 * edge_quadrature_points[q_point] (0)
1192 * (2.0 * this->shape_value_component
1193 (dof, quadrature_point_3, 0)
1194 - this->restriction[index][2 * (i + 2 * j) + 1]
1195 ((i + 4 * j + 2) * this->degree,
1197 * this->shape_value_component
1198 ((i + 4 * j + 2) * this->degree,
1199 quadrature_point_1, 0));
1200 tmp (4) = -1.0 * weight
1201 * this->restriction[index][i + 2 * j]
1202 ((i + 2 * (j + 4)) * this->degree,
1204 * this->shape_value_component
1205 ((i + 2 * (j + 4)) * this->degree,
1206 quadrature_point_2, 2);
1208 2.0 * edge_quadrature_points[q_point] (0)
1211 * (2.0 * this->shape_value_component
1212 (dof, quadrature_point_3, 2)
1213 - this->restriction[index][i + 2 * (j + 2)]
1214 ((i + 2 * (j + 4)) * this->degree,
1216 * this->shape_value_component
1217 ((i + 2 * (j + 4)) * this->degree,
1218 quadrature_point_2, 2));
1221 for (
unsigned int k = 0; k < deg; ++k)
1224 = legendre_polynomials[k + 1].value
1225 (edge_quadrature_points[q_point] (0));
1227 for (
unsigned int l = 0; l < tmp.
size (); ++l)
1228 system_rhs (k, l) += tmp (l) * L_k;
1232 system_matrix_inv.
mmult (solution, system_rhs);
1234 for (
unsigned int k = 0; k < 2; ++k)
1235 for (
unsigned int l = 0; l < deg; ++l)
1237 if (std::abs (solution (l, k)) > 1e-14)
1238 this->restriction[index][i + 2 * (2 * j + k)]
1239 ((i + 4 * j) * this->degree + l + 1, dof)
1242 if (std::abs (solution (l, k + 2)) > 1e-14)
1243 this->restriction[index][2 * (i + 2 * j) + k]
1244 ((i + 4 * j + 2) * this->degree + l + 1, dof)
1245 = solution (l, k + 2);
1247 if (std::abs (solution (l, k + 4)) > 1e-14)
1248 this->restriction[index][i + 2 * (j + 2 * k)]
1249 ((i + 2 * (j + 4)) * this->degree + l + 1,
1251 = solution (l, k + 4);
1255 const QGauss<2> face_quadrature (2 * this->degree);
1256 const std::vector<Point<2> > &face_quadrature_points
1258 const std::vector<Polynomials::Polynomial<double> > &
1262 const unsigned int n_edge_dofs
1264 const unsigned int &n_face_quadrature_points
1265 = face_quadrature.
size ();
1269 (deg * this->degree,
1270 n_face_quadrature_points);
1272 for (
unsigned int q_point = 0;
1273 q_point < n_face_quadrature_points; ++q_point)
1276 = std::sqrt (face_quadrature.
weight (q_point));
1278 for (
unsigned int i = 0; i <= deg; ++i)
1280 const double L_i = weight
1281 * 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,
1296 system_matrix_inv.
reinit (system_matrix.m (),
1297 system_matrix.m ());
1298 system_matrix_inv.
invert (system_matrix);
1301 solution.
reinit (system_matrix_inv.
m (), 24);
1302 system_rhs.
reinit (system_matrix_inv.
m (), 24);
1305 for (
unsigned int i = 0; i < 2; ++i)
1306 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
1310 for (
unsigned int q_point = 0;
1311 q_point < n_face_quadrature_points; ++q_point)
1315 if (face_quadrature_points[q_point] (0) < 0.5)
1317 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 =
Point<dim> (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 =
Point<dim> (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);
1348 2.0 * face_quadrature_points[q_point] (0),
1349 2.0 * face_quadrature_points[q_point] (1)
1352 tmp (2) += 2.0 * this->shape_value_component
1353 (dof, quadrature_point_0, 1);
1354 tmp (3) += 2.0 * this->shape_value_component
1355 (dof, quadrature_point_0, 2);
1357 =
Point<dim> (2.0 * face_quadrature_points[q_point] (0),
1359 2.0 * face_quadrature_points[q_point] (1)
1361 tmp (10) += 2.0 * this->shape_value_component
1362 (dof, quadrature_point_0, 2);
1363 tmp (11) += 2.0 * this->shape_value_component
1364 (dof, quadrature_point_0, 0);
1366 =
Point<dim> (2.0 * face_quadrature_points[q_point] (0),
1367 2.0 * face_quadrature_points[q_point] (1)
1369 tmp (18) += 2.0 * this->shape_value_component
1370 (dof, quadrature_point_0, 0);
1371 tmp (19) += 2.0 * this->shape_value_component
1372 (dof, quadrature_point_0, 1);
1376 else if (face_quadrature_points[q_point] (1) < 0.5)
1379 2.0 * face_quadrature_points[q_point] (0)
1381 2.0 * face_quadrature_points[q_point] (1));
1383 tmp (4) += 2.0 * this->shape_value_component
1384 (dof, quadrature_point_0, 1);
1385 tmp (5) += 2.0 * this->shape_value_component
1386 (dof, quadrature_point_0, 2);
1388 =
Point<dim> (2.0 * face_quadrature_points[q_point] (0)
1390 2.0 * face_quadrature_points[q_point] (1));
1391 tmp (12) += 2.0 * this->shape_value_component
1392 (dof, quadrature_point_0, 2);
1393 tmp (13) += 2.0 * this->shape_value_component
1394 (dof, quadrature_point_0, 0);
1396 =
Point<dim> (2.0 * face_quadrature_points[q_point] (0)
1398 2.0 * face_quadrature_points[q_point] (1),
1400 tmp (20) += 2.0 * this->shape_value_component
1401 (dof, quadrature_point_0, 0);
1402 tmp (21) += 2.0 * this->shape_value_component
1403 (dof, quadrature_point_0, 1);
1409 2.0 * face_quadrature_points[q_point] (0)
1411 2.0 * face_quadrature_points[q_point] (1)
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 =
Point<dim> (2.0 * face_quadrature_points[q_point] (0)
1421 2.0 * face_quadrature_points[q_point] (1)
1423 tmp (14) += 2.0 * this->shape_value_component
1424 (dof, quadrature_point_0, 2);
1425 tmp (15) += 2.0 * this->shape_value_component
1426 (dof, quadrature_point_0, 0);
1428 =
Point<dim> (2.0 * face_quadrature_points[q_point] (0)
1430 2.0 * face_quadrature_points[q_point] (1)
1432 tmp (22) += 2.0 * this->shape_value_component
1433 (dof, quadrature_point_0, 0);
1434 tmp (23) += 2.0 * this->shape_value_component
1435 (dof, quadrature_point_0, 1);
1439 face_quadrature_points[q_point] (0),
1440 face_quadrature_points[q_point] (1));
1442 (face_quadrature_points[q_point] (0),
1444 face_quadrature_points[q_point] (1));
1446 (face_quadrature_points[q_point] (0),
1447 face_quadrature_points[q_point] (1),
1450 for (
unsigned int j = 0; j < 2; ++j)
1451 for (
unsigned int k = 0; k < 2; ++k)
1452 for (
unsigned int l = 0; l <= deg; ++l)
1454 tmp (2 * (j + 2 * k))
1455 -= this->restriction[index][i + 2 * (2 * j + k)]
1456 ((i + 4 * j) * this->degree + l, dof)
1457 * this->shape_value_component
1458 ((i + 4 * j) * this->degree + l,
1459 quadrature_point_0, 1);
1460 tmp (2 * (j + 2 * k) + 1)
1461 -= this->restriction[index][i + 2 * (2 * j + k)]
1462 ((i + 2 * (k + 4)) * this->degree + l,
1464 * this->shape_value_component
1465 ((i + 2 * (k + 4)) * this->degree + l,
1466 quadrature_point_0, 2);
1467 tmp (2 * (j + 2 * (k + 2)))
1468 -= this->restriction[index][2 * (i + 2 * j) + k]
1469 ((2 * (i + 4) + k) * this->degree + l,
1471 * this->shape_value_component
1472 ((2 * (i + 4) + k) * this->degree + l,
1473 quadrature_point_1, 2);
1474 tmp (2 * (j + 2 * k) + 9)
1475 -= this->restriction[index][2 * (i + 2 * j) + k]
1476 ((i + 4 * j + 2) * this->degree + l,
1478 * this->shape_value_component
1479 ((i + 4 * j + 2) * this->degree + l,
1480 quadrature_point_1, 0);
1481 tmp (2 * (j + 2 * (k + 4)))
1482 -= this->restriction[index][2 * (2 * i + j) + k]
1483 ((4 * i + j + 2) * this->degree + l,
1485 * this->shape_value_component
1486 ((4 * i + j + 2) * this->degree + l,
1487 quadrature_point_2, 0);
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,
1493 quadrature_point_2, 1);
1496 tmp *= face_quadrature.
weight (q_point);
1498 for (
unsigned int j = 0; j <= deg; ++j)
1501 = legendre_polynomials[j].value
1502 (face_quadrature_points[q_point] (0));
1504 = legendre_polynomials[j].value
1505 (face_quadrature_points[q_point] (1));
1507 for (
unsigned int k = 0; k < deg; ++k)
1510 = L_j_0 * lobatto_polynomials[k + 2].value
1511 (face_quadrature_points[q_point] (1));
1513 = L_j_1 * lobatto_polynomials[k + 2].value
1514 (face_quadrature_points[q_point] (0));
1516 for (
unsigned int l = 0; l < 4; ++l)
1518 system_rhs (j * deg + k, 2 * l)
1519 += tmp (2 * l) * l_k_0;
1520 system_rhs (j * deg + k, 2 * l + 1)
1521 += tmp (2 * l + 1) * l_k_1;
1522 system_rhs (j * deg + k, 2 * (l + 4))
1523 += tmp (2 * (l + 4)) * l_k_1;
1524 system_rhs (j * deg + k, 2 * l + 9)
1525 += tmp (2 * l + 9) * l_k_0;
1526 system_rhs (j * deg + k, 2 * (l + 8))
1527 += tmp (2 * (l + 8)) * l_k_0;
1528 system_rhs (j * deg + k, 2 * l + 17)
1529 += tmp (2 * l + 17) * l_k_1;
1535 system_matrix_inv.
mmult (solution, system_rhs);
1537 for (
unsigned int j = 0; j < 2; ++j)
1538 for (
unsigned int k = 0; k < 2; ++k)
1539 for (
unsigned int l = 0; l <= deg; ++l)
1540 for (
unsigned int m = 0; m < deg; ++m)
1542 if (std::abs (solution (l * deg + m,
1545 this->restriction[index][i + 2 * (2 * j + k)]
1546 ((2 * i * this->degree + l) * deg + m
1548 dof) = solution (l * deg + m,
1551 if (std::abs (solution (l * deg + m,
1552 2 * (j + 2 * k) + 1))
1554 this->restriction[index][i + 2 * (2 * j + k)]
1555 (((2 * i + 1) * deg + m) * this->degree + l
1557 = solution (l * deg + m,
1558 2 * (j + 2 * k) + 1);
1560 if (std::abs (solution (l * deg + m,
1561 2 * (j + 2 * (k + 2))))
1563 this->restriction[index][2 * (i + 2 * j) + k]
1564 ((2 * (i + 2) * this->degree + l) * deg + m
1566 dof) = solution (l * deg + m,
1567 2 * (j + 2 * (k + 2)));
1569 if (std::abs (solution (l * deg + m,
1570 2 * (j + 2 * k) + 9))
1572 this->restriction[index][2 * (i + 2 * j) + k]
1573 (((2 * i + 5) * deg + m) * this->degree + l
1575 = solution (l * deg + m,
1576 2 * (j + 2 * k) + 9);
1578 if (std::abs (solution (l * deg + m,
1579 2 * (j + 2 * (k + 4))))
1581 this->restriction[index][2 * (2 * i + j) + k]
1582 ((2 * (i + 4) * this->degree + l) * deg + m
1584 dof) = solution (l * deg + m,
1585 2 * (j + 2 * (k + 4)));
1587 if (std::abs (solution (l * deg + m,
1588 2 * (j + 2 * k) + 17))
1590 this->restriction[index][2 * (2 * i + j) + k]
1591 (((2 * i + 9) * deg + m) * this->degree + l
1593 = solution (l * deg + m,
1594 2 * (j + 2 * k) + 17);
1599 const std::vector<Point<dim> > &
1600 quadrature_points = quadrature.
get_points ();
1601 const unsigned int n_boundary_dofs
1604 const unsigned int &n_quadrature_points = quadrature.
size ();
1608 assembling_matrix (deg * deg * this->degree,
1609 n_quadrature_points);
1611 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
1614 const double weight = std::sqrt (quadrature.
weight 1617 for (
unsigned int i = 0; i <= deg; ++i)
1619 const double L_i = weight
1620 * legendre_polynomials[i].value
1621 (quadrature_points[q_point] (0));
1623 for (
unsigned int j = 0; j < deg; ++j)
1626 = L_i * lobatto_polynomials[j + 2].value
1627 (quadrature_points[q_point] (1));
1629 for (
unsigned int k = 0; k < deg; ++k)
1630 assembling_matrix ((i * deg + j) * deg + k,
1632 = l_j * lobatto_polynomials[k + 2].value
1633 (quadrature_points[q_point] (2));
1639 assembling_matrix.
m ());
1641 assembling_matrix.
mTmult (system_matrix, assembling_matrix);
1642 system_matrix_inv.
reinit (system_matrix.m (),
1643 system_matrix.m ());
1644 system_matrix_inv.
invert (system_matrix);
1647 solution.
reinit (system_matrix_inv.
m (), 24);
1648 system_rhs.
reinit (system_matrix_inv.
m (), 24);
1651 for (
unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
1655 for (
unsigned int q_point = 0;
1656 q_point < n_quadrature_points; ++q_point)
1660 if (quadrature_points[q_point] (0) < 0.5)
1662 if (quadrature_points[q_point] (1) < 0.5)
1664 if (quadrature_points[q_point] (2) < 0.5)
1667 (2.0 * quadrature_points[q_point] (0),
1668 2.0 * quadrature_points[q_point] (1),
1669 2.0 * quadrature_points[q_point] (2));
1671 tmp (0) += 2.0 * this->shape_value_component
1672 (dof, quadrature_point, 0);
1673 tmp (1) += 2.0 * this->shape_value_component
1674 (dof, quadrature_point, 1);
1675 tmp (2) += 2.0 * this->shape_value_component
1676 (dof, quadrature_point, 2);
1682 (2.0 * quadrature_points[q_point] (0),
1683 2.0 * quadrature_points[q_point] (1),
1684 2.0 * quadrature_points[q_point] (2)
1687 tmp (3) += 2.0 * this->shape_value_component
1688 (dof, quadrature_point, 0);
1689 tmp (4) += 2.0 * this->shape_value_component
1690 (dof, quadrature_point, 1);
1691 tmp (5) += 2.0 * this->shape_value_component
1692 (dof, quadrature_point, 2);
1696 else if (quadrature_points[q_point] (2) < 0.5)
1699 (2.0 * quadrature_points[q_point] (0),
1700 2.0 * quadrature_points[q_point] (1)
1702 2.0 * quadrature_points[q_point] (2));
1704 tmp (6) += 2.0 * this->shape_value_component
1705 (dof, quadrature_point, 0);
1706 tmp (7) += 2.0 * this->shape_value_component
1707 (dof, quadrature_point, 1);
1708 tmp (8) += 2.0 * this->shape_value_component
1709 (dof, quadrature_point, 2);
1715 (2.0 * quadrature_points[q_point] (0),
1716 2.0 * quadrature_points[q_point] (1)
1718 2.0 * quadrature_points[q_point] (2)
1721 tmp (9) += 2.0 * this->shape_value_component
1722 (dof, quadrature_point, 0);
1723 tmp (10) += 2.0 * this->shape_value_component
1724 (dof, quadrature_point, 1);
1725 tmp (11) += 2.0 * this->shape_value_component
1726 (dof, quadrature_point, 2);
1730 else if (quadrature_points[q_point] (1) < 0.5)
1732 if (quadrature_points[q_point] (2) < 0.5)
1735 (2.0 * quadrature_points[q_point] (0)
1737 2.0 * quadrature_points[q_point] (1),
1738 2.0 * quadrature_points[q_point] (2));
1740 tmp (12) += 2.0 * this->shape_value_component
1741 (dof, quadrature_point, 0);
1742 tmp (13) += 2.0 * this->shape_value_component
1743 (dof, quadrature_point, 1);
1744 tmp (14) += 2.0 * this->shape_value_component
1745 (dof, quadrature_point, 2);
1751 (2.0 * quadrature_points[q_point] (0)
1753 2.0 * quadrature_points[q_point] (1),
1754 2.0 * quadrature_points[q_point] (2)
1757 tmp (15) += 2.0 * this->shape_value_component
1758 (dof, quadrature_point, 0);
1759 tmp (16) += 2.0 * this->shape_value_component
1760 (dof, quadrature_point, 1);
1761 tmp (17) += 2.0 * this->shape_value_component
1762 (dof, quadrature_point, 2);
1766 else if (quadrature_points[q_point] (2) < 0.5)
1769 (2.0 * quadrature_points[q_point] (0)
1771 2.0 * quadrature_points[q_point] (1)
1773 2.0 * quadrature_points[q_point] (2));
1775 tmp (18) += 2.0 * this->shape_value_component
1776 (dof, quadrature_point, 0);
1777 tmp (19) += 2.0 * this->shape_value_component
1778 (dof, quadrature_point, 1);
1779 tmp (20) += 2.0 * this->shape_value_component
1780 (dof, quadrature_point, 2);
1786 (2.0 * quadrature_points[q_point] (0)
1788 2.0 * quadrature_points[q_point] (1)
1790 2.0 * quadrature_points[q_point] (2)
1793 tmp (21) += 2.0 * this->shape_value_component
1794 (dof, quadrature_point, 0);
1795 tmp (22) += 2.0 * this->shape_value_component
1796 (dof, quadrature_point, 1);
1797 tmp (23) += 2.0 * this->shape_value_component
1798 (dof, quadrature_point, 2);
1801 for (
unsigned int i = 0; i < 2; ++i)
1802 for (
unsigned int j = 0; j < 2; ++j)
1803 for (
unsigned int k = 0; k < 2; ++k)
1804 for (
unsigned int l = 0; l <= deg; ++l)
1806 tmp (3 * (i + 2 * (j + 2 * k)))
1807 -= this->restriction[index][2 * (2 * i + j) + k]
1808 ((4 * i + j + 2) * this->degree + l, dof)
1809 * this->shape_value_component
1810 ((4 * i + j + 2) * this->degree + l,
1811 quadrature_points[q_point], 0);
1812 tmp (3 * (i + 2 * (j + 2 * k)) + 1)
1813 -= this->restriction[index][2 * (2 * i + j) + k]
1814 ((4 * i + k) * this->degree + l, dof)
1815 * this->shape_value_component
1816 ((4 * i + k) * this->degree + l,
1817 quadrature_points[q_point], 1);
1818 tmp (3 * (i + 2 * (j + 2 * k)) + 2)
1819 -= this->restriction[index][2 * (2 * i + j) + k]
1820 ((2 * (j + 4) + k) * this->degree + l,
1822 * this->shape_value_component
1823 ((2 * (j + 4) + k) * this->degree + l,
1824 quadrature_points[q_point], 2);
1826 for (
unsigned int m = 0; m < deg; ++m)
1828 tmp (3 * (i + 2 * (j + 2 * k)))
1829 -= this->restriction[index][2 * (2 * i + j) + k]
1830 (((2 * j + 5) * deg + m)
1831 * this->degree + l + n_edge_dofs,
1833 * this->shape_value_component
1834 (((2 * j + 5) * deg + m)
1835 * this->degree + l + n_edge_dofs,
1836 quadrature_points[q_point], 0);
1837 tmp (3 * (i + 2 * (j + 2 * k)))
1838 -= this->restriction[index][2 * (2 * i + j) + k]
1839 ((2 * (i + 4) * this->degree + l)
1840 * deg + m + n_edge_dofs, dof)
1841 * this->shape_value_component
1842 ((2 * (i + 4) * this->degree + l)
1843 * deg + m + n_edge_dofs,
1844 quadrature_points[q_point], 0);
1845 tmp (3 * (i + 2 * (j + 2 * k)) + 1)
1846 -= this->restriction[index][2 * (2 * i + j) + k]
1847 ((2 * k * this->degree + l) * deg + m
1850 * this->shape_value_component
1851 ((2 * k * this->degree + l) * deg + m
1853 quadrature_points[q_point], 1);
1854 tmp (3 * (i + 2 * (j + 2 * k)) + 1)
1855 -= this->restriction[index][2 * (2 * i + j) + k]
1856 (((2 * i + 9) * deg + m)
1857 * this->degree + l + n_edge_dofs,
1859 * this->shape_value_component
1860 (((2 * i + 9) * deg + m)
1861 * this->degree + l + n_edge_dofs,
1862 quadrature_points[q_point], 1);
1863 tmp (3 * (i + 2 * (j + 2 * k)) + 2)
1864 -= this->restriction[index][2 * (2 * i + j) + k]
1865 (((2 * k + 1) * deg + m)
1866 * this->degree + l + n_edge_dofs,
1868 * this->shape_value_component
1869 (((2 * k + 1) * deg + m)
1870 * this->degree + l + n_edge_dofs,
1871 quadrature_points[q_point], 2);
1872 tmp (3 * (i + 2 * (j + 2 * k)) + 2)
1873 -= this->restriction[index][2 * (2 * i + j) + k]
1874 ((2 * (j + 2) * this->degree + l)
1875 * deg + m + n_edge_dofs, dof)
1876 * this->shape_value_component
1877 ((2 * (j + 2) * this->degree + l)
1878 * deg + m + n_edge_dofs,
1879 quadrature_points[q_point], 2);
1883 tmp *= quadrature.
weight (q_point);
1885 for (
unsigned int i = 0; i <= deg; ++i)
1888 = legendre_polynomials[i].value
1889 (quadrature_points[q_point] (0));
1891 = legendre_polynomials[i].value
1892 (quadrature_points[q_point] (1));
1894 = legendre_polynomials[i].value
1895 (quadrature_points[q_point] (2));
1897 for (
unsigned int j = 0; j < deg; ++j)
1900 = L_i_0 * lobatto_polynomials[j + 2].value
1901 (quadrature_points[q_point] (1));
1903 = L_i_1 * lobatto_polynomials[j + 2].value
1904 (quadrature_points[q_point] (0));
1906 = L_i_2 * lobatto_polynomials[j + 2].value
1907 (quadrature_points[q_point] (0));
1909 for (
unsigned int k = 0; k < deg; ++k)
1912 = l_j_0 * lobatto_polynomials[k + 2].value
1913 (quadrature_points[q_point] (2));
1915 = l_j_1 * lobatto_polynomials[k + 2].value
1916 (quadrature_points[q_point] (2));
1918 = l_j_2 * lobatto_polynomials[k + 2].value
1919 (quadrature_points[q_point] (1));
1921 for (
unsigned int l = 0; l < 8; ++l)
1923 system_rhs ((i * deg + j) * deg + k,
1925 += tmp (3 * l) * l_k_0;
1926 system_rhs ((i * deg + j) * deg + k,
1928 += tmp (3 * l + 1) * l_k_1;
1929 system_rhs ((i * deg + j) * deg + k,
1931 += tmp (3 * l + 2) * l_k_2;
1938 system_matrix_inv.
mmult (solution, system_rhs);
1940 for (
unsigned int i = 0; i < 2; ++i)
1941 for (
unsigned int j = 0; j < 2; ++j)
1942 for (
unsigned int k = 0; k < 2; ++k)
1943 for (
unsigned int l = 0; l <= deg; ++l)
1944 for (
unsigned int m = 0; m < deg; ++m)
1945 for (
unsigned int n = 0; n < deg; ++n)
1947 if (std::abs (solution
1948 ((l * deg + m) * deg + n,
1949 3 * (i + 2 * (j + 2 * k))))
1951 this->restriction[index][2 * (2 * i + j) + k]
1952 ((l * deg + m) * deg + n + n_boundary_dofs,
1953 dof) = solution ((l * deg + m) * deg + n,
1954 3 * (i + 2 * (j + 2 * k)));
1956 if (std::abs (solution
1957 ((l * deg + m) * deg + n,
1958 3 * (i + 2 * (j + 2 * k)) + 1))
1960 this->restriction[index][2 * (2 * i + j) + k]
1961 ((l + (m + deg) * this->degree) * deg + n
1963 dof) = solution ((l * deg + m) * deg + n,
1964 3 * (i + 2 * (j + 2 * k)) + 1);
1966 if (std::abs (solution
1967 ((l * deg + m) * deg + n,
1968 3 * (i + 2 * (j + 2 * k)) + 2))
1970 this->restriction[index][2 * (2 * i + j) + k]
1971 (l + ((m + 2 * deg) * deg + n) * this->degree
1972 + n_boundary_dofs, dof)
1973 = solution ((l * deg + m) * deg + n,
1974 3 * (i + 2 * (j + 2 * k)) + 2);
1990 std::vector<unsigned int>
1993 std::vector<unsigned int> dpo (dim + 1);
2002 dpo[1] = degree + 1;
2003 dpo[2] = 2 * degree * (degree + 1);
2006 dpo[3] = 3 * degree * degree * (degree + 1);
2028 const unsigned int face_index)
const 2030 Assert (shape_index < this->dofs_per_cell,
2035 const unsigned int deg = this->degree-1;
2042 if (!((shape_index > deg) && (shape_index < 2 * this->degree)))
2049 if ((shape_index > deg) &&
2058 if (shape_index < 3 * this->degree)
2065 if (!((shape_index >= 2 * this->degree) &&
2066 (shape_index < 3 * this->degree)))
2083 if (((shape_index > deg) && (shape_index < 2 * this->degree)) ||
2084 ((shape_index >= 5 * this->degree) &&
2085 (shape_index < 6 * this->degree)) ||
2086 ((shape_index >= 9 * this->degree) &&
2087 (shape_index < 10 * this->degree)) ||
2088 ((shape_index >= 11 * this->degree) &&
2121 if (((shape_index > deg) && (shape_index < 4 * this->degree)) ||
2122 ((shape_index >= 5 * this->degree) &&
2123 (shape_index < 8 * this->degree)) ||
2124 ((shape_index >= 9 * this->degree) &&
2125 (shape_index < 10 * this->degree)) ||
2126 ((shape_index >= 11 * this->degree) &&
2159 if ((shape_index < 3 * this->degree) ||
2160 ((shape_index >= 4 * this->degree) &&
2161 (shape_index < 7 * this->degree)) ||
2162 ((shape_index >= 8 * this->degree) &&
2163 (shape_index < 10 * this->degree)) ||
2194 if ((shape_index < 2 * this->degree) ||
2195 ((shape_index >= 3 * this->degree) &&
2196 (shape_index < 6 * this->degree)) ||
2197 ((shape_index >= 7 * this->degree) &&
2198 (shape_index < 8 * this->degree)) ||
2199 ((shape_index >= 10 * this->degree) &&
2232 if ((shape_index < 4 * this->degree) ||
2233 ((shape_index >= 8 * this->degree) &&
2261 if (((shape_index >= 4 * this->degree) &&
2316 if (this->degree < fe_nedelec_other->degree)
2318 else if (this->degree == fe_nedelec_other->degree)
2337 if (fe_nothing->is_dominating())
2361 std::vector<std::pair<unsigned int, unsigned int> >
2367 return std::vector<std::pair<unsigned int, unsigned int> > ();
2371 std::vector<std::pair<unsigned int, unsigned int> >
2386 std::vector<std::pair<unsigned int, unsigned int> > identities;
2388 for (
unsigned int i = 0;
2389 i < std::min (fe_nedelec_other->degree, this->degree); ++i)
2390 identities.emplace_back (i, i);
2401 return std::vector<std::pair<unsigned int, unsigned int> > ();
2407 return std::vector<std::pair<unsigned int, unsigned int> > ();
2412 std::vector<std::pair<unsigned int, unsigned int> >
2427 const unsigned int p = fe_nedelec_other->degree;
2428 const unsigned int q = this->degree;
2429 const unsigned int p_min = std::min (p, q);
2430 std::vector<std::pair<unsigned int, unsigned int> > identities;
2432 for (
unsigned int i = 0; i < p_min; ++i)
2433 for (
unsigned int j = 0; j < p_min - 1; ++j)
2435 identities.emplace_back (i * (q - 1) + j, i * (p - 1) + j);
2436 identities.emplace_back (i + (j + q - 1) * q, i + (j + p - 1) * p);
2448 return std::vector<std::pair<unsigned int, unsigned int> > ();
2454 return std::vector<std::pair<unsigned int, unsigned int> > ();
2477 ExcInterpolationNotImplemented()));
2481 Assert (interpolation_matrix.
n () == this->dofs_per_face,
2483 this->dofs_per_face));
2503 ExcInterpolationNotImplemented ()));
2504 interpolation_matrix = 0;
2508 for (
unsigned int i = 0; i <this->degree; ++i)
2509 interpolation_matrix (i, i) = 1.0;
2519 const unsigned int p = source_fe.
degree;
2520 const unsigned int q = this->degree;
2522 for (
unsigned int i = 0; i <q; ++i)
2524 for (
int j = 1; j < (int) GeometryInfo<dim>::lines_per_face; ++j)
2525 interpolation_matrix (j * p + i,
2528 for (
unsigned int j = 0; j < q-1; ++j)
2575 const unsigned int subface,
2584 ExcInterpolationNotImplemented ());
2588 Assert (interpolation_matrix.
n () == this->dofs_per_face,
2590 this->dofs_per_face));
2610 ExcInterpolationNotImplemented ()));
2611 interpolation_matrix = 0.0;
2615 const std::vector<Point<1> > &
2616 edge_quadrature_points = edge_quadrature.
get_points ();
2617 const unsigned int &n_edge_quadrature_points = edge_quadrature.
size ();
2623 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2624 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
2628 0.5 * (edge_quadrature_points[q_point] (0)
2631 interpolation_matrix (0, dof) += 0.5
2632 * edge_quadrature.
weight (q_point)
2633 * this->shape_value_component
2634 (dof, quadrature_point, 1);
2637 if (source_fe.
degree > 1)
2639 const std::vector<Polynomials::Polynomial<double> > &
2640 legendre_polynomials
2647 n_edge_quadrature_points);
2649 for (
unsigned int q_point = 0;
2650 q_point < n_edge_quadrature_points; ++q_point)
2653 = std::sqrt (edge_quadrature.
weight (q_point));
2655 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2656 assembling_matrix (i, q_point) = weight
2657 * legendre_polynomials[i + 1].value
2658 (edge_quadrature_points[q_point] (0));
2663 assembling_matrix.
mTmult (system_matrix, assembling_matrix);
2664 system_matrix_inv.
invert (system_matrix);
2670 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2674 for (
unsigned int q_point = 0;
2675 q_point < n_edge_quadrature_points; ++q_point)
2678 0.5 * (edge_quadrature_points[q_point] (0)
2681 edge_quadrature_points[q_point] (0));
2682 const double tmp = edge_quadrature.
weight (q_point)
2683 * (0.5 * this->shape_value_component
2684 (dof, quadrature_point_0, 1)
2685 - interpolation_matrix (0,
2688 (0, quadrature_point_1, 1));
2690 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2691 system_rhs (i) += tmp
2692 * legendre_polynomials[i + 1].value
2693 (edge_quadrature_points[q_point] (0));
2696 system_matrix_inv.
vmult (solution, system_rhs);
2698 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2699 if (std::abs (solution (i)) > 1e-14)
2700 interpolation_matrix (i + 1, dof) = solution (i);
2709 const double shifts[4][2] = { { 0.0, 0.0 }, { 1.0, 0.0 },
2710 { 0.0, 1.0 }, { 1.0, 1.0 }
2713 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2714 for (
unsigned int q_point = 0; q_point < n_edge_quadrature_points;
2717 const double weight = 0.5 * edge_quadrature.
weight (q_point);
2719 for (
unsigned int i = 0; i < 2; ++i)
2722 quadrature_point (0.5 * (i + shifts[subface][0]),
2723 0.5 * (edge_quadrature_points[q_point] (0)
2724 + shifts[subface][1]),
2727 interpolation_matrix (i * source_fe.
degree, dof) += weight
2728 * this->shape_value_component
2729 (this->face_to_cell_index (dof, 4),
2733 =
Point<dim> (0.5 * (edge_quadrature_points[q_point] (0)
2734 + shifts[subface][0]),
2735 0.5 * (i + shifts[subface][1]), 0.0);
2736 interpolation_matrix ((i + 2) * source_fe.
degree, dof)
2737 += weight * this->shape_value_component
2738 (this->face_to_cell_index (dof, 4),
2739 quadrature_point, 0);
2743 if (source_fe.
degree > 1)
2745 const std::vector<Polynomials::Polynomial<double> > &
2746 legendre_polynomials
2753 n_edge_quadrature_points);
2755 for (
unsigned int q_point = 0;
2756 q_point < n_edge_quadrature_points; ++q_point)
2759 = std::sqrt (edge_quadrature.
weight (q_point));
2761 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2762 assembling_matrix (i, q_point) = weight
2763 * legendre_polynomials[i + 1].value
2764 (edge_quadrature_points[q_point] (0));
2769 assembling_matrix.
mTmult (system_matrix, assembling_matrix);
2770 system_matrix_inv.
invert (system_matrix);
2779 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2783 for (
unsigned int q_point = 0;
2784 q_point < n_edge_quadrature_points; ++q_point)
2786 const double weight = edge_quadrature.
weight (q_point);
2788 for (
unsigned int i = 0; i < 2; ++i)
2792 (0.5 * (i + shifts[subface][0]),
2793 0.5 * (edge_quadrature_points[q_point] (0)
2794 + shifts[subface][1]), 0.0);
2796 edge_quadrature_points[q_point] (0),
2800 * (0.5 * this->shape_value_component
2801 (this->face_to_cell_index (dof, 4),
2802 quadrature_point_0, 1)
2803 - interpolation_matrix
2804 (i * source_fe.
degree, dof)
2807 quadrature_point_1, 1));
2809 =
Point<dim> (0.5 * (edge_quadrature_points[q_point] (0)
2810 + shifts[subface][0]),
2811 0.5 * (i + shifts[subface][1]),
2814 =
Point<dim> (edge_quadrature_points[q_point] (0),
2816 tmp (i + 2) = weight
2817 * (0.5 * this->shape_value_component
2818 (this->face_to_cell_index (dof, 4),
2819 quadrature_point_0, 0)
2820 - interpolation_matrix
2821 ((i + 2) * source_fe.
degree,
2824 ((i + 2) * source_fe.
degree,
2825 quadrature_point_1, 0));
2828 for (
unsigned int i = 0; i < source_fe.
degree - 1; ++i)
2831 = legendre_polynomials[i + 1].value
2832 (edge_quadrature_points[q_point] (0));
2834 for (
unsigned int j = 0;
2835 j < GeometryInfo<dim>::lines_per_face; ++j)
2836 system_rhs (i, j) += tmp (j) * L_i;
2840 system_matrix_inv.
mmult (solution, system_rhs);
2842 for (
unsigned int i = 0;
2843 i < GeometryInfo<dim>::lines_per_face; ++i)
2844 for (
unsigned int j = 0; j < source_fe.
degree - 1; ++j)
2845 if (std::abs (solution (j, i)) > 1e-14)
2846 interpolation_matrix (i * source_fe.
degree + j + 1,
2847 dof) = solution (j, i);
2851 const std::vector<Point<2> > &
2852 quadrature_points = quadrature.
get_points ();
2853 const std::vector<Polynomials::Polynomial<double> > &
2857 const unsigned int n_boundary_dofs
2859 const unsigned int &n_quadrature_points = quadrature.
size ();
2863 assembling_matrix (source_fe.
degree * (source_fe.
degree - 1),
2864 n_quadrature_points);
2866 for (
unsigned int q_point = 0; q_point < n_quadrature_points;
2869 const double weight = std::sqrt (quadrature.
weight (q_point));
2871 for (
unsigned int i = 0; i < source_fe.
degree; ++i)
2873 const double L_i = weight
2874 * legendre_polynomials[i].value
2875 (quadrature_points[q_point] (0));
2877 for (
unsigned int j = 0; j < source_fe.
degree - 1; ++j)
2878 assembling_matrix (i * (source_fe.
degree - 1) + j,
2880 = L_i * lobatto_polynomials[j + 2].value
2881 (quadrature_points[q_point] (1));
2886 assembling_matrix.
m ());
2888 assembling_matrix.
mTmult (system_matrix, assembling_matrix);
2889 system_matrix_inv.
reinit (system_matrix.m (),
2890 system_matrix.m ());
2891 system_matrix_inv.
invert (system_matrix);
2894 solution.
reinit (system_matrix_inv.
m (), 2);
2895 system_rhs.
reinit (system_matrix_inv.
m (), 2);
2898 for (
unsigned int dof = 0; dof < this->dofs_per_face; ++dof)
2902 for (
unsigned int q_point = 0;
2903 q_point < n_quadrature_points; ++q_point)
2907 (0.5 * (quadrature_points[q_point] (0)
2908 + shifts[subface][0]),
2909 0.5 * (quadrature_points[q_point] (1)
2910 + shifts[subface][1]), 0.0);
2911 tmp (0) = 0.5 * this->shape_value_component
2912 (this->face_to_cell_index (dof, 4),
2913 quadrature_point, 0);
2914 tmp (1) = 0.5 * this->shape_value_component
2915 (this->face_to_cell_index (dof, 4),
2916 quadrature_point, 1);
2918 =
Point<dim> (quadrature_points[q_point] (0),
2919 quadrature_points[q_point] (1), 0.0);
2921 for (
unsigned int i = 0; i < 2; ++i)
2922 for (
unsigned int j = 0; j < source_fe.
degree; ++j)
2924 tmp (0) -= interpolation_matrix
2925 ((i + 2) * source_fe.
degree + j, dof)
2927 ((i + 2) * source_fe.
degree + j,
2928 quadrature_point, 0);
2929 tmp (1) -= interpolation_matrix
2930 (i * source_fe.
degree + j, dof)
2932 (i * source_fe.
degree + j,
2933 quadrature_point, 1);
2936 tmp *= quadrature.
weight (q_point);
2938 for (
unsigned int i = 0; i < source_fe.
degree; ++i)
2940 const double L_i_0 = legendre_polynomials[i].value
2941 (quadrature_points[q_point] (0));
2942 const double L_i_1 = legendre_polynomials[i].value
2943 (quadrature_points[q_point] (1));
2945 for (
unsigned int j = 0; j < source_fe.
degree - 1; ++j)
2947 system_rhs (i * (source_fe.
degree - 1) + j, 0)
2949 * lobatto_polynomials[j + 2].value
2950 (quadrature_points[q_point] (1));
2951 system_rhs (i * (source_fe.
degree - 1) + j, 1)
2953 * lobatto_polynomials[j + 2].value
2954 (quadrature_points[q_point] (0));
2959 system_matrix_inv.
mmult (solution, system_rhs);
2961 for (
unsigned int i = 0; i < source_fe.
degree; ++i)
2962 for (
unsigned int j = 0; j < source_fe.
degree - 1; ++j)
2964 if (std::abs (solution (i * (source_fe.
degree - 1) + j, 0))
2966 interpolation_matrix (i * (source_fe.
degree - 1)
2967 + j + n_boundary_dofs, dof)
2968 = solution (i * (source_fe.
degree - 1) + j, 0);
2970 if (std::abs (solution (i * (source_fe.
degree - 1) + j, 1))
2972 interpolation_matrix (i + (j + source_fe.
degree - 1)
2974 + n_boundary_dofs, dof)
2975 = solution (i * (source_fe.
degree - 1) + j, 1);
2997 ExcMessage(
"Prolongation matrices are only available for refined cells!"));
3002 if (this->prolongation[refinement_case-1][child].n() == 0)
3007 if (this->prolongation[refinement_case-1][child].n() ==
3008 this->dofs_per_cell)
3009 return this->prolongation[refinement_case-1][child];
3020 #ifdef DEBUG_NEDELEC 3021 deallog <<
"Embedding" << std::endl;
3026 internal::FE_Nedelec::get_embedding_computation_tolerance(this->
degree));
3027 #ifdef DEBUG_NEDELEC 3028 deallog <<
"Restriction" << std::endl;
3036 return this->prolongation[refinement_case-1][child];
3048 ExcMessage(
"Restriction matrices are only available for refined cells!"));
3053 if (this->restriction[refinement_case-1][child].n() == 0)
3058 if (this->restriction[refinement_case-1][child].n() ==
3059 this->dofs_per_cell)
3060 return this->restriction[refinement_case-1][child];
3071 #ifdef DEBUG_NEDELEC 3072 deallog <<
"Embedding" << std::endl;
3077 internal::FE_Nedelec::get_embedding_computation_tolerance(this->
degree));
3078 #ifdef DEBUG_NEDELEC 3079 deallog <<
"Restriction" << std::endl;
3087 return this->restriction[refinement_case-1][child];
3101 std::vector<double> &nodal_values)
const 3103 const unsigned int deg = this->degree-1;
3104 Assert (support_point_values.size () == this->generalized_support_points.size (),
3106 this->generalized_support_points.size ()));
3109 Assert (nodal_values.size () == this->dofs_per_cell,
3111 std::fill (nodal_values.begin (), nodal_values.end (), 0.0);
3119 const QGauss<dim - 1> reference_edge_quadrature (this->degree);
3120 const unsigned int &
3121 n_edge_points = reference_edge_quadrature.size ();
3123 for (
unsigned int i = 0; i < 2; ++i)
3124 for (
unsigned int j = 0; j < 2; ++j)
3126 for (
unsigned int q_point = 0; q_point < n_edge_points;
3128 nodal_values[(i + 2 * j) * this->degree]
3129 += reference_edge_quadrature.weight (q_point)
3130 * support_point_values[q_point + (i + 2 * j) * n_edge_points][1 - j];
3135 if (std::abs (nodal_values[(i + 2 * j) * this->degree]) < 1e-14)
3136 nodal_values[(i + 2 * j) * this->degree] = 0.0;
3149 if (this->degree-1 > 1)
3154 const std::vector<Polynomials::Polynomial<double> > &
3159 std::vector<Polynomials::Polynomial<double> >
3160 lobatto_polynomials_grad (this->degree);
3162 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size ();
3164 lobatto_polynomials_grad[i]
3165 = lobatto_polynomials[i + 1].derivative ();
3170 for (
unsigned int i = 0; i < system_matrix.
m (); ++i)
3171 for (
unsigned int j = 0; j < system_matrix.
n (); ++j)
3172 for (
unsigned int q_point = 0; q_point < n_edge_points;
3174 system_matrix (i, j)
3175 += boundary_weights (q_point, j)
3176 * lobatto_polynomials_grad[i + 1].value
3177 (this->generalized_face_support_points[q_point]
3182 system_matrix_inv.
invert (system_matrix);
3190 for (
unsigned int line = 0;
3191 line < GeometryInfo<dim>::lines_per_cell; ++line)
3196 for (
unsigned int q_point = 0; q_point < n_edge_points;
3200 = support_point_values[line * n_edge_points + q_point][line_coordinate[line]]
3201 - nodal_values[line * this->degree]
3202 * this->shape_value_component
3203 (line * this->degree,
3204 this->generalized_support_points[line
3207 line_coordinate[line]);
3209 for (
unsigned int i = 0; i < system_rhs.size (); ++i)
3210 system_rhs (i) += boundary_weights (q_point, i) * tmp;
3213 system_matrix_inv.
vmult (solution, system_rhs);
3219 for (
unsigned int i = 0; i < solution.size (); ++i)
3220 if (std::abs (solution (i)) > 1e-14)
3221 nodal_values[line * this->degree + i + 1] = solution (i);
3233 const QGauss<dim> reference_quadrature (this->degree);
3234 const unsigned int &
3235 n_interior_points = reference_quadrature.
size ();
3236 const std::vector<Polynomials::Polynomial<double> > &
3237 legendre_polynomials
3240 system_matrix.
reinit ((this->degree-1) * this->degree,
3241 (this->degree-1) * this->degree);
3244 for (
unsigned int i = 0; i < this->degree; ++i)
3245 for (
unsigned int j = 0; j < this->degree-1; ++j)
3246 for (
unsigned int k = 0; k < this->degree; ++k)
3247 for (
unsigned int l = 0; l < this->degree-1; ++l)
3248 for (
unsigned int q_point = 0;
3249 q_point < n_interior_points; ++q_point)
3250 system_matrix (i * (this->degree-1) + j, k * (this->degree-1) + l)
3251 += reference_quadrature.
weight (q_point)
3252 * legendre_polynomials[i].value
3253 (this->generalized_support_points[q_point
3257 * lobatto_polynomials[j + 2].value
3258 (this->generalized_support_points[q_point
3262 * lobatto_polynomials_grad[k].value
3263 (this->generalized_support_points[q_point
3267 * lobatto_polynomials[l + 2].value
3268 (this->generalized_support_points[q_point
3273 system_matrix_inv.
reinit (system_matrix.
m (),
3274 system_matrix.
m ());
3275 system_matrix_inv.
invert (system_matrix);
3279 system_rhs.reinit (system_matrix_inv.
m ());
3282 for (
unsigned int q_point = 0; q_point < n_interior_points;
3287 * n_edge_points][0];
3289 for (
unsigned int i = 0; i < 2; ++i)
3290 for (
unsigned int j = 0; j <= deg; ++j)
3291 tmp -= nodal_values[(i + 2) * this->degree + j]
3292 * this->shape_value_component
3293 ((i + 2) * this->degree + j,
3294 this->generalized_support_points[q_point
3299 for (
unsigned int i = 0; i <= deg; ++i)
3300 for (
unsigned int j = 0; j < deg; ++j)
3301 system_rhs (i * deg + j)
3302 += reference_quadrature.
weight (q_point) * tmp
3303 * lobatto_polynomials_grad[i].value
3304 (this->generalized_support_points[q_point
3308 * lobatto_polynomials[j + 2].value
3309 (this->generalized_support_points[q_point
3315 solution.reinit (system_matrix.
m ());
3316 system_matrix_inv.
vmult (solution, system_rhs);
3322 for (
unsigned int i = 0; i <= deg; ++i)
3323 for (
unsigned int j = 0; j < deg; ++j)
3324 if (std::abs (solution (i * deg + j)) > 1e-14)
3327 = solution (i * deg + j);
3334 for (
unsigned int q_point = 0; q_point < n_interior_points;
3339 * n_edge_points][1];
3341 for (
unsigned int i = 0; i < 2; ++i)
3342 for (
unsigned int j = 0; j <= deg; ++j)
3343 tmp -= nodal_values[i * this->degree + j]
3344 * this->shape_value_component
3345 (i * this->degree + j,
3346 this->generalized_support_points[q_point
3351 for (
unsigned int i = 0; i <= deg; ++i)
3352 for (
unsigned int j = 0; j < deg; ++j)
3353 system_rhs (i * deg + j)
3354 += reference_quadrature.
weight (q_point) * tmp
3355 * lobatto_polynomials_grad[i].value
3356 (this->generalized_support_points[q_point
3360 * lobatto_polynomials[j + 2].value
3361 (this->generalized_support_points[q_point
3367 system_matrix_inv.
vmult (solution, system_rhs);
3373 for (
unsigned int i = 0; i <= deg; ++i)
3374 for (
unsigned int j = 0; j < deg; ++j)
3375 if (std::abs (solution (i * deg + j)) > 1e-14)
3377 + deg) * this->degree]
3378 = solution (i * deg + j);
3388 const QGauss<1> reference_edge_quadrature (this->degree);
3389 const unsigned int &
3390 n_edge_points = reference_edge_quadrature.
size ();
3392 for (
unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
3394 for (
unsigned int i = 0; i < 4; ++i)
3395 nodal_values[(i + 8) * this->degree]
3396 += reference_edge_quadrature.
weight (q_point)
3397 * support_point_values[q_point + (i + 8) * n_edge_points][2];
3399 for (
unsigned int i = 0; i < 2; ++i)
3400 for (
unsigned int j = 0; j < 2; ++j)
3401 for (
unsigned int k = 0; k < 2; ++k)
3402 nodal_values[(i + 2 * (2 * j + k)) * this->degree]
3403 += reference_edge_quadrature.
weight (q_point)
3404 * support_point_values[q_point + (i + 2 * (2 * j + k))
3405 * n_edge_points][1 - k];
3412 for (
unsigned int i = 0; i < 4; ++i)
3413 if (std::abs (nodal_values[(i + 8) * this->degree]) < 1e-14)
3414 nodal_values[(i + 8) * this->degree] = 0.0;
3416 for (
unsigned int i = 0; i < 2; ++i)
3417 for (
unsigned int j = 0; j < 2; ++j)
3418 for (
unsigned int k = 0; k < 2; ++k)
3419 if (std::abs (nodal_values[(i + 2 * (2 * j + k)) * this->degree])
3421 nodal_values[(i + 2 * (2 * j + k)) * this->degree] = 0.0;
3432 if (this->degree > 1)
3437 const std::vector<Polynomials::Polynomial<double> > &
3442 std::vector<Polynomials::Polynomial<double> >
3443 lobatto_polynomials_grad (this->degree);
3445 for (
unsigned int i = 0; i < lobatto_polynomials_grad.size ();
3447 lobatto_polynomials_grad[i]
3448 = lobatto_polynomials[i + 1].derivative ();
3453 for (
unsigned int i = 0; i < system_matrix.
m (); ++i)
3454 for (
unsigned int j = 0; j < system_matrix.
n (); ++j)
3455 for (
unsigned int q_point = 0; q_point < n_edge_points;
3457 system_matrix (i, j)
3458 += boundary_weights (q_point, j)
3459 * lobatto_polynomials_grad[i + 1].value
3460 (this->generalized_face_support_points[q_point]
3465 system_matrix_inv.
invert (system_matrix);
3469 = {1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2};
3473 for (
unsigned int line = 0;
3474 line < GeometryInfo<dim>::lines_per_cell; ++line)
3479 for (
unsigned int q_point = 0; q_point < this->degree; ++q_point)
3482 = support_point_values[line * this->degree
3483 + q_point][line_coordinate[line]]
3484 - nodal_values[line * this->degree]
3485 * this->shape_value_component
3486 (line * this->degree,
3487 this->generalized_support_points[line
3490 line_coordinate[line]);
3492 for (
unsigned int i = 0; i < system_rhs.size (); ++i)
3493 system_rhs (i) += boundary_weights (q_point, i)
3497 system_matrix_inv.
vmult (solution, system_rhs);
3503 for (
unsigned int i = 0; i < solution.size (); ++i)
3504 if (std::abs (solution (i)) > 1e-14)
3505 nodal_values[line * this->degree + i + 1] = solution (i);
3516 const std::vector<Polynomials::Polynomial<double> > &
3517 legendre_polynomials
3519 const unsigned int n_face_points = n_edge_points * n_edge_points;
3521 system_matrix.
reinit ((this->degree-1) * this->degree,
3522 (this->degree-1) * this->degree);
3525 for (
unsigned int i = 0; i < this->degree; ++i)
3526 for (
unsigned int j = 0; j < this->degree-1; ++j)
3527 for (
unsigned int k = 0; k < this->degree; ++k)
3528 for (
unsigned int l = 0; l < this->degree-1; ++l)
3529 for (
unsigned int q_point = 0; q_point < n_face_points;
3531 system_matrix (i * (this->degree-1) + j, k * (this->degree-1) + l)
3532 += boundary_weights (q_point + n_edge_points,
3533 2 * (k * (this->degree-1) + l))
3534 * legendre_polynomials[i].value
3535 (this->generalized_face_support_points[q_point
3539 * lobatto_polynomials[j + 2].value
3540 (this->generalized_face_support_points[q_point
3545 system_matrix_inv.
reinit (system_matrix.
m (),
3546 system_matrix.
m ());
3547 system_matrix_inv.
invert (system_matrix);
3548 solution.reinit (system_matrix.
m ());
3549 system_rhs.reinit (system_matrix.
m ());
3553 = {{1, 2}, {1, 2}, {2, 0}, {2, 0}, {0, 1}, {0, 1}};
3556 = {{0, 4, 8, 10}, {1, 5, 9, 11}, {8, 9, 2, 6},
3557 {10, 11, 3, 7}, {2, 3, 0, 1}, {6, 7, 4, 5}
3560 for (
unsigned int face = 0;
3561 face < GeometryInfo<dim>::faces_per_cell; ++face)
3568 for (
unsigned int q_point = 0; q_point < n_face_points;
3572 = support_point_values[q_point
3574 * n_edge_points][face_coordinates[face][0]];
3576 for (
unsigned int i = 0; i < 2; ++i)
3577 for (
unsigned int j = 0; j <= deg; ++j)
3578 tmp -= nodal_values[edge_indices[face][i]
3580 * this->shape_value_component
3581 (edge_indices[face][i] * this->degree + j,
3582 this->generalized_support_points[q_point
3585 face_coordinates[face][0]);
3587 for (
unsigned int i = 0; i <= deg; ++i)
3588 for (
unsigned int j = 0; j < deg; ++j)
3589 system_rhs (i * deg + j)
3590 += boundary_weights (q_point + n_edge_points,
3591 2 * (i * deg + j)) * tmp;
3594 system_matrix_inv.
vmult (solution, system_rhs);
3600 for (
unsigned int i = 0; i <= deg; ++i)
3601 for (
unsigned int j = 0; j < deg; ++j)
3602 if (std::abs (solution (i * deg + j)) > 1e-14)
3603 nodal_values[(2 * face * this->degree + i
3606 = solution (i * deg + j);
3613 for (
unsigned int q_point = 0; q_point < n_face_points;
3617 = support_point_values[q_point
3619 * n_edge_points][face_coordinates[face][1]];
3621 for (
int i = 2; i < (int) GeometryInfo<dim>::lines_per_face; ++i)
3622 for (
unsigned int j = 0; j <= deg; ++j)
3623 tmp -= nodal_values[edge_indices[face][i]
3625 * this->shape_value_component
3626 (edge_indices[face][i] * this->degree + j,
3627 this->generalized_support_points[q_point
3630 face_coordinates[face][1]);
3632 for (
unsigned int i = 0; i <= deg; ++i)
3633 for (
unsigned int j = 0; j < deg; ++j)
3634 system_rhs (i * deg + j)
3635 += boundary_weights (q_point + n_edge_points,
3636 2 * (i * deg + j) + 1)
3640 system_matrix_inv.
vmult (solution, system_rhs);
3646 for (
unsigned int i = 0; i <= deg; ++i)
3647 for (
unsigned int j = 0; j < deg; ++j)
3648 if (std::abs (solution (i * deg + j)) > 1e-14)
3651 = solution (i * deg + j);
3659 const QGauss<dim> reference_quadrature (this->degree);
3661 n_interior_points = reference_quadrature.
size ();
3665 system_matrix.
reinit (this->degree * deg * deg,
3666 this->degree * deg * deg);
3669 for (
unsigned int i = 0; i <= deg; ++i)
3670 for (
unsigned int j = 0; j < deg; ++j)
3671 for (
unsigned int k = 0; k < deg; ++k)
3672 for (
unsigned int l = 0; l <= deg; ++l)
3673 for (
unsigned int m = 0; m < deg; ++m)
3674 for (
unsigned int n = 0; n < deg; ++n)
3675 for (
unsigned int q_point = 0;
3676 q_point < n_interior_points; ++q_point)
3677 system_matrix ((i * deg + j) * deg + k,
3678 (l * deg + m) * deg + n)
3679 += reference_quadrature.
weight (q_point)
3680 * legendre_polynomials[i].value
3681 (this->generalized_support_points[q_point
3687 * lobatto_polynomials[j + 2].value
3688 (this->generalized_support_points[q_point
3694 * lobatto_polynomials[k + 2].value
3695 (this->generalized_support_points[q_point
3701 * lobatto_polynomials_grad[l].value
3702 (this->generalized_support_points[q_point
3708 * lobatto_polynomials[m + 2].value
3709 (this->generalized_support_points[q_point
3715 * lobatto_polynomials[n + 2].value
3716 (this->generalized_support_points[q_point
3723 system_matrix_inv.
reinit (system_matrix.
m (),
3724 system_matrix.
m ());
3725 system_matrix_inv.
invert (system_matrix);
3727 system_rhs.reinit (system_matrix.
m ());
3730 for (
unsigned int q_point = 0; q_point < n_interior_points;
3737 * n_face_points][0];
3739 for (
unsigned int i = 0; i <= deg; ++i)
3741 for (
unsigned int j = 0; j < 2; ++j)
3742 for (
unsigned int k = 0; k < 2; ++k)
3743 tmp -= nodal_values[i + (j + 4 * k + 2) * this->degree]
3744 * this->shape_value_component
3745 (i + (j + 4 * k + 2) * this->degree,
3746 this->generalized_support_points[q_point
3753 for (
unsigned int j = 0; j < deg; ++j)
3754 for (
unsigned int k = 0; k < 4; ++k)
3755 tmp -= 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[q_point
3772 for (
unsigned int i = 0; i <= deg; ++i)
3773 for (
unsigned int j = 0; j < deg; ++j)
3774 for (
unsigned int k = 0; k < deg; ++k)
3775 system_rhs ((i * deg + j) * deg + k)
3776 += reference_quadrature.
weight (q_point) * tmp
3777 * lobatto_polynomials_grad[i].value
3778 (this->generalized_support_points[q_point
3784 * lobatto_polynomials[j + 2].value
3785 (this->generalized_support_points[q_point
3791 * lobatto_polynomials[k + 2].value
3792 (this->generalized_support_points[q_point
3800 solution.reinit (system_rhs.size ());
3801 system_matrix_inv.
vmult (solution, system_rhs);
3807 for (
unsigned int i = 0; i <= deg; ++i)
3808 for (
unsigned int j = 0; j < deg; ++j)
3809 for (
unsigned int k = 0; k < deg; ++k)
3810 if (std::abs (solution ((i * deg + j) * deg + k)) > 1e-14)
3815 = solution ((i * deg + j) * deg + k);
3820 for (
unsigned int q_point = 0; q_point < n_interior_points;
3827 * n_face_points][1];
3829 for (
unsigned int i = 0; i <= deg; ++i)
3830 for (
unsigned int j = 0; j < 2; ++j)
3832 for (
unsigned int k = 0; k < 2; ++k)
3833 tmp -= nodal_values[i + (4 * j + k) * this->degree]
3834 * this->shape_value_component
3835 (i + (4 * j + k) * this->degree,
3836 this->generalized_support_points[q_point
3843 for (
unsigned int k = 0; k < deg; ++k)
3844 tmp -= nodal_values[(i + 2 * j * this->degree
3848 * this->shape_value_component
3849 ((i + 2 * j * this->degree
3853 this->generalized_support_points[q_point
3859 + nodal_values[i + ((2 * j + 9) * deg + k
3862 * this->shape_value_component
3863 (i + ((2 * j + 9) * deg + k
3866 this->generalized_support_points[q_point
3874 for (
unsigned int i = 0; i <= deg; ++i)
3875 for (
unsigned int j = 0; j < deg; ++j)
3876 for (
unsigned int k = 0; k < deg; ++k)
3877 system_rhs ((i * deg + j) * deg + k)
3878 += reference_quadrature.
weight (q_point) * tmp
3879 * lobatto_polynomials_grad[i].value
3880 (this->generalized_support_points[q_point
3886 * lobatto_polynomials[j + 2].value
3887 (this->generalized_support_points[q_point
3893 * lobatto_polynomials[k + 2].value
3894 (this->generalized_support_points[q_point
3902 system_matrix_inv.
vmult (solution, system_rhs);
3908 for (
unsigned int i = 0; i <= deg; ++i)
3909 for (
unsigned int j = 0; j < deg; ++j)
3910 for (
unsigned int k = 0; k < deg; ++k)
3911 if (std::abs (solution ((i * deg + j) * deg + k)) > 1e-14)
3912 nodal_values[((i + this->degree + 2
3917 = solution ((i * deg + j) * deg + k);
3922 for (
unsigned int q_point = 0; q_point < n_interior_points;
3929 * n_face_points][2];
3931 for (
unsigned int i = 0; i <= deg; ++i)
3932 for (
unsigned int j = 0; j < 4; ++j)
3934 tmp -= nodal_values[i + (j + 8) * this->degree]
3935 * this->shape_value_component
3936 (i + (j + 8) * this->degree,
3937 this->generalized_support_points[q_point
3944 for (
unsigned int k = 0; k < deg; ++k)
3945 tmp -= nodal_values[i + ((2 * j + 1) * deg + k
3948 * this->shape_value_component
3949 (i + ((2 * j + 1) * deg + k
3952 this->generalized_support_points[q_point
3960 for (
unsigned int i = 0; i <= deg; ++i)
3961 for (
unsigned int j = 0; j < deg; ++j)
3962 for (
unsigned int k = 0; k < deg; ++k)
3963 system_rhs ((i * deg + j) * deg + k)
3964 += reference_quadrature.
weight (q_point) * tmp
3965 * lobatto_polynomials_grad[i].value
3966 (this->generalized_support_points[q_point
3972 * lobatto_polynomials[j + 2].value
3973 (this->generalized_support_points[q_point
3979 * lobatto_polynomials[k + 2].value
3980 (this->generalized_support_points[q_point
3988 system_matrix_inv.
vmult (solution, system_rhs);
3994 for (
unsigned int i = 0; i <= deg; ++i)
3995 for (
unsigned int j = 0; j < deg; ++j)
3996 for (
unsigned int k = 0; k < deg; ++k)
3997 if (std::abs (solution ((i * deg + j) * deg + k)) > 1e-14)
3998 nodal_values[i + ((j + 2 * (deg
4003 = solution ((i * deg + j) * deg + k);
4017 std::pair<Table<2,bool>, std::vector<unsigned int> >
4021 for (
unsigned int d=0; d<dim; ++d)
4022 for (
unsigned int i=0; i<this->dofs_per_cell; ++i)
4023 constant_modes(d,i) =
true;
4024 std::vector<unsigned int> components;
4025 for (
unsigned int d=0; d<dim; ++d)
4026 components.push_back(d);
4027 return std::pair<Table<2,bool>, std::vector<unsigned int> >
4028 (constant_modes, components);
4045 #include "fe_nedelec.inst" 4048 DEAL_II_NAMESPACE_CLOSE
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
FullMatrix< double > interface_constraints
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim > &fe_other) const
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 std::size_t memory_consumption() const
const unsigned int degree
const Point< dim > & point(const unsigned int i) const
virtual void get_subface_interpolation_matrix(const FiniteElement< dim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
#define AssertThrow(cond, exc)
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim > &fe_other) const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree, bool dg=false)
void initialize_support_points(const unsigned int order)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
virtual std::string get_name() const
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const
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)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
virtual std::string get_name() const =0
virtual std::unique_ptr< FiniteElement< dim, dim > > clone() const
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim > &fe_other) const
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::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim > &fe_other) const
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)
virtual double shape_value_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
static ::ExceptionBase & ExcNotImplemented()
virtual bool hp_constraints_are_implemented() const
void initialize_restriction()
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
FullMatrix< double > inverse_node_matrix
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)
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const
virtual void get_face_interpolation_matrix(const FiniteElement< dim > &source, FullMatrix< double > &matrix) const
void mTmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
double weight(const unsigned int i) const