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