Reference documentation for deal.II version 9.0.0
fe_q.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2017 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/quadrature_lib.h>
18 #include <deal.II/lac/vector.h>
19 #include <deal.II/fe/fe_q.h>
20 
21 #include <vector>
22 #include <sstream>
23 #include <deal.II/base/std_cxx14/memory.h>
24 
25 DEAL_II_NAMESPACE_OPEN
26 
27 
28 namespace internal
29 {
30  namespace FE_Q
31  {
32  namespace
33  {
34  std::vector<Point<1> >
35  get_QGaussLobatto_points (const unsigned int degree)
36  {
37  if (degree > 0)
38  return QGaussLobatto<1>(degree+1).get_points();
39  else
40  {
41  typedef ::FE_Q_Base<TensorProductPolynomials<1>, 1, 1> FEQ;
42  AssertThrow(false, FEQ::ExcFEQCannotHaveDegree0());
43  }
44  return std::vector<Point<1> >();
45  }
46  }
47  }
48 }
49 
50 
51 
52 template <int dim, int spacedim>
53 FE_Q<dim,spacedim>::FE_Q (const unsigned int degree)
54  :
55  FE_Q_Base<TensorProductPolynomials<dim>, dim, spacedim>
56  (TensorProductPolynomials<dim>(Polynomials::generate_complete_Lagrange_basis(internal::FE_Q::get_QGaussLobatto_points(degree))),
57  FiniteElementData<dim>(this->get_dpo_vector(degree),
58  1, degree,
59  FiniteElementData<dim>::H1),
60  std::vector<bool> (1, false))
61 {
62  this->initialize(internal::FE_Q::get_QGaussLobatto_points(degree));
63 }
64 
65 
66 
67 template <int dim, int spacedim>
69  :
70  FE_Q_Base<TensorProductPolynomials<dim>, dim, spacedim> (
71  TensorProductPolynomials<dim>(Polynomials::generate_complete_Lagrange_basis(points.get_points())),
72  FiniteElementData<dim>(this->get_dpo_vector(points.size()-1),
73  1, points.size()-1,
74  FiniteElementData<dim>::H1),
75  std::vector<bool> (1, false))
76 {
77  this->initialize(points.get_points());
78 }
79 
80 
81 
82 template <int dim, int spacedim>
83 std::string
85 {
86  // note that the FETools::get_fe_by_name function depends on the
87  // particular format of the string this function returns, so they have to be
88  // kept in synch
89 
90  std::ostringstream namebuf;
91  bool equidistant = true;
92  std::vector<double> points(this->degree+1);
93 
94  // Decode the support points in one coordinate direction.
95  std::vector<unsigned int> lexicographic = this->poly_space.get_numbering_inverse();
96  for (unsigned int j=0; j<=this->degree; j++)
97  points[j] = this->unit_support_points[lexicographic[j]][0];
98 
99  // Check whether the support points are equidistant.
100  for (unsigned int j=0; j<=this->degree; j++)
101  if (std::fabs(points[j] - (double)j/this->degree) > 1e-15)
102  {
103  equidistant = false;
104  break;
105  }
106 
107  if (equidistant == true)
108  {
109  if (this->degree > 2)
110  namebuf << "FE_Q<"
111  << Utilities::dim_string(dim,spacedim)
112  << ">(QIterated(QTrapez()," << this->degree << "))";
113  else
114  namebuf << "FE_Q<"
115  << Utilities::dim_string(dim,spacedim)
116  << ">(" << this->degree << ")";
117  }
118  else
119  {
120  // Check whether the support points come from QGaussLobatto.
121  const QGaussLobatto<1> points_gl(this->degree+1);
122  bool gauss_lobatto = true;
123  for (unsigned int j=0; j<=this->degree; j++)
124  if (points[j] != points_gl.point(j)(0))
125  {
126  gauss_lobatto = false;
127  break;
128  }
129  if (gauss_lobatto == true)
130  namebuf << "FE_Q<"
131  << Utilities::dim_string(dim,spacedim)
132  << ">(" << this->degree << ")";
133  else
134  namebuf << "FE_Q<"
135  << Utilities::dim_string(dim,spacedim)
136  << ">(QUnknownNodes(" << this->degree << "))";
137  }
138  return namebuf.str();
139 }
140 
141 
142 
143 template <int dim, int spacedim>
144 void
147  std::vector<double> &nodal_values) const
148 {
149  AssertDimension (support_point_values.size(),
150  this->get_unit_support_points().size());
151  AssertDimension (support_point_values.size(),
152  nodal_values.size());
153  AssertDimension (this->dofs_per_cell,
154  nodal_values.size());
155 
156  for (unsigned int i=0; i<this->dofs_per_cell; ++i)
157  {
158  AssertDimension (support_point_values[i].size(), 1);
159 
160  nodal_values[i] = support_point_values[i](0);
161  }
162 }
163 
164 
165 
166 template <int dim, int spacedim>
167 std::unique_ptr<FiniteElement<dim,spacedim> >
169 {
170  return std_cxx14::make_unique<FE_Q<dim,spacedim>>(*this);
171 }
172 
173 
174 // explicit instantiations
175 #include "fe_q.inst"
176 
177 DEAL_II_NAMESPACE_CLOSE
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const
Definition: fe_q.cc:146
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1248
FE_Q(const unsigned int p)
Definition: fe_q.cc:53
const std::vector< Point< dim > > & get_points() const
const unsigned int degree
Definition: fe_base.h:311
const Point< dim > & point(const unsigned int i) const
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
Definition: fe_q.h:552
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const
Definition: fe_q.cc:168
std::string dim_string(const int dim, const int spacedim)
Definition: utilities.cc:176
virtual std::string get_name() const
Definition: fe_q.cc:84
void initialize(const std::vector< Point< 1 > > &support_points_1d)
Definition: fe_q_base.cc:434