Reference documentation for deal.II version 8.5.1
fe_dgp_monomial.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 2016 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/fe/fe_dgp_monomial.h>
18 #include <deal.II/fe/fe_tools.h>
19 
20 #include <sstream>
21 
22 DEAL_II_NAMESPACE_OPEN
23 
24 // namespace for some functions that are used in this file.
25 namespace
26 {
27  // storage of hand-chosen support
28  // points
29  //
30  // For dim=2, dofs_per_cell of
31  // FE_DGPMonomial(k) is given by
32  // 0.5(k+1)(k+2), i.e.
33  //
34  // k 0 1 2 3 4 5 6 7
35  // dofs 1 3 6 10 15 21 28 36
36  //
37  // indirect access of unit points:
38  // the points for degree k are
39  // located at
40  //
41  // points[start_index[k]..start_index[k+1]-1]
42  const unsigned int start_index2d[6]= {0,1,4,10,20,35};
43  const double points2d[35][2]=
44  {
45  {0,0},
46  {0,0},{1,0},{0,1},
47  {0,0},{1,0},{0,1},{1,1},{0.5,0},{0,0.5},
48  {0,0},{1,0},{0,1},{1,1},{1./3.,0},{2./3.,0},{0,1./3.},{0,2./3.},{0.5,1},{1,0.5},
49  {0,0},{1,0},{0,1},{1,1},{0.25,0},{0.5,0},{0.75,0},{0,0.25},{0,0.5},{0,0.75},{1./3.,1},{2./3.,1},{1,1./3.},{1,2./3.},{0.5,0.5}
50  };
51 
52  // For dim=3, dofs_per_cell of
53  // FE_DGPMonomial(k) is given by
54  // 1./6.(k+1)(k+2)(k+3), i.e.
55  //
56  // k 0 1 2 3 4 5 6 7
57  // dofs 1 4 10 20 35 56 84 120
58  const unsigned int start_index3d[6]= {0,1,5,15/*,35*/};
59  const double points3d[35][3]=
60  {
61  {0,0,0},
62  {0,0,0},{1,0,0},{0,1,0},{0,0,1},
63  {0,0,0},{1,0,0},{0,1,0},{0,0,1},{0.5,0,0},{0,0.5,0},{0,0,0.5},{1,1,0},{1,0,1},{0,1,1}
64  };
65 
66 
67  template<int dim>
68  void generate_unit_points (const unsigned int,
69  std::vector<Point<dim> > &);
70 
71  template <>
72  void generate_unit_points (const unsigned int k,
73  std::vector<Point<1> > &p)
74  {
75  Assert(p.size()==k+1, ExcDimensionMismatch(p.size(), k+1));
76  const double h = 1./k;
77  for (unsigned int i=0; i<p.size(); ++i)
78  p[i](0)=i*h;
79  }
80 
81  template <>
82  void generate_unit_points (const unsigned int k,
83  std::vector<Point<2> > &p)
84  {
85  Assert(k<=4, ExcNotImplemented());
86  Assert(p.size()==start_index2d[k+1]-start_index2d[k], ExcInternalError());
87  for (unsigned int i=0; i<p.size(); ++i)
88  {
89  p[i](0)=points2d[start_index2d[k]+i][0];
90  p[i](1)=points2d[start_index2d[k]+i][1];
91  }
92  }
93 
94  template <>
95  void generate_unit_points (const unsigned int k,
96  std::vector<Point<3> > &p)
97  {
98  Assert(k<=2, ExcNotImplemented());
99  Assert(p.size()==start_index3d[k+1]-start_index3d[k], ExcInternalError());
100  for (unsigned int i=0; i<p.size(); ++i)
101  {
102  p[i](0)=points3d[start_index3d[k]+i][0];
103  p[i](1)=points3d[start_index3d[k]+i][1];
104  p[i](2)=points3d[start_index3d[k]+i][2];
105  }
106  }
107 }
108 
109 
110 
111 template <int dim>
112 FE_DGPMonomial<dim>::FE_DGPMonomial (const unsigned int degree)
113  :
114  FE_Poly<PolynomialsP<dim>, dim> (
115  PolynomialsP<dim>(degree),
116  FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
117  std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
118  std::vector<ComponentMask>(FiniteElementData<dim>(
119  get_dpo_vector(degree), 1, degree).dofs_per_cell, std::vector<bool>(1,true)))
120 {
121  Assert(this->poly_space.n()==this->dofs_per_cell, ExcInternalError());
122  Assert(this->poly_space.degree()==this->degree, ExcInternalError());
123 
124  // DG doesn't have constraints, so
125  // leave them empty
126 
127  // Reinit the vectors of
128  // restriction and prolongation
129  // matrices to the right sizes
131  // Fill prolongation matrices with embedding operators
133  // Fill restriction matrices with L2-projection
135 }
136 
137 
138 
139 template <int dim>
140 std::string
142 {
143  // note that the
144  // FETools::get_fe_by_name
145  // function depends on the
146  // particular format of the string
147  // this function returns, so they
148  // have to be kept in synch
149 
150  std::ostringstream namebuf;
151  namebuf << "FE_DGPMonomial<" << dim << ">(" << this->degree << ")";
152 
153  return namebuf.str();
154 }
155 
156 
157 
158 template <int dim>
161 {
162  return new FE_DGPMonomial<dim>(*this);
163 }
164 
165 
166 
167 //TODO: Remove this function and use the one in FETools, if needed
168 template <int dim>
169 void
172  FullMatrix<double> &interpolation_matrix) const
173 {
174  const FE_DGPMonomial<dim> *source_dgp_monomial
175  = dynamic_cast<const FE_DGPMonomial<dim> *>(&source_fe);
176 
177  if (source_dgp_monomial)
178  {
179  // ok, source_fe is a DGP_Monomial
180  // element. Then, the interpolation
181  // matrix is simple
182  const unsigned int m=interpolation_matrix.m();
183  const unsigned int n=interpolation_matrix.n();
184  (void)m;
185  (void)n;
186  Assert (m == this->dofs_per_cell, ExcDimensionMismatch (m, this->dofs_per_cell));
187  Assert (n == source_dgp_monomial->dofs_per_cell,
188  ExcDimensionMismatch (n, source_dgp_monomial->dofs_per_cell));
189 
190  const unsigned int min_mn=
191  interpolation_matrix.m()<interpolation_matrix.n() ?
192  interpolation_matrix.m() : interpolation_matrix.n();
193 
194  for (unsigned int i=0; i<min_mn; ++i)
195  interpolation_matrix(i,i)=1.;
196  }
197  else
198  {
199  std::vector<Point<dim> > unit_points(this->dofs_per_cell);
200  generate_unit_points(this->degree, unit_points);
201 
202  FullMatrix<double> source_fe_matrix(unit_points.size(), source_fe.dofs_per_cell);
203  for (unsigned int j=0; j<source_fe.dofs_per_cell; ++j)
204  for (unsigned int k=0; k<unit_points.size(); ++k)
205  source_fe_matrix(k,j)=source_fe.shape_value(j, unit_points[k]);
206 
207  FullMatrix<double> this_matrix(this->dofs_per_cell, this->dofs_per_cell);
208  for (unsigned int j=0; j<this->dofs_per_cell; ++j)
209  for (unsigned int k=0; k<unit_points.size(); ++k)
210  this_matrix(k,j)=this->poly_space.compute_value (j, unit_points[k]);
211 
212  this_matrix.gauss_jordan();
213 
214  this_matrix.mmult(interpolation_matrix, source_fe_matrix);
215  }
216 }
217 
218 
219 
220 template <int dim>
221 void
223 {
224  Assert(false, ExcNotImplemented());
225 }
226 
227 
228 //---------------------------------------------------------------------------
229 // Auxiliary functions
230 //---------------------------------------------------------------------------
231 
232 
233 template <int dim>
234 std::vector<unsigned int>
235 FE_DGPMonomial<dim>::get_dpo_vector (const unsigned int deg)
236 {
237  std::vector<unsigned int> dpo(dim+1, 0U);
238  dpo[dim] = deg+1;
239  for (unsigned int i=1; i<dim; ++i)
240  {
241  dpo[dim] *= deg+1+i;
242  dpo[dim] /= i+1;
243  }
244  return dpo;
245 }
246 
247 
248 template <int dim>
249 void
252  FullMatrix<double> &interpolation_matrix) const
253 {
254  // this is only implemented, if the source
255  // FE is also a DGPMonomial element. in that case,
256  // both elements have no dofs on their
257  // faces and the face interpolation matrix
258  // is necessarily empty -- i.e. there isn't
259  // much we need to do here.
260  (void)interpolation_matrix;
261  AssertThrow ((x_source_fe.get_name().find ("FE_DGPMonomial<") == 0)
262  ||
263  (dynamic_cast<const FE_DGPMonomial<dim>*>(&x_source_fe) != 0),
264  typename FiniteElement<dim>::
265  ExcInterpolationNotImplemented());
266 
267  Assert (interpolation_matrix.m() == 0,
268  ExcDimensionMismatch (interpolation_matrix.m(),
269  0));
270  Assert (interpolation_matrix.n() == 0,
271  ExcDimensionMismatch (interpolation_matrix.n(),
272  0));
273 }
274 
275 
276 
277 template <int dim>
278 void
281  const unsigned int ,
282  FullMatrix<double> &interpolation_matrix) const
283 {
284  // this is only implemented, if the source
285  // FE is also a DGPMonomial element. in that case,
286  // both elements have no dofs on their
287  // faces and the face interpolation matrix
288  // is necessarily empty -- i.e. there isn't
289  // much we need to do here.
290  (void)interpolation_matrix;
291  AssertThrow ((x_source_fe.get_name().find ("FE_DGPMonomial<") == 0)
292  ||
293  (dynamic_cast<const FE_DGPMonomial<dim>*>(&x_source_fe) != 0),
294  typename FiniteElement<dim>::
295  ExcInterpolationNotImplemented());
296 
297  Assert (interpolation_matrix.m() == 0,
298  ExcDimensionMismatch (interpolation_matrix.m(),
299  0));
300  Assert (interpolation_matrix.n() == 0,
301  ExcDimensionMismatch (interpolation_matrix.n(),
302  0));
303 }
304 
305 
306 
307 template <int dim>
308 bool
310 {
311  return true;
312 }
313 
314 
315 
316 template <int dim>
317 std::vector<std::pair<unsigned int, unsigned int> >
320 {
321  // there are no such constraints for DGPMonomial
322  // elements at all
323  if (dynamic_cast<const FE_DGPMonomial<dim>*>(&fe_other) != 0)
324  return
325  std::vector<std::pair<unsigned int, unsigned int> > ();
326  else
327  {
328  Assert (false, ExcNotImplemented());
329  return std::vector<std::pair<unsigned int, unsigned int> > ();
330  }
331 }
332 
333 
334 
335 template <int dim>
336 std::vector<std::pair<unsigned int, unsigned int> >
339 {
340  // there are no such constraints for DGPMonomial
341  // elements at all
342  if (dynamic_cast<const FE_DGPMonomial<dim>*>(&fe_other) != 0)
343  return
344  std::vector<std::pair<unsigned int, unsigned int> > ();
345  else
346  {
347  Assert (false, ExcNotImplemented());
348  return std::vector<std::pair<unsigned int, unsigned int> > ();
349  }
350 }
351 
352 
353 
354 template <int dim>
355 std::vector<std::pair<unsigned int, unsigned int> >
358 {
359  // there are no such constraints for DGPMonomial
360  // elements at all
361  if (dynamic_cast<const FE_DGPMonomial<dim>*>(&fe_other) != 0)
362  return
363  std::vector<std::pair<unsigned int, unsigned int> > ();
364  else
365  {
366  Assert (false, ExcNotImplemented());
367  return std::vector<std::pair<unsigned int, unsigned int> > ();
368  }
369 }
370 
371 
372 
373 template <int dim>
377 {
378  // check whether both are discontinuous
379  // elements, see
380  // the description of
381  // FiniteElementDomination::Domination
382  if (dynamic_cast<const FE_DGPMonomial<dim>*>(&fe_other) != 0)
384 
385  Assert (false, ExcNotImplemented());
387 }
388 
389 
390 
391 template <>
392 bool
394  const unsigned int face_index) const
395 {
396  return face_index==1 || (face_index==0 && this->degree==0);
397 }
398 
399 
400 
401 template <>
402 bool
403 FE_DGPMonomial<2>::has_support_on_face (const unsigned int shape_index,
404  const unsigned int face_index) const
405 {
406  bool support_on_face=false;
407  if (face_index==1 || face_index==2)
408  support_on_face=true;
409  else
410  {
411  unsigned int degrees[2];
412  this->poly_space.directional_degrees(shape_index, degrees);
413  if ((face_index==0 && degrees[1]==0) ||
414  (face_index==3 && degrees[0]==0))
415  support_on_face=true;
416  }
417  return support_on_face;
418 }
419 
420 
421 
422 template <>
423 bool
424 FE_DGPMonomial<3>::has_support_on_face (const unsigned int shape_index,
425  const unsigned int face_index) const
426 {
427  bool support_on_face=false;
428  if (face_index==1 || face_index==3 || face_index==4)
429  support_on_face=true;
430  else
431  {
432  unsigned int degrees[3];
433  this->poly_space.directional_degrees(shape_index, degrees);
434  if ((face_index==0 && degrees[1]==0) ||
435  (face_index==2 && degrees[2]==0) ||
436  (face_index==5 && degrees[0]==0))
437  support_on_face=true;
438  }
439  return support_on_face;
440 }
441 
442 
443 
444 template <int dim>
445 std::size_t
447 {
448  Assert (false, ExcNotImplemented ());
449  return 0;
450 }
451 
452 
453 
454 // explicit instantiations
455 #include "fe_dgp_monomial.inst"
456 
457 
458 DEAL_II_NAMESPACE_CLOSE
size_type m() const
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
std::vector< std::vector< FullMatrix< double > > > restriction
Definition: fe.h:2185
virtual void get_subface_interpolation_matrix(const FiniteElement< dim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
FE_DGPMonomial(const unsigned int p)
virtual void get_face_interpolation_matrix(const FiniteElement< dim > &source, FullMatrix< double > &matrix) const
void gauss_jordan()
virtual FiniteElement< dim > * clone() const
const unsigned int degree
Definition: fe_base.h:311
STL namespace.
void compute_embedding_matrices(const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number > > > &matrices, const bool isotropic_only=false, const double threshold=1.e-12)
Definition: fe_tools.cc:1897
#define AssertThrow(cond, exc)
Definition: exceptions.h:369
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim > &fe_other) const
virtual bool hp_constraints_are_implemented() const
void initialize_restriction()
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim > &fe_other) const
size_type n() const
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim > &fe_other) const
std::vector< std::vector< FullMatrix< double > > > prolongation
Definition: fe.h:2199
virtual void get_interpolation_matrix(const FiniteElement< dim > &source, FullMatrix< double > &matrix) const
#define Assert(cond, exc)
Definition: exceptions.h:313
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
virtual std::string get_name() const =0
const unsigned int dofs_per_cell
Definition: fe_base.h:295
void mmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:163
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim > &fe_other) const
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
virtual std::size_t memory_consumption() const
void compute_projection_matrices(const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number > > > &matrices, const bool isotropic_only=false)
Definition: fe_tools.cc:2123
void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false, const bool isotropic_prolongation_only=false)
Definition: fe.cc:277
static ::ExceptionBase & ExcNotImplemented()
virtual std::string get_name() const
PolynomialsP< dim > poly_space
Definition: fe_poly.h:444
static ::ExceptionBase & ExcInternalError()