Reference documentation for deal.II version 9.1.0-pre
fe_trace.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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/config.h>
17 
18 #include <deal.II/base/qprojector.h>
19 #include <deal.II/base/quadrature_lib.h>
20 #include <deal.II/base/std_cxx14/memory.h>
21 #include <deal.II/base/tensor_product_polynomials.h>
22 
23 #include <deal.II/fe/fe_nothing.h>
24 #include <deal.II/fe/fe_poly_face.h>
25 #include <deal.II/fe/fe_q.h>
26 #include <deal.II/fe/fe_tools.h>
27 #include <deal.II/fe/fe_trace.h>
28 
29 #include <fstream>
30 #include <iostream>
31 #include <sstream>
32 
33 DEAL_II_NAMESPACE_OPEN
34 
35 
36 
37 template <int dim, int spacedim>
38 FE_TraceQ<dim, spacedim>::FE_TraceQ(const unsigned int degree)
39  : FE_PolyFace<TensorProductPolynomials<dim - 1>, dim, spacedim>(
40  TensorProductPolynomials<dim - 1>(
41  Polynomials::generate_complete_Lagrange_basis(
42  QGaussLobatto<1>(degree + 1).get_points())),
43  FiniteElementData<dim>(get_dpo_vector(degree),
44  1,
45  degree,
46  FiniteElementData<dim>::L2),
47  std::vector<bool>(1, true))
48  , fe_q(degree)
49 {
50  Assert(degree > 0,
51  ExcMessage("FE_Trace can only be used for polynomial degrees "
52  "greater than zero"));
53  std::vector<unsigned int> renumber(this->dofs_per_face);
55  this->poly_space.set_numbering(renumber);
56 
57  // Initialize face support points
58  this->unit_face_support_points = fe_q.get_unit_face_support_points();
59 
60  // initialize unit support points (this makes it possible to assign initial
61  // values to FE_TraceQ). Note that we simply take the points of fe_q but
62  // skip the last ones which are associated with the interior of FE_Q.
63  this->unit_support_points.resize(this->dofs_per_cell);
64  for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
65  this->unit_support_points[i] = fe_q.get_unit_support_points()[i];
66 
67  // Initialize constraint matrices
68  this->interface_constraints = fe_q.constraints();
69 }
70 
71 
72 
73 template <int dim, int spacedim>
74 std::unique_ptr<FiniteElement<dim, spacedim>>
76 {
77  return std_cxx14::make_unique<FE_TraceQ<dim, spacedim>>(this->degree);
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  namebuf << "FE_TraceQ<" << Utilities::dim_string(dim, spacedim) << ">("
92  << this->degree << ")";
93 
94  return namebuf.str();
95 }
96 
97 
98 
99 template <int dim, int spacedim>
100 bool
102  const unsigned int shape_index,
103  const unsigned int face_index) const
104 {
105  Assert(shape_index < this->dofs_per_cell,
106  ExcIndexRange(shape_index, 0, this->dofs_per_cell));
109 
110  // FE_TraceQ shares the numbering of elemental degrees of freedom with FE_Q
111  // except for the missing interior ones (quad dofs in 2D and hex dofs in
112  // 3D). Therefore, it is safe to ask fe_q for the corresponding
113  // information. The assertion 'shape_index < this->dofs_per_cell' will make
114  // sure that we only access the trace dofs.
115  return fe_q.has_support_on_face(shape_index, face_index);
116 }
117 
118 
119 
120 template <int dim, int spacedim>
121 std::pair<Table<2, bool>, std::vector<unsigned int>>
123 {
124  Table<2, bool> constant_modes(1, this->dofs_per_cell);
125  for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
126  constant_modes(0, i) = true;
127  return std::pair<Table<2, bool>, std::vector<unsigned int>>(
128  constant_modes, std::vector<unsigned int>(1, 0));
129 }
130 
131 template <int dim, int spacedim>
132 void
135  const std::vector<Vector<double>> &support_point_values,
136  std::vector<double> & nodal_values) const
137 {
138  AssertDimension(support_point_values.size(),
139  this->get_unit_support_points().size());
140  AssertDimension(support_point_values.size(), nodal_values.size());
141  AssertDimension(this->dofs_per_cell, nodal_values.size());
142 
143  for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
144  {
145  AssertDimension(support_point_values[i].size(), 1);
146 
147  nodal_values[i] = support_point_values[i](0);
148  }
149 }
150 
151 
152 template <int dim, int spacedim>
153 std::vector<unsigned int>
155 {
156  // This constructs FE_TraceQ in exactly the same way as FE_Q except for the
157  // interior degrees of freedom that are not present here (line in 1D, quad
158  // in 2D, hex in 3D).
159  AssertThrow(deg > 0, ExcMessage("FE_TraceQ needs to be of degree > 0."));
160  std::vector<unsigned int> dpo(dim + 1, 1U);
161  dpo[dim] = 0;
162  dpo[0] = 1;
163  for (unsigned int i = 1; i < dim; ++i)
164  dpo[i] = dpo[i - 1] * (deg - 1);
165  return dpo;
166 }
167 
168 
169 
170 template <int dim, int spacedim>
171 bool
173 {
174  return fe_q.hp_constraints_are_implemented();
175 }
176 
177 
178 template <int dim, int spacedim>
181  const FiniteElement<dim, spacedim> &fe_other) const
182 {
183  if (const FE_TraceQ<dim, spacedim> *fe_q_other =
184  dynamic_cast<const FE_TraceQ<dim, spacedim> *>(&fe_other))
185  {
186  if (this->degree < fe_q_other->degree)
188  else if (this->degree == fe_q_other->degree)
190  else
192  }
193  else if (const FE_Nothing<dim> *fe_nothing =
194  dynamic_cast<const FE_Nothing<dim> *>(&fe_other))
195  {
196  if (fe_nothing->is_dominating())
197  {
199  }
200  else
201  {
202  // the FE_Nothing has no degrees of freedom and it is typically used
203  // in a context where we don't require any continuity along the
204  // interface
206  }
207  }
208 
209  Assert(false, ExcNotImplemented());
211 }
212 
213 
214 
215 template <int dim, int spacedim>
216 void
218  const FiniteElement<dim, spacedim> &source_fe,
219  FullMatrix<double> & interpolation_matrix) const
220 {
223  interpolation_matrix);
224 }
225 
226 
227 
228 template <int dim, int spacedim>
229 void
231  const FiniteElement<dim, spacedim> &x_source_fe,
232  const unsigned int subface,
233  FullMatrix<double> & interpolation_matrix) const
234 {
235  // this is the code from FE_FaceQ
236  Assert(interpolation_matrix.n() == this->dofs_per_face,
237  ExcDimensionMismatch(interpolation_matrix.n(), this->dofs_per_face));
238  Assert(interpolation_matrix.m() == x_source_fe.dofs_per_face,
239  ExcDimensionMismatch(interpolation_matrix.m(),
240  x_source_fe.dofs_per_face));
241 
242  // see if source is a FaceQ element
243  if (const FE_TraceQ<dim, spacedim> *source_fe =
244  dynamic_cast<const FE_TraceQ<dim, spacedim> *>(&x_source_fe))
245  {
246  fe_q.get_subface_interpolation_matrix(source_fe->fe_q,
247  subface,
248  interpolation_matrix);
249  }
250  else if (dynamic_cast<const FE_Nothing<dim> *>(&x_source_fe) != nullptr)
251  {
252  // nothing to do here, the FE_Nothing has no degrees of freedom anyway
253  }
254  else
255  AssertThrow(
256  false,
257  (typename FiniteElement<dim,
258  spacedim>::ExcInterpolationNotImplemented()));
259 }
260 
261 
262 
263 template <int spacedim>
265  : FE_FaceQ<1, spacedim>(degree)
266 {}
267 
268 
269 
270 template <int spacedim>
271 std::string
273 {
274  // note that the FETools::get_fe_by_name function depends on the
275  // particular format of the string this function returns, so they have to be
276  // kept in synch
277  std::ostringstream namebuf;
278  namebuf << "FE_TraceQ<" << Utilities::dim_string(1, spacedim) << ">("
279  << this->degree << ")";
280 
281  return namebuf.str();
282 }
283 
284 
285 
286 // explicit instantiations
287 #include "fe_trace.inst"
288 
289 
290 DEAL_II_NAMESPACE_CLOSE
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const override
Definition: fe_trace.cc:122
static const unsigned int invalid_unsigned_int
Definition: types.h:173
const std::vector< Point< dim > > & get_unit_support_points() const
Definition: fe.cc:1000
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1366
FullMatrix< double > interface_constraints
Definition: fe.h:2445
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
Definition: fe_trace.cc:101
FE_TraceQ(unsigned int p)
Definition: fe_trace.cc:38
void hierarchic_to_lexicographic_numbering(unsigned int degree, std::vector< unsigned int > &h2l)
const unsigned int degree
Definition: fe_base.h:313
void set_numbering(const std::vector< unsigned int > &renumber)
std::vector< Point< dim-1 > > unit_face_support_points
Definition: fe.h:2464
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
static::ExceptionBase & ExcInterpolationNotImplemented()
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
std::vector< Point< dim > > unit_support_points
Definition: fe.h:2457
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const override
Definition: fe_trace.cc:217
static::ExceptionBase & ExcMessage(std::string arg1)
size_type n() const
#define Assert(cond, exc)
Definition: exceptions.h:1227
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
FE_Q< dim, spacedim > fe_q
Definition: fe_trace.h:144
size_type m() 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 override
Definition: fe_trace.cc:134
std::string dim_string(const int dim, const int spacedim)
Definition: utilities.cc:170
const unsigned int dofs_per_cell
Definition: fe_base.h:297
virtual bool hp_constraints_are_implemented() const override
Definition: fe_trace.cc:172
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
Definition: fe_trace.cc:75
const unsigned int dofs_per_face
Definition: fe_base.h:290
static::ExceptionBase & ExcNotImplemented()
static std::vector< unsigned int > get_dpo_vector(const unsigned int deg)
Definition: fe_trace.cc:154
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim, spacedim > &fe_other) const override
Definition: fe_trace.cc:180
Definition: table.h:37
virtual std::string get_name() const override
Definition: fe_trace.cc:84
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const override
Definition: fe_trace.cc:230