Reference documentation for deal.II version 8.5.1
fe_dgq.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2001 - 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.h>
18 #include <deal.II/base/quadrature_lib.h>
19 #include <deal.II/fe/fe.h>
20 #include <deal.II/fe/fe_dgq.h>
21 #include <deal.II/fe/fe_tools.h>
22 
23 
24 #include <iostream>
25 #include <sstream>
26 
27 DEAL_II_NAMESPACE_OPEN
28 
29 
30 namespace
31 {
32  std::vector<Point<1> >
33  get_QGaussLobatto_points (const unsigned int degree)
34  {
35  if (degree > 0)
36  return QGaussLobatto<1>(degree+1).get_points();
37  else
38  return std::vector<Point<1> >(1, Point<1>(0.5));
39  }
40 }
41 
42 
43 
44 template <int dim, int spacedim>
45 FE_DGQ<dim, spacedim>::FE_DGQ (const unsigned int degree)
46  :
47  FE_Poly<TensorProductPolynomials<dim>, dim, spacedim>
48  (TensorProductPolynomials<dim>(Polynomials::generate_complete_Lagrange_basis(get_QGaussLobatto_points(degree))),
49  FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
50  std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell, true),
51  std::vector<ComponentMask>(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell, std::vector<bool>(1,true)))
52 {
53  // Compute support points, which are the tensor product of the Lagrange
54  // interpolation points in the constructor.
55  Quadrature<dim> support_quadrature(get_QGaussLobatto_points(degree));
56  Assert (support_quadrature.get_points().size() > 0,
58  this->unit_support_points = support_quadrature.get_points();
59 
60  // do not initialize embedding and restriction here. these matrices are
61  // initialized on demand in get_restriction_matrix and
62  // get_prolongation_matrix
63 
64  // note: no face support points for DG elements
65 }
66 
67 
68 
69 template <int dim, int spacedim>
71  :
72  FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
73  TensorProductPolynomials<dim>(polynomials),
74  FiniteElementData<dim>(get_dpo_vector(polynomials.size()-1), 1, polynomials.size()-1, FiniteElementData<dim>::L2),
75  std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(polynomials.size()-1),1, polynomials.size()-1).dofs_per_cell, true),
76  std::vector<ComponentMask>(FiniteElementData<dim>(get_dpo_vector(polynomials.size()-1),1, polynomials.size()-1).dofs_per_cell, std::vector<bool>(1,true)))
77 {
78  // No support points can be defined in general. Derived classes might define
79  // support points like the class FE_DGQArbitraryNodes
80 
81  // do not initialize embedding and restriction here. these matrices are
82  // initialized on demand in get_restriction_matrix and
83  // get_prolongation_matrix
84 }
85 
86 
87 
88 template <int dim, int spacedim>
89 std::string
91 {
92  // note that the FETools::get_fe_by_name function depends on the
93  // particular format of the string this function returns, so they have to be
94  // kept in sync
95 
96  std::ostringstream namebuf;
97  namebuf << "FE_DGQ<"
98  << Utilities::dim_string(dim,spacedim)
99  << ">(" << this->degree << ")";
100  return namebuf.str();
101 }
102 
103 
104 
105 template <int dim, int spacedim>
108 {
109  return new FE_DGQ<dim, spacedim>(*this);
110 }
111 
112 
113 //---------------------------------------------------------------------------
114 // Auxiliary functions
115 //---------------------------------------------------------------------------
116 
117 
118 template <int dim, int spacedim>
119 std::vector<unsigned int>
121 {
122  std::vector<unsigned int> dpo(dim+1, 0U);
123  dpo[dim] = deg+1;
124  for (unsigned int i=1; i<dim; ++i)
125  dpo[dim] *= deg+1;
126  return dpo;
127 }
128 
129 
130 
131 template <int dim, int spacedim>
132 void
133 FE_DGQ<dim, spacedim>::rotate_indices (std::vector<unsigned int> &numbers,
134  const char direction) const
135 {
136  const unsigned int n = this->degree+1;
137  unsigned int s = n;
138  for (unsigned int i=1; i<dim; ++i)
139  s *= n;
140  numbers.resize (s);
141 
142  unsigned int l = 0;
143 
144  if (dim==1)
145  {
146  // Mirror around midpoint
147  for (unsigned int i=n; i>0;)
148  numbers[l++]=--i;
149  }
150  else
151  {
152  switch (direction)
153  {
154  // Rotate xy-plane
155  // counter-clockwise
156  case 'z':
157  for (unsigned int iz=0; iz<((dim>2) ? n:1); ++iz)
158  for (unsigned int j=0; j<n; ++j)
159  for (unsigned int i=0; i<n; ++i)
160  {
161  unsigned int k = n*i-j+n-1 + n*n*iz;
162  numbers[l++] = k;
163  }
164  break;
165  // Rotate xy-plane
166  // clockwise
167  case 'Z':
168  for (unsigned int iz=0; iz<((dim>2) ? n:1); ++iz)
169  for (unsigned int iy=0; iy<n; ++iy)
170  for (unsigned int ix=0; ix<n; ++ix)
171  {
172  unsigned int k = n*ix-iy+n-1 + n*n*iz;
173  numbers[k] = l++;
174  }
175  break;
176  // Rotate yz-plane
177  // counter-clockwise
178  case 'x':
179  Assert (dim>2, ExcDimensionMismatch (dim,3));
180  for (unsigned int iz=0; iz<n; ++iz)
181  for (unsigned int iy=0; iy<n; ++iy)
182  for (unsigned int ix=0; ix<n; ++ix)
183  {
184  unsigned int k = n*(n*iy-iz+n-1) + ix;
185  numbers[l++] = k;
186  }
187  break;
188  // Rotate yz-plane
189  // clockwise
190  case 'X':
191  Assert (dim>2, ExcDimensionMismatch (dim,3));
192  for (unsigned int iz=0; iz<n; ++iz)
193  for (unsigned int iy=0; iy<n; ++iy)
194  for (unsigned int ix=0; ix<n; ++ix)
195  {
196  unsigned int k = n*(n*iy-iz+n-1) + ix;
197  numbers[k] = l++;
198  }
199  break;
200  default:
201  Assert (false, ExcNotImplemented ());
202  }
203  }
204 }
205 
206 
207 
208 template <int dim, int spacedim>
209 void
212  FullMatrix<double> &interpolation_matrix) const
213 {
214  // this is only implemented, if the
215  // source FE is also a
216  // DGQ element
217  typedef FiniteElement<dim, spacedim> FE;
218  AssertThrow ((dynamic_cast<const FE_DGQ<dim, spacedim>*>(&x_source_fe) != 0),
219  typename FE::ExcInterpolationNotImplemented() );
220 
221  // ok, source is a Q element, so
222  // we will be able to do the work
223  const FE_DGQ<dim, spacedim> &source_fe
224  = dynamic_cast<const FE_DGQ<dim, spacedim>&>(x_source_fe);
225 
226  Assert (interpolation_matrix.m() == this->dofs_per_cell,
227  ExcDimensionMismatch (interpolation_matrix.m(),
228  this->dofs_per_cell));
229  Assert (interpolation_matrix.n() == source_fe.dofs_per_cell,
230  ExcDimensionMismatch (interpolation_matrix.n(),
231  source_fe.dofs_per_cell));
232 
233 
234  // compute the interpolation
235  // matrices in much the same way as
236  // we do for the embedding matrices
237  // from mother to child.
238  FullMatrix<double> cell_interpolation (this->dofs_per_cell,
239  this->dofs_per_cell);
240  FullMatrix<double> source_interpolation (this->dofs_per_cell,
241  source_fe.dofs_per_cell);
242  FullMatrix<double> tmp (this->dofs_per_cell,
243  source_fe.dofs_per_cell);
244  for (unsigned int j=0; j<this->dofs_per_cell; ++j)
245  {
246  // generate a point on this
247  // cell and evaluate the
248  // shape functions there
249  const Point<dim> p = this->unit_support_points[j];
250  for (unsigned int i=0; i<this->dofs_per_cell; ++i)
251  cell_interpolation(j,i)
252  = this->poly_space.compute_value (i, p);
253 
254  for (unsigned int i=0; i<source_fe.dofs_per_cell; ++i)
255  source_interpolation(j,i)
256  = source_fe.poly_space.compute_value (i, p);
257  }
258 
259  // then compute the
260  // interpolation matrix matrix
261  // for this coordinate
262  // direction
263  cell_interpolation.gauss_jordan ();
264  cell_interpolation.mmult (interpolation_matrix,
265  source_interpolation);
266 
267  // cut off very small values
268  for (unsigned int i=0; i<this->dofs_per_cell; ++i)
269  for (unsigned int j=0; j<source_fe.dofs_per_cell; ++j)
270  if (std::fabs(interpolation_matrix(i,j)) < 1e-15)
271  interpolation_matrix(i,j) = 0.;
272 
273  // make sure that the row sum of
274  // each of the matrices is 1 at
275  // this point. this must be so
276  // since the shape functions sum up
277  // to 1
278  for (unsigned int i=0; i<this->dofs_per_cell; ++i)
279  {
280  double sum = 0.;
281  for (unsigned int j=0; j<source_fe.dofs_per_cell; ++j)
282  sum += interpolation_matrix(i,j);
283 
284  Assert (std::fabs(sum-1) < 5e-14*std::max(this->degree,1U)*dim,
285  ExcInternalError());
286  }
287 }
288 
289 
290 
291 template <int dim, int spacedim>
292 void
295  FullMatrix<double> &interpolation_matrix) const
296 {
297  // this is only implemented, if the source
298  // FE is also a DGQ element. in that case,
299  // both elements have no dofs on their
300  // faces and the face interpolation matrix
301  // is necessarily empty -- i.e. there isn't
302  // much we need to do here.
303  (void)interpolation_matrix;
304  typedef FiniteElement<dim,spacedim> FE;
305  AssertThrow ((dynamic_cast<const FE_DGQ<dim, spacedim>*>(&x_source_fe) != 0),
306  typename FE::ExcInterpolationNotImplemented());
307 
308  Assert (interpolation_matrix.m() == 0,
309  ExcDimensionMismatch (interpolation_matrix.m(),
310  0));
311  Assert (interpolation_matrix.n() == 0,
312  ExcDimensionMismatch (interpolation_matrix.m(),
313  0));
314 }
315 
316 
317 
318 template <int dim, int spacedim>
319 void
322  const unsigned int ,
323  FullMatrix<double> &interpolation_matrix) const
324 {
325  // this is only implemented, if the source
326  // FE is also a DGQ element. in that case,
327  // both elements have no dofs on their
328  // faces and the face interpolation matrix
329  // is necessarily empty -- i.e. there isn't
330  // much we need to do here.
331  (void)interpolation_matrix;
332  typedef FiniteElement<dim, spacedim> FE;
333  AssertThrow ((dynamic_cast<const FE_DGQ<dim, spacedim>*>(&x_source_fe) != 0),
334  typename FE::ExcInterpolationNotImplemented());
335 
336  Assert (interpolation_matrix.m() == 0,
337  ExcDimensionMismatch (interpolation_matrix.m(),
338  0));
339  Assert (interpolation_matrix.n() == 0,
340  ExcDimensionMismatch (interpolation_matrix.m(),
341  0));
342 }
343 
344 
345 
346 template <int dim, int spacedim>
347 const FullMatrix<double> &
349 ::get_prolongation_matrix (const unsigned int child,
350  const RefinementCase<dim> &refinement_case) const
351 {
354  Assert (refinement_case!=RefinementCase<dim>::no_refinement,
355  ExcMessage("Prolongation matrices are only available for refined cells!"));
356  Assert (child<GeometryInfo<dim>::n_children(refinement_case),
357  ExcIndexRange(child,0,GeometryInfo<dim>::n_children(refinement_case)));
358 
359  // initialization upon first request
360  if (this->prolongation[refinement_case-1][child].n() == 0)
361  {
362  Threads::Mutex::ScopedLock lock(this->mutex);
363 
364  // if matrix got updated while waiting for the lock
365  if (this->prolongation[refinement_case-1][child].n() ==
366  this->dofs_per_cell)
367  return this->prolongation[refinement_case-1][child];
368 
369  // now do the work. need to get a non-const version of data in order to
370  // be able to modify them inside a const function
371  FE_DGQ<dim,spacedim> &this_nonconst = const_cast<FE_DGQ<dim,spacedim>& >(*this);
372  if (refinement_case == RefinementCase<dim>::isotropic_refinement)
373  {
374  std::vector<std::vector<FullMatrix<double> > >
375  isotropic_matrices(RefinementCase<dim>::isotropic_refinement);
376  isotropic_matrices.back().
377  resize(GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
378  FullMatrix<double>(this->dofs_per_cell, this->dofs_per_cell));
379  if (dim == spacedim)
380  FETools::compute_embedding_matrices (*this, isotropic_matrices, true);
381  else
383  isotropic_matrices, true);
384  this_nonconst.prolongation[refinement_case-1].swap(isotropic_matrices.back());
385  }
386  else
387  {
388  // must compute both restriction and prolongation matrices because
389  // we only check for their size and the reinit call initializes them
390  // all
392  if (dim == spacedim)
393  {
394  FETools::compute_embedding_matrices (*this, this_nonconst.prolongation);
395  FETools::compute_projection_matrices (*this, this_nonconst.restriction);
396  }
397  else
398  {
399  FE_DGQ<dim> tmp(this->degree);
402  }
403  }
404  }
405 
406  // finally return the matrix
407  return this->prolongation[refinement_case-1][child];
408 }
409 
410 
411 
412 template <int dim, int spacedim>
413 const FullMatrix<double> &
415 ::get_restriction_matrix (const unsigned int child,
416  const RefinementCase<dim> &refinement_case) const
417 {
420  Assert (refinement_case!=RefinementCase<dim>::no_refinement,
421  ExcMessage("Restriction matrices are only available for refined cells!"));
422  Assert (child<GeometryInfo<dim>::n_children(refinement_case),
423  ExcIndexRange(child,0,GeometryInfo<dim>::n_children(refinement_case)));
424 
425  // initialization upon first request
426  if (this->restriction[refinement_case-1][child].n() == 0)
427  {
428  Threads::Mutex::ScopedLock lock(this->mutex);
429 
430  // if matrix got updated while waiting for the lock...
431  if (this->restriction[refinement_case-1][child].n() ==
432  this->dofs_per_cell)
433  return this->restriction[refinement_case-1][child];
434 
435  // now do the work. need to get a non-const version of data in order to
436  // be able to modify them inside a const function
437  FE_DGQ<dim,spacedim> &this_nonconst = const_cast<FE_DGQ<dim,spacedim>& >(*this);
438  if (refinement_case == RefinementCase<dim>::isotropic_refinement)
439  {
440  std::vector<std::vector<FullMatrix<double> > >
441  isotropic_matrices(RefinementCase<dim>::isotropic_refinement);
442  isotropic_matrices.back().
443  resize(GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
444  FullMatrix<double>(this->dofs_per_cell, this->dofs_per_cell));
445  if (dim == spacedim)
446  FETools::compute_projection_matrices (*this, isotropic_matrices, true);
447  else
449  isotropic_matrices, true);
450  this_nonconst.restriction[refinement_case-1].swap(isotropic_matrices.back());
451  }
452  else
453  {
454  // must compute both restriction and prolongation matrices because
455  // we only check for their size and the reinit call initializes them
456  // all
458  if (dim == spacedim)
459  {
460  FETools::compute_embedding_matrices (*this, this_nonconst.prolongation);
461  FETools::compute_projection_matrices (*this, this_nonconst.restriction);
462  }
463  else
464  {
465  FE_DGQ<dim> tmp(this->degree);
468  }
469  }
470  }
471 
472  // finally return the matrix
473  return this->restriction[refinement_case-1][child];
474 }
475 
476 
477 
478 template <int dim, int spacedim>
479 bool
481 {
482  return true;
483 }
484 
485 
486 
487 template <int dim, int spacedim>
488 std::vector<std::pair<unsigned int, unsigned int> >
491 {
492  // this element is discontinuous, so by definition there can
493  // be no identities between its dofs and those of any neighbor
494  // (of whichever type the neighbor may be -- after all, we have
495  // no face dofs on this side to begin with)
496  return
497  std::vector<std::pair<unsigned int, unsigned int> > ();
498 }
499 
500 
501 
502 template <int dim, int spacedim>
503 std::vector<std::pair<unsigned int, unsigned int> >
506 {
507  // this element is discontinuous, so by definition there can
508  // be no identities between its dofs and those of any neighbor
509  // (of whichever type the neighbor may be -- after all, we have
510  // no face dofs on this side to begin with)
511  return
512  std::vector<std::pair<unsigned int, unsigned int> > ();
513 }
514 
515 
516 
517 template <int dim, int spacedim>
518 std::vector<std::pair<unsigned int, unsigned int> >
521 {
522  // this element is discontinuous, so by definition there can
523  // be no identities between its dofs and those of any neighbor
524  // (of whichever type the neighbor may be -- after all, we have
525  // no face dofs on this side to begin with)
526  return
527  std::vector<std::pair<unsigned int, unsigned int> > ();
528 }
529 
530 
531 
532 template <int dim, int spacedim>
535 {
536  // this is a discontinuous element, so by definition there will
537  // be no constraints wherever this element comes together with
538  // any other kind of element
540 }
541 
542 
543 
544 template <int dim, int spacedim>
545 bool
546 FE_DGQ<dim, spacedim>::has_support_on_face (const unsigned int shape_index,
547  const unsigned int face_index) const
548 {
549  Assert (shape_index < this->dofs_per_cell,
550  ExcIndexRange (shape_index, 0, this->dofs_per_cell));
553 
554  unsigned int n = this->degree+1;
555 
556  // For DGQ elements that do not define support points, we cannot define
557  // whether they have support at the boundary easily, so return true in any
558  // case
559  if (this->unit_support_points.empty())
560  return true;
561 
562  // for DGQ(0) elements or arbitrary node DGQ with support points not located
563  // at the element boundary, the single shape functions is constant and
564  // therefore lives on the boundary
565  bool support_points_on_boundary = true;
566  for (unsigned int d=0; d<dim; ++d)
567  if (std::abs(this->unit_support_points[0][d]) > 1e-13)
568  support_points_on_boundary = false;
569  for (unsigned int d=0; d<dim; ++d)
570  if (std::abs(this->unit_support_points.back()[d]-1.) > 1e-13)
571  support_points_on_boundary = false;
572  if (support_points_on_boundary == false)
573  return true;
574 
575  unsigned int n2 = n*n;
576 
577  switch (dim)
578  {
579  case 1:
580  {
581  // in 1d, things are simple. since
582  // there is only one degree of
583  // freedom per vertex in this
584  // class, the first is on vertex 0
585  // (==face 0 in some sense), the
586  // second on face 1:
587  return (((shape_index == 0) && (face_index == 0)) ||
588  ((shape_index == this->degree) && (face_index == 1)));
589  };
590 
591  case 2:
592  {
593  if (face_index==0 && (shape_index % n) == 0)
594  return true;
595  if (face_index==1 && (shape_index % n) == this->degree)
596  return true;
597  if (face_index==2 && shape_index < n)
598  return true;
599  if (face_index==3 && shape_index >= this->dofs_per_cell-n)
600  return true;
601  return false;
602  };
603 
604  case 3:
605  {
606  const unsigned int in2 = shape_index % n2;
607 
608  // x=0
609  if (face_index==0 && (shape_index % n) == 0)
610  return true;
611  // x=1
612  if (face_index==1 && (shape_index % n) == n-1)
613  return true;
614  // y=0
615  if (face_index==2 && in2 < n )
616  return true;
617  // y=1
618  if (face_index==3 && in2 >= n2-n)
619  return true;
620  // z=0
621  if (face_index==4 && shape_index < n2)
622  return true;
623  // z=1
624  if (face_index==5 && shape_index >= this->dofs_per_cell - n2)
625  return true;
626  return false;
627  };
628 
629  default:
630  Assert (false, ExcNotImplemented());
631  }
632  return true;
633 }
634 
635 
636 
637 template <int dim, int spacedim>
638 std::pair<Table<2,bool>, std::vector<unsigned int> >
640 {
641  Table<2,bool> constant_modes(1, this->dofs_per_cell);
642  constant_modes.fill(true);
643  return std::pair<Table<2,bool>, std::vector<unsigned int> >
644  (constant_modes, std::vector<unsigned int>(1, 0));
645 }
646 
647 
648 
649 
650 template <int dim, int spacedim>
651 std::size_t
653 {
654  Assert (false, ExcNotImplemented ());
655  return 0;
656 }
657 
658 
659 
660 // ------------------------------ FE_DGQArbitraryNodes -----------------------
661 
662 template <int dim, int spacedim>
664  : FE_DGQ<dim,spacedim>(Polynomials::generate_complete_Lagrange_basis(points.get_points()))
665 {
666  Assert (points.size() > 0,
668  Quadrature<dim> support_quadrature(points);
669  this->unit_support_points = support_quadrature.get_points();
670 }
671 
672 
673 
674 template <int dim, int spacedim>
675 std::string
677 {
678  // note that the FETools::get_fe_by_name function does not work for
679  // FE_DGQArbitraryNodes since there is no initialization by a degree value.
680  std::ostringstream namebuf;
681  bool equidistant = true;
682  std::vector<double> points(this->degree+1);
683 
684  std::vector<unsigned int> lexicographic = this->poly_space.get_numbering_inverse();
685  for (unsigned int j=0; j<=this->degree; j++)
686  points[j] = this->unit_support_points[lexicographic[j]][0];
687 
688  // Check whether the support points are equidistant.
689  for (unsigned int j=0; j<=this->degree; j++)
690  if (std::abs(points[j] - (double)j/this->degree) > 1e-15)
691  {
692  equidistant = false;
693  break;
694  }
695  if (this->degree == 0 && std::abs(points[0]-0.5) < 1e-15)
696  equidistant = true;
697 
698  if (equidistant == true)
699  {
700  if (this->degree > 2)
701  namebuf << "FE_DGQArbitraryNodes<" << Utilities::dim_string(dim,spacedim) << ">(QIterated(QTrapez()," << this->degree << "))";
702  else
703  namebuf << "FE_DGQ<" << Utilities::dim_string(dim,spacedim) << ">(" << this->degree << ")";
704  return namebuf.str();
705  }
706 
707  // Check whether the support points come from QGaussLobatto.
708  const QGaussLobatto<1> points_gl(this->degree+1);
709  bool gauss_lobatto = true;
710  for (unsigned int j=0; j<=this->degree; j++)
711  if (points[j] != points_gl.point(j)(0))
712  {
713  gauss_lobatto = false;
714  break;
715  }
716 
717  if (gauss_lobatto == true)
718  {
719  namebuf << "FE_DGQ<" << Utilities::dim_string(dim,spacedim) << ">(" << this->degree << ")";
720  return namebuf.str();
721  }
722 
723  // Check whether the support points come from QGauss.
724  const QGauss<1> points_g(this->degree+1);
725  bool gauss = true;
726  for (unsigned int j=0; j<=this->degree; j++)
727  if (points[j] != points_g.point(j)(0))
728  {
729  gauss = false;
730  break;
731  }
732 
733  if (gauss == true)
734  {
735  namebuf << "FE_DGQArbitraryNodes<" << Utilities::dim_string(dim,spacedim) << ">(QGauss(" << this->degree+1 << "))";
736  return namebuf.str();
737  }
738 
739  // Check whether the support points come from QGauss.
740  const QGaussLog<1> points_glog(this->degree+1);
741  bool gauss_log = true;
742  for (unsigned int j=0; j<=this->degree; j++)
743  if (points[j] != points_glog.point(j)(0))
744  {
745  gauss_log = false;
746  break;
747  }
748 
749  if (gauss_log == true)
750  {
751  namebuf << "FE_DGQArbitraryNodes<" << Utilities::dim_string(dim,spacedim) << ">(QGaussLog(" << this->degree+1 << "))";
752  return namebuf.str();
753  }
754 
755  // All guesses exhausted
756  namebuf << "FE_DGQArbitraryNodes<" << Utilities::dim_string(dim,spacedim) << ">(QUnknownNodes(" << this->degree+1 << "))";
757  return namebuf.str();
758 }
759 
760 
761 
762 template <int dim, int spacedim>
765 {
766  // Construct a dummy quadrature formula containing the FE's nodes:
767  std::vector<Point<1> > qpoints(this->degree+1);
768  std::vector<unsigned int> lexicographic = this->poly_space.get_numbering_inverse();
769  for (unsigned int i=0; i<=this->degree; ++i)
770  qpoints[i] = Point<1>(this->unit_support_points[lexicographic[i]][0]);
771  Quadrature<1> pquadrature(qpoints);
772 
773  return new FE_DGQArbitraryNodes<dim,spacedim>(pquadrature);
774 }
775 
776 
777 
778 // ---------------------------------- FE_DGQLegendre -------------------------
779 
780 template <int dim, int spacedim>
782  : FE_DGQ<dim,spacedim>(Polynomials::Legendre::generate_complete_basis(degree))
783 {}
784 
785 
786 
787 template <int dim, int spacedim>
788 std::pair<Table<2,bool>, std::vector<unsigned int> >
790 {
791  // Legendre represents a constant function by one in the first basis
792  // function and zero in all others
793  Table<2,bool> constant_modes(1, this->dofs_per_cell);
794  constant_modes(0,0) = true;
795  return std::pair<Table<2,bool>, std::vector<unsigned int> >
796  (constant_modes, std::vector<unsigned int>(1, 0));
797 }
798 
799 
800 
801 template <int dim, int spacedim>
802 std::string
804 {
805  return "FE_DGQLegendre<" + Utilities::dim_string(dim,spacedim) + ">("
806  + Utilities::int_to_string(this->degree) + ")";
807 }
808 
809 
810 
811 template <int dim, int spacedim>
814 {
815  return new FE_DGQLegendre<dim,spacedim>(this->degree);
816 }
817 
818 
819 
820 // ---------------------------------- FE_DGQHermite --------------------------
821 
822 template <int dim, int spacedim>
824  : FE_DGQ<dim,spacedim>(degree < 3 ?
825  Polynomials::generate_complete_Lagrange_basis(get_QGaussLobatto_points(degree))
826  :
827  Polynomials::HermiteInterpolation::generate_complete_basis(degree))
828 {}
829 
830 
831 
832 template <int dim, int spacedim>
833 std::pair<Table<2,bool>, std::vector<unsigned int> >
835 {
836  if (this->degree < 3)
838  else
839  {
840  // The first two basis functions in the Hermite polynomials represent
841  // the value 1 in the left and right end point of the element. Expand
842  // them into the tensor product.
843  AssertThrow(dim<=3, ExcNotImplemented());
844  Table<2,bool> constant_modes(1, this->dofs_per_cell);
845  for (unsigned int i=0; i<(dim>2?2:1); ++i)
846  for (unsigned int j=0; j<(dim>1?2:1); ++j)
847  for (unsigned int k=0; k<2; ++k)
848  constant_modes(0,i*(this->degree+1)*(this->degree+1)+j*(this->degree+1)+k) = true;
849  return std::pair<Table<2,bool>, std::vector<unsigned int> >
850  (constant_modes, std::vector<unsigned int>(1, 0));
851  }
852 }
853 
854 
855 
856 template <int dim, int spacedim>
857 std::string
859 {
860  return "FE_DGQHermite<" + Utilities::dim_string(dim,spacedim) + ">("
861  + Utilities::int_to_string(this->degree) + ")";
862 }
863 
864 
865 
866 template <int dim, int spacedim>
869 {
870  return new FE_DGQHermite<dim,spacedim>(this->degree);
871 }
872 
873 
874 
875 // explicit instantiations
876 #include "fe_dgq.inst"
877 
878 
879 DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcFEHasNoSupportPoints()
size_type m() const
virtual FiniteElement< dim, spacedim > * clone() const
Definition: fe_dgq.cc:107
virtual FiniteElement< dim, spacedim > * clone() const
Definition: fe_dgq.cc:764
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
Definition: fe_dgq.cc:321
std::vector< std::vector< FullMatrix< double > > > restriction
Definition: fe.h:2185
const std::vector< Point< dim > > & get_points() const
void gauss_jordan()
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim, spacedim > &fe_other) const
Definition: fe_dgq.cc:534
FE_DGQLegendre(const unsigned int degree)
Definition: fe_dgq.cc:781
Definition: fe_dgq.h:105
virtual FiniteElement< dim, spacedim > * clone() const
Definition: fe_dgq.cc:813
const unsigned int degree
Definition: fe_base.h:311
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
Definition: fe_dgq.cc:294
const Point< dim > & point(const unsigned int i) const
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::size_t memory_consumption() const
Definition: fe_dgq.cc:652
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
Definition: point.h:89
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
Definition: fe_dgq.cc:349
std::vector< Point< dim > > unit_support_points
Definition: fe.h:2223
static ::ExceptionBase & ExcMessage(std::string arg1)
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const
Definition: fe_dgq.cc:639
size_type n() const
std::vector< std::vector< FullMatrix< double > > > prolongation
Definition: fe.h:2199
virtual std::string get_name() const
Definition: fe_dgq.cc:858
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
Definition: fe_dgq.cc:120
#define Assert(cond, exc)
Definition: exceptions.h:313
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
Definition: fe_dgq.cc:546
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const
Definition: fe_dgq.cc:834
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
Definition: fe_dgq.cc:415
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
Definition: fe_dgq.cc:211
void rotate_indices(std::vector< unsigned int > &indices, const char direction) const
Definition: fe_dgq.cc:133
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition: utilities.cc:85
std::string dim_string(const int dim, const int spacedim)
Definition: utilities.cc:161
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
Definition: fe_base.h:295
FE_DGQArbitraryNodes(const Quadrature< 1 > &points)
Definition: fe_dgq.cc:663
virtual FiniteElement< dim, spacedim > * clone() const
Definition: fe_dgq.cc:868
void mmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
FE_DGQHermite(const unsigned int degree)
Definition: fe_dgq.cc:823
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
Definition: fe_dgq.cc:520
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
Definition: fe_dgq.cc:505
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::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const
Definition: fe_dgq.cc:789
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
Definition: fe_dgq.cc:490
double compute_value(const unsigned int i, const Point< dim > &p) const
virtual std::string get_name() const
Definition: fe_dgq.cc:803
void fill(InputIterator entries, const bool C_style_indexing=true)
friend class FE_DGQ
Definition: fe_dgq.h:367
virtual bool hp_constraints_are_implemented() const
Definition: fe_dgq.cc:480
virtual std::string get_name() const
Definition: fe_dgq.cc:676
static ::ExceptionBase & ExcInternalError()
virtual std::string get_name() const
Definition: fe_dgq.cc:90