17 #include <deal.II/base/quadrature.h> 18 #include <deal.II/base/quadrature_lib.h> 19 #include <deal.II/base/std_cxx14/memory.h> 21 #include <deal.II/fe/fe.h> 22 #include <deal.II/fe/fe_bernstein.h> 23 #include <deal.II/fe/fe_dgq.h> 24 #include <deal.II/fe/fe_nothing.h> 25 #include <deal.II/fe/fe_q.h> 26 #include <deal.II/fe/fe_q_bubbles.h> 27 #include <deal.II/fe/fe_q_dg0.h> 28 #include <deal.II/fe/fe_q_hierarchical.h> 29 #include <deal.II/fe/fe_q_iso_q1.h> 30 #include <deal.II/fe/fe_tools.h> 32 #include <deal.II/lac/vector.h> 38 DEAL_II_NAMESPACE_OPEN
48 get_QGaussLobatto_points(
const unsigned int degree)
53 return std::vector<Point<1>>(1,
Point<1>(0.5));
61 template <
int dim,
int spacedim>
76 std::vector<bool>(1, true)))
93 template <
int dim,
int spacedim>
100 polynomials.size() - 1,
103 polynomials.size() - 1),
105 polynomials.size() - 1)
111 polynomials.size() - 1)
113 std::vector<bool>(1, true)))
125 template <
int dim,
int spacedim>
133 std::ostringstream namebuf;
135 << this->degree <<
")";
136 return namebuf.str();
141 template <
int dim,
int spacedim>
145 std::vector<double> & nodal_values)
const 148 this->get_unit_support_points().size());
152 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
156 nodal_values[i] = support_point_values[i](0);
162 template <
int dim,
int spacedim>
163 std::unique_ptr<FiniteElement<dim, spacedim>>
166 return std_cxx14::make_unique<FE_DGQ<dim, spacedim>>(*this);
175 template <
int dim,
int spacedim>
176 std::vector<unsigned int>
179 std::vector<unsigned int> dpo(dim + 1, 0U);
181 for (
unsigned int i = 1; i < dim; ++i)
188 template <
int dim,
int spacedim>
191 const char direction)
const 193 const unsigned int n = this->degree + 1;
195 for (
unsigned int i = 1; i < dim; ++i)
204 for (
unsigned int i = n; i > 0;)
214 for (
unsigned int iz = 0; iz < ((dim > 2) ? n : 1); ++iz)
215 for (
unsigned int j = 0; j < n; ++j)
216 for (
unsigned int i = 0; i < n; ++i)
218 unsigned int k = n * i - j + n - 1 + n * n * iz;
225 for (
unsigned int iz = 0; iz < ((dim > 2) ? n : 1); ++iz)
226 for (
unsigned int iy = 0; iy < n; ++iy)
227 for (
unsigned int ix = 0; ix < n; ++ix)
229 unsigned int k = n * ix - iy + n - 1 + n * n * iz;
237 for (
unsigned int iz = 0; iz < n; ++iz)
238 for (
unsigned int iy = 0; iy < n; ++iy)
239 for (
unsigned int ix = 0; ix < n; ++ix)
241 unsigned int k = n * (n * iy - iz + n - 1) + ix;
249 for (
unsigned int iz = 0; iz < n; ++iz)
250 for (
unsigned int iy = 0; iy < n; ++iy)
251 for (
unsigned int ix = 0; ix < n; ++ix)
253 unsigned int k = n * (n * iy - iz + n - 1) + ix;
265 template <
int dim,
int spacedim>
277 typename FE::ExcInterpolationNotImplemented());
284 Assert(interpolation_matrix.
m() == this->dofs_per_cell,
296 this->dofs_per_cell);
300 for (
unsigned int j = 0; j < this->dofs_per_cell; ++j)
305 const Point<dim> p = this->unit_support_points[j];
306 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
307 cell_interpolation(j, i) = this->poly_space.compute_value(i, p);
318 cell_interpolation.
mmult(interpolation_matrix, source_interpolation);
321 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
323 if (std::fabs(interpolation_matrix(i, j)) < 1e-15)
324 interpolation_matrix(i, j) = 0.;
331 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
335 sum += interpolation_matrix(i, j);
337 Assert(std::fabs(
sum - 1) < 5e-14 * std::max(this->degree, 1U) * dim,
344 template <
int dim,
int spacedim>
356 (void)interpolation_matrix;
360 typename FE::ExcInterpolationNotImplemented());
362 Assert(interpolation_matrix.
m() == 0,
364 Assert(interpolation_matrix.
n() == 0,
370 template <
int dim,
int spacedim>
383 (void)interpolation_matrix;
387 typename FE::ExcInterpolationNotImplemented());
389 Assert(interpolation_matrix.
m() == 0,
391 Assert(interpolation_matrix.
n() == 0,
397 template <
int dim,
int spacedim>
400 const unsigned int child,
409 "Prolongation matrices are only available for refined cells!"));
416 if (this->prolongation[refinement_case - 1][child].n() == 0)
418 std::lock_guard<std::mutex> lock(this->mutex);
421 if (this->prolongation[refinement_case - 1][child].n() ==
423 return this->prolongation[refinement_case - 1][child];
431 std::vector<std::vector<FullMatrix<double>>> isotropic_matrices(
433 isotropic_matrices.back().resize(
445 isotropic_matrices.back());
472 return this->prolongation[refinement_case - 1][child];
477 template <
int dim,
int spacedim>
480 const unsigned int child,
489 "Restriction matrices are only available for refined cells!"));
496 if (this->restriction[refinement_case - 1][child].n() == 0)
498 std::lock_guard<std::mutex> lock(this->mutex);
501 if (this->restriction[refinement_case - 1][child].n() ==
503 return this->restriction[refinement_case - 1][child];
511 std::vector<std::vector<FullMatrix<double>>> isotropic_matrices(
513 isotropic_matrices.back().resize(
524 this_nonconst.
restriction[refinement_case - 1].swap(
525 isotropic_matrices.back());
552 return this->restriction[refinement_case - 1][child];
557 template <
int dim,
int spacedim>
566 template <
int dim,
int spacedim>
567 std::vector<std::pair<unsigned int, unsigned int>>
575 return std::vector<std::pair<unsigned int, unsigned int>>();
580 template <
int dim,
int spacedim>
581 std::vector<std::pair<unsigned int, unsigned int>>
589 return std::vector<std::pair<unsigned int, unsigned int>>();
594 template <
int dim,
int spacedim>
595 std::vector<std::pair<unsigned int, unsigned int>>
603 return std::vector<std::pair<unsigned int, unsigned int>>();
608 template <
int dim,
int spacedim>
612 const unsigned int codim)
const 632 if (this->degree < fe_dgq_other->degree)
634 else if (this->degree == fe_dgq_other->degree)
642 if (this->degree < fe_q_other->degree)
644 else if (this->degree == fe_q_other->degree)
652 if (this->degree < fe_bernstein_other->degree)
654 else if (this->degree == fe_bernstein_other->degree)
662 if (this->degree < fe_bubbles_other->degree)
664 else if (this->degree == fe_bubbles_other->degree)
672 if (this->degree < fe_dg0_other->degree)
674 else if (this->degree == fe_dg0_other->degree)
682 if (this->degree < fe_q_iso_q1_other->degree)
684 else if (this->degree == fe_q_iso_q1_other->degree)
692 if (this->degree < fe_hierarchical_other->degree)
694 else if (this->degree == fe_hierarchical_other->degree)
702 if (fe_nothing->is_dominating())
717 template <
int dim,
int spacedim>
720 const unsigned int face_index)
const 722 Assert(shape_index < this->dofs_per_cell,
727 unsigned int n = this->degree + 1;
732 if (this->unit_support_points.empty())
738 bool support_points_on_boundary =
true;
739 for (
unsigned int d = 0; d < dim; ++d)
740 if (std::abs(this->unit_support_points[0][d]) > 1e-13)
741 support_points_on_boundary =
false;
742 for (
unsigned int d = 0; d < dim; ++d)
743 if (std::abs(this->unit_support_points.back()[d] - 1.) > 1e-13)
744 support_points_on_boundary =
false;
745 if (support_points_on_boundary ==
false)
748 unsigned int n2 = n * n;
760 return (((shape_index == 0) && (face_index == 0)) ||
761 ((shape_index == this->degree) && (face_index == 1)));
766 if (face_index == 0 && (shape_index % n) == 0)
768 if (face_index == 1 && (shape_index % n) == this->degree)
770 if (face_index == 2 && shape_index < n)
772 if (face_index == 3 && shape_index >= this->dofs_per_cell - n)
779 const unsigned int in2 = shape_index % n2;
782 if (face_index == 0 && (shape_index % n) == 0)
785 if (face_index == 1 && (shape_index % n) == n - 1)
788 if (face_index == 2 && in2 < n)
791 if (face_index == 3 && in2 >= n2 - n)
794 if (face_index == 4 && shape_index < n2)
797 if (face_index == 5 && shape_index >= this->dofs_per_cell - n2)
810 template <
int dim,
int spacedim>
811 std::pair<Table<2, bool>, std::vector<unsigned int>>
815 constant_modes.
fill(
true);
816 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
817 constant_modes, std::vector<unsigned int>(1, 0));
822 template <
int dim,
int spacedim>
834 template <
int dim,
int spacedim>
838 Polynomials::generate_complete_Lagrange_basis(points.get_points()))
847 template <
int dim,
int spacedim>
853 std::ostringstream namebuf;
854 bool equidistant =
true;
855 std::vector<double> points(this->degree + 1);
857 std::vector<unsigned int> lexicographic =
858 this->poly_space.get_numbering_inverse();
859 for (
unsigned int j = 0; j <= this->degree; j++)
860 points[j] = this->unit_support_points[lexicographic[j]][0];
863 for (
unsigned int j = 0; j <= this->degree; j++)
864 if (std::abs(points[j] - static_cast<double>(j) / this->degree) > 1e-15)
869 if (this->degree == 0 && std::abs(points[0] - 0.5) < 1e-15)
872 if (equidistant ==
true)
874 if (this->degree > 2)
875 namebuf <<
"FE_DGQArbitraryNodes<" 877 <<
">(QIterated(QTrapez()," << this->degree <<
"))";
880 << this->degree <<
")";
881 return namebuf.str();
886 bool gauss_lobatto =
true;
887 for (
unsigned int j = 0; j <= this->degree; j++)
888 if (points[j] != points_gl.
point(j)(0))
890 gauss_lobatto =
false;
894 if (gauss_lobatto ==
true)
897 << this->degree <<
")";
898 return namebuf.str();
902 const QGauss<1> points_g(this->degree + 1);
904 for (
unsigned int j = 0; j <= this->degree; j++)
905 if (points[j] != points_g.
point(j)(0))
914 <<
">(QGauss(" << this->degree + 1 <<
"))";
915 return namebuf.str();
920 bool gauss_log =
true;
921 for (
unsigned int j = 0; j <= this->degree; j++)
922 if (points[j] != points_glog.
point(j)(0))
928 if (gauss_log ==
true)
931 <<
">(QGaussLog(" << this->degree + 1 <<
"))";
932 return namebuf.str();
937 <<
">(QUnknownNodes(" << this->degree + 1 <<
"))";
938 return namebuf.str();
943 template <
int dim,
int spacedim>
948 std::vector<double> & nodal_values)
const 951 this->get_unit_support_points().size());
955 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
959 nodal_values[i] = support_point_values[i](0);
965 template <
int dim,
int spacedim>
966 std::unique_ptr<FiniteElement<dim, spacedim>>
970 std::vector<Point<1>> qpoints(this->degree + 1);
971 std::vector<unsigned int> lexicographic =
972 this->poly_space.get_numbering_inverse();
973 for (
unsigned int i = 0; i <= this->degree; ++i)
974 qpoints[i] =
Point<1>(this->unit_support_points[lexicographic[i]][0]);
977 return std_cxx14::make_unique<FE_DGQArbitraryNodes<dim, spacedim>>(
985 template <
int dim,
int spacedim>
988 Polynomials::Legendre::generate_complete_basis(degree))
993 template <
int dim,
int spacedim>
994 std::pair<Table<2, bool>, std::vector<unsigned int>>
1000 constant_modes(0, 0) =
true;
1001 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
1002 constant_modes, std::vector<unsigned int>(1, 0));
1007 template <
int dim,
int spacedim>
1017 template <
int dim,
int spacedim>
1018 std::unique_ptr<FiniteElement<dim, spacedim>>
1021 return std_cxx14::make_unique<FE_DGQLegendre<dim, spacedim>>(this->degree);
1028 template <
int dim,
int spacedim>
1031 Polynomials::HermiteLikeInterpolation::generate_complete_basis(degree))
1036 template <
int dim,
int spacedim>
1046 template <
int dim,
int spacedim>
1047 std::unique_ptr<FiniteElement<dim, spacedim>>
1050 return std_cxx14::make_unique<FE_DGQHermite<dim, spacedim>>(this->degree);
1056 #include "fe_dgq.inst" 1059 DEAL_II_NAMESPACE_CLOSE
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const override
static ::ExceptionBase & ExcFEHasNoSupportPoints()
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
std::vector< std::vector< FullMatrix< double > > > restriction
#define AssertDimension(dim1, dim2)
virtual bool hp_constraints_are_implemented() const override
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
FE_DGQLegendre(const unsigned int degree)
const unsigned int degree
virtual std::string get_name() const override
const Point< dim > & point(const unsigned int i) const
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const override
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
std::vector< Point< dim > > unit_support_points
virtual FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim=0) const override final
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
virtual std::size_t memory_consumption() const override
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
virtual std::string get_name() const override
std::vector< std::vector< FullMatrix< double > > > prolongation
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const override
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
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
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const override
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
void rotate_indices(std::vector< unsigned int > &indices, const char direction) const
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
std::string dim_string(const int dim, const int spacedim)
SymmetricTensor< rank, dim, Number > sum(const SymmetricTensor< rank, dim, Number > &local, const MPI_Comm &mpi_communicator)
unsigned int size() const
const unsigned int dofs_per_cell
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
FE_DGQArbitraryNodes(const Quadrature< 1 > &points)
void mmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const override
FE_DGQHermite(const unsigned int degree)
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
void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false, const bool isotropic_prolongation_only=false)
virtual std::string get_name() const override
virtual std::string get_name() const override
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const override
static ::ExceptionBase & ExcNotImplemented()
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
double compute_value(const unsigned int i, const Point< dim > &p) const
TensorProductPolynomials< dim > poly_space
void fill(InputIterator entries, const bool C_style_indexing=true)
static ::ExceptionBase & ExcInternalError()