Reference documentation for deal.II version 9.1.0-pre
fe.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2018 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/memory_consumption.h>
17 #include <deal.II/base/qprojector.h>
18 #include <deal.II/base/quadrature.h>
19 
20 #include <deal.II/dofs/dof_accessor.h>
21 
22 #include <deal.II/fe/fe.h>
23 #include <deal.II/fe/fe_values.h>
24 #include <deal.II/fe/mapping.h>
25 
26 #include <deal.II/grid/tria.h>
27 #include <deal.II/grid/tria_iterator.h>
28 
29 #include <algorithm>
30 #include <functional>
31 #include <numeric>
32 #include <typeinfo>
33 
34 DEAL_II_NAMESPACE_OPEN
35 
36 
37 /*------------------------------- FiniteElement ----------------------*/
38 
39 
40 template <int dim, int spacedim>
42  : update_each(update_default)
43 {}
44 
45 
46 
47 template <int dim, int spacedim>
48 std::size_t
50 {
51  return sizeof(*this);
52 }
53 
54 
55 
56 template <int dim, int spacedim>
58  const FiniteElementData<dim> & fe_data,
59  const std::vector<bool> & r_i_a_f,
60  const std::vector<ComponentMask> &nonzero_c)
61  : FiniteElementData<dim>(fe_data)
63  this->dofs_per_quad :
64  0,
65  dim == 3 ? 8 : 0)
67  dim == 3 ? this->dofs_per_line : 0)
71  std::make_pair(std::make_pair(0U, 0U), 0U))
72  ,
73 
74  // Special handling of vectors of length one: in this case, we
75  // assume that all entries were supposed to be equal
77  r_i_a_f.size() == 1 ? std::vector<bool>(fe_data.dofs_per_cell, r_i_a_f[0]) :
78  r_i_a_f)
80  nonzero_c.size() == 1 ?
81  std::vector<ComponentMask>(fe_data.dofs_per_cell, nonzero_c[0]) :
82  nonzero_c)
86  std::bind(std::not_equal_to<unsigned int>(),
87  std::placeholders::_1,
88  1U)) ==
90 {
93  this->dofs_per_cell));
95  for (unsigned int i = 0; i < nonzero_components.size(); ++i)
96  {
97  Assert(nonzero_components[i].size() == this->n_components(),
99  Assert(nonzero_components[i].n_selected_components() >= 1,
100  ExcInternalError());
103  ExcInternalError());
104  }
105 
106  // initialize some tables in the default way, i.e. if there is only one
107  // (vector-)component; if the element is not primitive, leave these tables
108  // empty.
109  if (this->is_primitive())
110  {
113  for (unsigned int j = 0; j < this->dofs_per_cell; ++j)
114  system_to_component_table[j] = std::pair<unsigned, unsigned>(0, j);
115  for (unsigned int j = 0; j < this->dofs_per_face; ++j)
116  face_system_to_component_table[j] = std::pair<unsigned, unsigned>(0, j);
117  }
118 
119  for (unsigned int j = 0; j < this->dofs_per_cell; ++j)
120  system_to_base_table[j] = std::make_pair(std::make_pair(0U, 0U), j);
121  for (unsigned int j = 0; j < this->dofs_per_face; ++j)
122  face_system_to_base_table[j] = std::make_pair(std::make_pair(0U, 0U), j);
123 
124  // Fill with default value; may be changed by constructor of derived class.
126 
127  // initialize the restriction and prolongation matrices. the default
128  // constructor of FullMatrix<dim> initializes them with size zero
131  for (unsigned int ref = RefinementCase<dim>::cut_x;
132  ref < RefinementCase<dim>::isotropic_refinement + 1;
133  ++ref)
134  {
136  RefinementCase<dim>(ref)),
139  RefinementCase<dim>(ref)),
141  }
142 
144 }
145 
146 
147 
148 template <int dim, int spacedim>
149 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>
150 FiniteElement<dim, spacedim>::operator^(const unsigned int multiplicity) const
151 {
152  return {this->clone(), multiplicity};
153 }
154 
155 
156 
157 template <int dim, int spacedim>
158 double
160  const Point<dim> &) const
161 {
163  return 0.;
164 }
165 
166 
167 
168 template <int dim, int spacedim>
169 double
171  const Point<dim> &,
172  const unsigned int) const
173 {
175  return 0.;
176 }
177 
178 
179 
180 template <int dim, int spacedim>
183  const Point<dim> &) const
184 {
186  return Tensor<1, dim>();
187 }
188 
189 
190 
191 template <int dim, int spacedim>
194  const Point<dim> &,
195  const unsigned int) const
196 {
198  return Tensor<1, dim>();
199 }
200 
201 
202 
203 template <int dim, int spacedim>
206  const Point<dim> &) const
207 {
209  return Tensor<2, dim>();
210 }
211 
212 
213 
214 template <int dim, int spacedim>
217  const unsigned int,
218  const Point<dim> &,
219  const unsigned int) const
220 {
222  return Tensor<2, dim>();
223 }
224 
225 
226 
227 template <int dim, int spacedim>
230  const Point<dim> &) const
231 {
233  return Tensor<3, dim>();
234 }
235 
236 
237 
238 template <int dim, int spacedim>
241  const unsigned int,
242  const Point<dim> &,
243  const unsigned int) const
244 {
246  return Tensor<3, dim>();
247 }
248 
249 
250 
251 template <int dim, int spacedim>
254  const Point<dim> &) const
255 {
257  return Tensor<4, dim>();
258 }
259 
260 
261 
262 template <int dim, int spacedim>
265  const unsigned int,
266  const Point<dim> &,
267  const unsigned int) const
268 {
270  return Tensor<4, dim>();
271 }
272 
273 
274 template <int dim, int spacedim>
275 void
277  const bool isotropic_restriction_only,
278  const bool isotropic_prolongation_only)
279 {
280  for (unsigned int ref_case = RefinementCase<dim>::cut_x;
281  ref_case <= RefinementCase<dim>::isotropic_refinement;
282  ++ref_case)
283  {
284  const unsigned int nc =
286 
287  for (unsigned int i = 0; i < nc; ++i)
288  {
289  if (this->restriction[ref_case - 1][i].m() != this->dofs_per_cell &&
290  (!isotropic_restriction_only ||
292  this->restriction[ref_case - 1][i].reinit(this->dofs_per_cell,
293  this->dofs_per_cell);
294  if (this->prolongation[ref_case - 1][i].m() != this->dofs_per_cell &&
295  (!isotropic_prolongation_only ||
297  this->prolongation[ref_case - 1][i].reinit(this->dofs_per_cell,
298  this->dofs_per_cell);
299  }
300  }
301 }
302 
303 
304 template <int dim, int spacedim>
305 const FullMatrix<double> &
307  const unsigned int child,
308  const RefinementCase<dim> &refinement_case) const
309 {
311  ExcIndexRange(refinement_case,
312  0,
314  Assert(refinement_case != RefinementCase<dim>::no_refinement,
315  ExcMessage(
316  "Restriction matrices are only available for refined cells!"));
317  Assert(child <
319  ExcIndexRange(child,
320  0,
322  RefinementCase<dim>(refinement_case))));
323  // we use refinement_case-1 here. the -1 takes care of the origin of the
324  // vector, as for RefinementCase<dim>::no_refinement (=0) there is no data
325  // available and so the vector indices are shifted
326  Assert(restriction[refinement_case - 1][child].n() == this->dofs_per_cell,
328  return restriction[refinement_case - 1][child];
329 }
330 
331 
332 
333 template <int dim, int spacedim>
334 const FullMatrix<double> &
336  const unsigned int child,
337  const RefinementCase<dim> &refinement_case) const
338 {
340  ExcIndexRange(refinement_case,
341  0,
343  Assert(refinement_case != RefinementCase<dim>::no_refinement,
344  ExcMessage(
345  "Prolongation matrices are only available for refined cells!"));
346  Assert(child <
348  ExcIndexRange(child,
349  0,
351  RefinementCase<dim>(refinement_case))));
352  // we use refinement_case-1 here. the -1 takes care
353  // of the origin of the vector, as for
354  // RefinementCase::no_refinement (=0) there is no
355  // data available and so the vector indices
356  // are shifted
357  Assert(prolongation[refinement_case - 1][child].n() == this->dofs_per_cell,
358  ExcEmbeddingVoid());
359  return prolongation[refinement_case - 1][child];
360 }
361 
362 
363 // TODO:[GK] This is probably not the most efficient way of doing this.
364 template <int dim, int spacedim>
365 unsigned int
367  const unsigned int index) const
368 {
369  Assert(index < this->n_components(),
370  ExcIndexRange(index, 0, this->n_components()));
371 
372  return first_block_of_base(component_to_base_table[index].first.first) +
373  component_to_base_table[index].second;
374 }
375 
376 
377 template <int dim, int spacedim>
380  const FEValuesExtractors::Scalar &scalar) const
381 {
382  AssertIndexRange(scalar.component, this->n_components());
383 
384  // TODO: it would be nice to verify that it is indeed possible
385  // to select this scalar component, i.e., that it is not part
386  // of a non-primitive element. unfortunately, there is no simple
387  // way to write such a condition...
388 
389  std::vector<bool> mask(this->n_components(), false);
390  mask[scalar.component] = true;
391  return mask;
392 }
393 
394 
395 template <int dim, int spacedim>
398  const FEValuesExtractors::Vector &vector) const
399 {
400  AssertIndexRange(vector.first_vector_component + dim - 1,
401  this->n_components());
402 
403  // TODO: it would be nice to verify that it is indeed possible
404  // to select these vector components, i.e., that they don't span
405  // beyond the beginning or end of anon-primitive element.
406  // unfortunately, there is no simple way to write such a condition...
407 
408  std::vector<bool> mask(this->n_components(), false);
409  for (unsigned int c = vector.first_vector_component;
410  c < vector.first_vector_component + dim;
411  ++c)
412  mask[c] = true;
413  return mask;
414 }
415 
416 
417 template <int dim, int spacedim>
420  const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const
421 {
424  this->n_components());
425 
426  // TODO: it would be nice to verify that it is indeed possible
427  // to select these vector components, i.e., that they don't span
428  // beyond the beginning or end of anon-primitive element.
429  // unfortunately, there is no simple way to write such a condition...
430 
431  std::vector<bool> mask(this->n_components(), false);
432  for (unsigned int c = sym_tensor.first_tensor_component;
433  c < sym_tensor.first_tensor_component +
435  ++c)
436  mask[c] = true;
437  return mask;
438 }
439 
440 
441 
442 template <int dim, int spacedim>
445 {
446  // if we get a block mask that represents all blocks, then
447  // do the same for the returned component mask
448  if (block_mask.represents_the_all_selected_mask())
449  return ComponentMask();
450 
451  AssertDimension(block_mask.size(), this->n_blocks());
452 
453  std::vector<bool> component_mask(this->n_components(), false);
454  for (unsigned int c = 0; c < this->n_components(); ++c)
455  if (block_mask[component_to_block_index(c)] == true)
456  component_mask[c] = true;
457 
458  return component_mask;
459 }
460 
461 
462 
463 template <int dim, int spacedim>
464 BlockMask
466  const FEValuesExtractors::Scalar &scalar) const
467 {
468  // simply create the corresponding component mask (a simpler
469  // process) and then convert it to a block mask
470  return block_mask(component_mask(scalar));
471 }
472 
473 
474 template <int dim, int spacedim>
475 BlockMask
477  const FEValuesExtractors::Vector &vector) const
478 {
479  // simply create the corresponding component mask (a simpler
480  // process) and then convert it to a block mask
481  return block_mask(component_mask(vector));
482 }
483 
484 
485 template <int dim, int spacedim>
486 BlockMask
488  const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const
489 {
490  // simply create the corresponding component mask (a simpler
491  // process) and then convert it to a block mask
492  return block_mask(component_mask(sym_tensor));
493 }
494 
495 
496 
497 template <int dim, int spacedim>
498 BlockMask
500  const ComponentMask &component_mask) const
501 {
502  // if we get a component mask that represents all component, then
503  // do the same for the returned block mask
504  if (component_mask.represents_the_all_selected_mask())
505  return BlockMask();
506 
507  AssertDimension(component_mask.size(), this->n_components());
508 
509  // walk over all of the components
510  // of this finite element and see
511  // if we need to set the
512  // corresponding block. inside the
513  // block, walk over all the
514  // components that correspond to
515  // this block and make sure the
516  // component mask is set for all of
517  // them
518  std::vector<bool> block_mask(this->n_blocks(), false);
519  for (unsigned int c = 0; c < this->n_components();)
520  {
521  const unsigned int block = component_to_block_index(c);
522  if (component_mask[c] == true)
523  block_mask[block] = true;
524 
525  // now check all of the other
526  // components that correspond
527  // to this block
528  ++c;
529  while ((c < this->n_components()) &&
530  (component_to_block_index(c) == block))
531  {
532  Assert(component_mask[c] == block_mask[block],
533  ExcMessage(
534  "The component mask argument given to this function "
535  "is not a mask where the individual components belonging "
536  "to one block of the finite element are either all "
537  "selected or not selected. You can't call this function "
538  "with a component mask that splits blocks."));
539  ++c;
540  }
541  }
542 
543 
544  return block_mask;
545 }
546 
547 
548 
549 template <int dim, int spacedim>
550 unsigned int
552  const unsigned int face,
553  const bool face_orientation,
554  const bool face_flip,
555  const bool face_rotation) const
556 {
557  Assert(face_index < this->dofs_per_face,
558  ExcIndexRange(face_index, 0, this->dofs_per_face));
561 
562  // TODO: we could presumably solve the 3d case below using the
563  // adjust_quad_dof_index_for_face_orientation_table field. for the
564  // 2d case, we can't use adjust_line_dof_index_for_line_orientation_table
565  // since that array is empty (presumably because we thought that
566  // there are no flipped edges in 2d, but these can happen in
567  // DoFTools::make_periodicity_constraints, for example). so we
568  // would need to either fill this field, or rely on derived classes
569  // implementing this function, as we currently do
570 
571  // see the function's documentation for an explanation of this
572  // assertion -- in essence, derived classes have to implement
573  // an overloaded version of this function if we are to use any
574  // other than standard orientation
575  if ((face_orientation != true) || (face_flip != false) ||
576  (face_rotation != false))
577  Assert((this->dofs_per_line <= 1) && (this->dofs_per_quad <= 1),
578  ExcMessage(
579  "The function in this base class can not handle this case. "
580  "Rather, the derived class you are using must provide "
581  "an overloaded version but apparently hasn't done so. See "
582  "the documentation of this function for more information."));
583 
584  // we need to distinguish between DoFs on vertices, lines and in 3d quads.
585  // do so in a sequence of if-else statements
586  if (face_index < this->first_face_line_index)
587  // DoF is on a vertex
588  {
589  // get the number of the vertex on the face that corresponds to this DoF,
590  // along with the number of the DoF on this vertex
591  const unsigned int face_vertex = face_index / this->dofs_per_vertex;
592  const unsigned int dof_index_on_vertex =
593  face_index % this->dofs_per_vertex;
594 
595  // then get the number of this vertex on the cell and translate
596  // this to a DoF number on the cell
598  face, face_vertex, face_orientation, face_flip, face_rotation) *
599  this->dofs_per_vertex +
600  dof_index_on_vertex);
601  }
602  else if (face_index < this->first_face_quad_index)
603  // DoF is on a face
604  {
605  // do the same kind of translation as before. we need to only consider
606  // DoFs on the lines, i.e., ignoring those on the vertices
607  const unsigned int index = face_index - this->first_face_line_index;
608 
609  const unsigned int face_line = index / this->dofs_per_line;
610  const unsigned int dof_index_on_line = index % this->dofs_per_line;
611 
612  return (this->first_line_index +
614  face, face_line, face_orientation, face_flip, face_rotation) *
615  this->dofs_per_line +
616  dof_index_on_line);
617  }
618  else
619  // DoF is on a quad
620  {
621  Assert(dim >= 3, ExcInternalError());
622 
623  // ignore vertex and line dofs
624  const unsigned int index = face_index - this->first_face_quad_index;
625 
626  return (this->first_quad_index + face * this->dofs_per_quad + index);
627  }
628 }
629 
630 
631 
632 template <int dim, int spacedim>
633 unsigned int
635  const unsigned int index,
636  const bool face_orientation,
637  const bool face_flip,
638  const bool face_rotation) const
639 {
640  // general template for 1D and 2D: not
641  // implemented. in fact, the function
642  // shouldn't even be called unless we are
643  // in 3d, so throw an internal error
644  Assert(dim == 3, ExcInternalError());
645  if (dim < 3)
646  return index;
647 
648  // adjust dofs on 3d faces if the face is
649  // flipped. note that we query a table that
650  // derived elements need to have set up
651  // front. the exception are discontinuous
652  // elements for which there should be no
653  // face dofs anyway (i.e. dofs_per_quad==0
654  // in 3d), so we don't need the table, but
655  // the function should also not have been
656  // called
657  Assert(index < this->dofs_per_quad,
658  ExcIndexRange(index, 0, this->dofs_per_quad));
660  8 * this->dofs_per_quad,
661  ExcInternalError());
663  index, 4 * face_orientation + 2 * face_flip + face_rotation);
664 }
665 
666 
667 
668 template <int dim, int spacedim>
669 unsigned int
671  const unsigned int index,
672  const bool line_orientation) const
673 {
674  // general template for 1D and 2D: do
675  // nothing. Do not throw an Assertion,
676  // however, in order to allow to call this
677  // function in 2D as well
678  if (dim < 3)
679  return index;
680 
681  Assert(index < this->dofs_per_line,
682  ExcIndexRange(index, 0, this->dofs_per_line));
684  this->dofs_per_line,
685  ExcInternalError());
686  if (line_orientation)
687  return index;
688  else
690 }
691 
692 
693 
694 template <int dim, int spacedim>
695 bool
697 {
698  for (unsigned int ref_case = RefinementCase<dim>::cut_x;
699  ref_case < RefinementCase<dim>::isotropic_refinement + 1;
700  ++ref_case)
701  for (unsigned int c = 0;
702  c < GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
703  ++c)
704  {
705  // make sure also the lazily initialized matrices are created
707  Assert((prolongation[ref_case - 1][c].m() == this->dofs_per_cell) ||
708  (prolongation[ref_case - 1][c].m() == 0),
709  ExcInternalError());
710  Assert((prolongation[ref_case - 1][c].n() == this->dofs_per_cell) ||
711  (prolongation[ref_case - 1][c].n() == 0),
712  ExcInternalError());
713  if ((prolongation[ref_case - 1][c].m() == 0) ||
714  (prolongation[ref_case - 1][c].n() == 0))
715  return false;
716  }
717  return true;
718 }
719 
720 
721 
722 template <int dim, int spacedim>
723 bool
725 {
726  for (unsigned int ref_case = RefinementCase<dim>::cut_x;
727  ref_case < RefinementCase<dim>::isotropic_refinement + 1;
728  ++ref_case)
729  for (unsigned int c = 0;
730  c < GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
731  ++c)
732  {
733  // make sure also the lazily initialized matrices are created
735  Assert((restriction[ref_case - 1][c].m() == this->dofs_per_cell) ||
736  (restriction[ref_case - 1][c].m() == 0),
737  ExcInternalError());
738  Assert((restriction[ref_case - 1][c].n() == this->dofs_per_cell) ||
739  (restriction[ref_case - 1][c].n() == 0),
740  ExcInternalError());
741  if ((restriction[ref_case - 1][c].m() == 0) ||
742  (restriction[ref_case - 1][c].n() == 0))
743  return false;
744  }
745  return true;
746 }
747 
748 
749 
750 template <int dim, int spacedim>
751 bool
753 {
754  const RefinementCase<dim> ref_case =
756 
757  for (unsigned int c = 0;
758  c < GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
759  ++c)
760  {
761  // make sure also the lazily initialized matrices are created
763  Assert((prolongation[ref_case - 1][c].m() == this->dofs_per_cell) ||
764  (prolongation[ref_case - 1][c].m() == 0),
765  ExcInternalError());
766  Assert((prolongation[ref_case - 1][c].n() == this->dofs_per_cell) ||
767  (prolongation[ref_case - 1][c].n() == 0),
768  ExcInternalError());
769  if ((prolongation[ref_case - 1][c].m() == 0) ||
770  (prolongation[ref_case - 1][c].n() == 0))
771  return false;
772  }
773  return true;
774 }
775 
776 
777 
778 template <int dim, int spacedim>
779 bool
781 {
782  const RefinementCase<dim> ref_case =
784 
785  for (unsigned int c = 0;
786  c < GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
787  ++c)
788  {
789  // make sure also the lazily initialized matrices are created
791  Assert((restriction[ref_case - 1][c].m() == this->dofs_per_cell) ||
792  (restriction[ref_case - 1][c].m() == 0),
793  ExcInternalError());
794  Assert((restriction[ref_case - 1][c].n() == this->dofs_per_cell) ||
795  (restriction[ref_case - 1][c].n() == 0),
796  ExcInternalError());
797  if ((restriction[ref_case - 1][c].m() == 0) ||
798  (restriction[ref_case - 1][c].n() == 0))
799  return false;
800  }
801  return true;
802 }
803 
804 
805 
806 template <int dim, int spacedim>
807 bool
809  const internal::SubfaceCase<dim> &subface_case) const
810 {
811  if (subface_case == internal::SubfaceCase<dim>::case_isotropic)
812  return (this->dofs_per_face == 0) || (interface_constraints.m() != 0);
813  else
814  return false;
815 }
816 
817 
818 
819 template <int dim, int spacedim>
820 bool
822 {
823  return false;
824 }
825 
826 
827 
828 template <int dim, int spacedim>
829 const FullMatrix<double> &
831  const internal::SubfaceCase<dim> &subface_case) const
832 {
833  (void)subface_case;
835  ExcMessage("Constraints for this element are only implemented "
836  "for the case that faces are refined isotropically "
837  "(which is always the case in 2d, and in 3d requires "
838  "that the neighboring cell of a coarse cell presents "
839  "exactly four children on the common face)."));
840  Assert((this->dofs_per_face == 0) || (interface_constraints.m() != 0),
841  ExcMessage("The finite element for which you try to obtain "
842  "hanging node constraints does not appear to "
843  "implement them."));
844 
845  if (dim == 1)
849 
850  return interface_constraints;
851 }
852 
853 
854 
855 template <int dim, int spacedim>
858 {
859  switch (dim)
860  {
861  case 1:
862  return TableIndices<2>(0U, 0U);
863  case 2:
864  return TableIndices<2>(this->dofs_per_vertex + 2 * this->dofs_per_line,
865  this->dofs_per_face);
866  case 3:
867  return TableIndices<2>(5 * this->dofs_per_vertex +
868  12 * this->dofs_per_line +
869  4 * this->dofs_per_quad,
870  this->dofs_per_face);
871  default:
872  Assert(false, ExcNotImplemented());
873  };
876 }
877 
878 
879 
880 template <int dim, int spacedim>
881 void
884  FullMatrix<double> &) const
885 {
886  // by default, no interpolation
887  // implemented. so throw exception,
888  // as documentation says
889  AssertThrow(
890  false,
892 }
893 
894 
895 
896 template <int dim, int spacedim>
897 void
900  FullMatrix<double> &) const
901 {
902  // by default, no interpolation
903  // implemented. so throw exception,
904  // as documentation says
905  AssertThrow(
906  false,
908 }
909 
910 
911 
912 template <int dim, int spacedim>
913 void
916  const unsigned int,
917  FullMatrix<double> &) const
918 {
919  // by default, no interpolation
920  // implemented. so throw exception,
921  // as documentation says
922  AssertThrow(
923  false,
925 }
926 
927 
928 
929 template <int dim, int spacedim>
930 std::vector<std::pair<unsigned int, unsigned int>>
932  const FiniteElement<dim, spacedim> &) const
933 {
934  Assert(false, ExcNotImplemented());
935  return std::vector<std::pair<unsigned int, unsigned int>>();
936 }
937 
938 
939 
940 template <int dim, int spacedim>
941 std::vector<std::pair<unsigned int, unsigned int>>
943  const FiniteElement<dim, spacedim> &) const
944 {
945  Assert(false, ExcNotImplemented());
946  return std::vector<std::pair<unsigned int, unsigned int>>();
947 }
948 
949 
950 
951 template <int dim, int spacedim>
952 std::vector<std::pair<unsigned int, unsigned int>>
954  const FiniteElement<dim, spacedim> &) const
955 {
956  Assert(false, ExcNotImplemented());
957  return std::vector<std::pair<unsigned int, unsigned int>>();
958 }
959 
960 
961 
962 template <int dim, int spacedim>
965  const FiniteElement<dim, spacedim> &) const
966 {
967  Assert(false, ExcNotImplemented());
969 }
970 
971 
972 
973 template <int dim, int spacedim>
974 bool
977 {
978  // Compare fields in roughly increasing order of how expensive the
979  // comparison is
980  return ((typeid(*this) == typeid(f)) && (this->get_name() == f.get_name()) &&
981  (static_cast<const FiniteElementData<dim> &>(*this) ==
982  static_cast<const FiniteElementData<dim> &>(f)) &&
984 }
985 
986 
987 
988 template <int dim, int spacedim>
989 bool
992 {
993  return !(*this == f);
994 }
995 
996 
997 
998 template <int dim, int spacedim>
999 const std::vector<Point<dim>> &
1001 {
1002  // a finite element may define
1003  // support points, but only if
1004  // there are as many as there are
1005  // degrees of freedom
1006  Assert((unit_support_points.size() == 0) ||
1007  (unit_support_points.size() == this->dofs_per_cell),
1008  ExcInternalError());
1009  return unit_support_points;
1010 }
1011 
1012 
1013 
1014 template <int dim, int spacedim>
1015 bool
1017 {
1018  return (unit_support_points.size() != 0);
1019 }
1020 
1021 
1022 
1023 template <int dim, int spacedim>
1024 const std::vector<Point<dim>> &
1026 {
1027  // If the finite element implements generalized support points, return
1028  // those. Otherwise fall back to unit support points.
1029  return ((generalized_support_points.size() == 0) ?
1032 }
1033 
1034 
1035 
1036 template <int dim, int spacedim>
1037 bool
1039 {
1040  return (get_generalized_support_points().size() != 0);
1041 }
1042 
1043 
1044 
1045 template <int dim, int spacedim>
1046 Point<dim>
1048 {
1049  Assert(index < this->dofs_per_cell,
1050  ExcIndexRange(index, 0, this->dofs_per_cell));
1051  Assert(unit_support_points.size() == this->dofs_per_cell,
1053  return unit_support_points[index];
1054 }
1055 
1056 
1057 
1058 template <int dim, int spacedim>
1059 const std::vector<Point<dim - 1>> &
1061 {
1062  // a finite element may define
1063  // support points, but only if
1064  // there are as many as there are
1065  // degrees of freedom on a face
1066  Assert((unit_face_support_points.size() == 0) ||
1067  (unit_face_support_points.size() == this->dofs_per_face),
1068  ExcInternalError());
1069  return unit_face_support_points;
1070 }
1071 
1072 
1073 
1074 template <int dim, int spacedim>
1075 bool
1077 {
1078  return (unit_face_support_points.size() != 0);
1079 }
1080 
1081 
1082 
1083 template <int dim, int spacedim>
1084 const std::vector<Point<dim - 1>> &
1086 {
1087  // a finite element may define
1088  // support points, but only if
1089  // there are as many as there are
1090  // degrees of freedom on a face
1091  return ((generalized_face_support_points.size() == 0) ?
1094 }
1095 
1096 
1097 
1098 template <int dim, int spacedim>
1099 bool
1101 {
1102  return (generalized_face_support_points.size() != 0);
1103 }
1104 
1105 
1106 
1107 template <int dim, int spacedim>
1108 Point<dim - 1>
1110  const unsigned int index) const
1111 {
1112  Assert(index < this->dofs_per_face,
1113  ExcIndexRange(index, 0, this->dofs_per_face));
1116  return unit_face_support_points[index];
1117 }
1118 
1119 
1120 
1121 template <int dim, int spacedim>
1122 bool
1124  const unsigned int) const
1125 {
1126  return true;
1127 }
1128 
1129 
1130 
1131 template <int dim, int spacedim>
1134 {
1135  // Translate the ComponentMask into first_selected and n_components after
1136  // some error checking:
1137  const unsigned int n_total_components = this->n_components();
1138  Assert((n_total_components == mask.size()) || (mask.size() == 0),
1139  ExcMessage("The given ComponentMask has the wrong size."));
1140 
1141  const unsigned int n_selected =
1142  mask.n_selected_components(n_total_components);
1143  Assert(n_selected > 0,
1144  ExcMessage("You need at least one selected component."));
1145 
1146  const unsigned int first_selected =
1147  mask.first_selected_component(n_total_components);
1148 
1149 #ifdef DEBUG
1150  // check that it is contiguous:
1151  for (unsigned int c = 0; c < n_total_components; ++c)
1152  Assert((c < first_selected && (!mask[c])) ||
1153  (c >= first_selected && c < first_selected + n_selected &&
1154  mask[c]) ||
1155  (c >= first_selected + n_selected && !mask[c]),
1156  ExcMessage("Error: the given ComponentMask is not contiguous!"));
1157 #endif
1158 
1159  return get_sub_fe(first_selected, n_selected);
1160 }
1161 
1162 
1163 
1164 template <int dim, int spacedim>
1167  const unsigned int first_component,
1168  const unsigned int n_selected_components) const
1169 {
1170  // No complicated logic is needed here, because it is overridden in
1171  // FESystem<dim,spacedim>. Just make sure that what the user chose is valid:
1172  Assert(first_component == 0 && n_selected_components == this->n_components(),
1173  ExcMessage(
1174  "You can only select a whole FiniteElement, not a part of one."));
1175 
1176  (void)first_component;
1177  (void)n_selected_components;
1178  return *this;
1179 }
1180 
1181 
1182 
1183 template <int dim, int spacedim>
1184 std::pair<Table<2, bool>, std::vector<unsigned int>>
1186 {
1187  Assert(false, ExcNotImplemented());
1188  return std::pair<Table<2, bool>, std::vector<unsigned int>>(
1189  Table<2, bool>(this->n_components(), this->dofs_per_cell),
1190  std::vector<unsigned int>(this->n_components()));
1191 }
1192 
1193 
1194 
1195 template <int dim, int spacedim>
1196 void
1199  const std::vector<Vector<double>> &,
1200  std::vector<double> &) const
1201 {
1203  ExcMessage("The element for which you are calling the current "
1204  "function does not have generalized support points (see "
1205  "the glossary for a definition of generalized support "
1206  "points). Consequently, the current function can not "
1207  "be defined and is not implemented by the element."));
1208  Assert(false, ExcNotImplemented());
1209 }
1210 
1211 
1212 
1213 template <int dim, int spacedim>
1214 std::size_t
1216 {
1217  return (
1218  sizeof(FiniteElementData<dim>) +
1230 }
1231 
1232 
1233 
1234 template <int dim, int spacedim>
1235 std::vector<unsigned int>
1237  const std::vector<ComponentMask> &nonzero_components)
1238 {
1239  std::vector<unsigned int> retval(nonzero_components.size());
1240  for (unsigned int i = 0; i < nonzero_components.size(); ++i)
1241  retval[i] = nonzero_components[i].n_selected_components();
1242  return retval;
1243 }
1244 
1245 
1246 
1247 /*------------------------------- FiniteElement ----------------------*/
1248 
1249 template <int dim, int spacedim>
1250 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1252  const UpdateFlags flags,
1253  const Mapping<dim, spacedim> &mapping,
1254  const Quadrature<dim - 1> & quadrature,
1256  spacedim>
1257  &output_data) const
1258 {
1259  return get_data(flags,
1260  mapping,
1262  output_data);
1263 }
1264 
1265 
1266 
1267 template <int dim, int spacedim>
1268 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
1270  const UpdateFlags flags,
1271  const Mapping<dim, spacedim> &mapping,
1272  const Quadrature<dim - 1> & quadrature,
1274  spacedim>
1275  &output_data) const
1276 {
1277  return get_data(flags,
1278  mapping,
1280  output_data);
1281 }
1282 
1283 
1284 
1285 template <int dim, int spacedim>
1287 FiniteElement<dim, spacedim>::base_element(const unsigned int index) const
1288 {
1289  (void)index;
1290  Assert(index == 0, ExcIndexRange(index, 0, 1));
1291  // This function should not be
1292  // called for a system element
1294  return *this;
1295 }
1296 
1297 
1298 
1299 /*------------------------------- Explicit Instantiations -------------*/
1300 #include "fe.inst"
1301 
1302 
1303 DEAL_II_NAMESPACE_CLOSE
static::ExceptionBase & ExcFEHasNoSupportPoints()
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:159
bool prolongation_is_implemented() const
Definition: fe.cc:696
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const
Definition: fe.cc:1185
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
std::vector< std::vector< FullMatrix< double > > > restriction
Definition: fe.h:2419
const unsigned int components
Definition: fe_base.h:307
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1366
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
Definition: fe.cc:942
std::vector< Point< dim > > generalized_support_points
Definition: fe.h:2470
FullMatrix< double > interface_constraints
Definition: fe.h:2445
FiniteElement(const FiniteElementData< dim > &fe_data, const std::vector< bool > &restriction_is_additive_flags, const std::vector< ComponentMask > &nonzero_components)
Definition: fe.cc:57
virtual Tensor< 3, dim > shape_3rd_derivative(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:229
static::ExceptionBase & ExcUnitShapeValuesDoNotExist()
bool isotropic_restriction_is_implemented() const
Definition: fe.cc:780
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
const std::vector< Point< dim-1 > > & get_generalized_face_support_points() const
Definition: fe.cc:1085
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
Definition: fe.cc:882
bool constraints_are_implemented(const ::internal::SubfaceCase< dim > &subface_case=::internal::SubfaceCase< dim >::case_isotropic) const
Definition: fe.cc:808
#define AssertIndexRange(index, range)
Definition: exceptions.h:1407
const unsigned int dofs_per_quad
Definition: fe_base.h:252
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
Definition: fe.cc:953
std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > component_to_base_table
Definition: fe.h:2579
std::vector< Point< dim-1 > > unit_face_support_points
Definition: fe.h:2464
STL namespace.
virtual bool hp_constraints_are_implemented() const
Definition: fe.cc:821
bool isotropic_prolongation_is_implemented() const
Definition: fe.cc:752
const FiniteElement< dim, spacedim > & get_sub_fe(const ComponentMask &mask) const
Definition: fe.cc:1133
unsigned int size() const
Definition: block_mask.h:250
TableIndices< 2 > interface_constraints_size() const
Definition: fe.cc:857
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const =0
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
virtual Tensor< 2, dim > shape_grad_grad(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:205
static std::vector< unsigned int > compute_n_nonzero_components(const std::vector< ComponentMask > &nonzero_components)
Definition: fe.cc:1236
bool operator!=(const FiniteElement< dim, spacedim > &) const
Definition: fe.cc:991
bool is_primitive() const
Definition: fe.h:3285
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
Definition: fe.cc:1123
std::vector< Point< dim-1 > > generalized_face_support_points
Definition: fe.h:2476
const std::vector< unsigned int > n_nonzero_components_table
Definition: fe.h:2604
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
const unsigned int dofs_per_line
Definition: fe_base.h:246
BlockMask block_mask(const FEValuesExtractors::Scalar &scalar) const
Definition: fe.cc:465
virtual std::unique_ptr< InternalDataBase > get_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim > &quadrature,::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const =0
virtual std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const
Definition: fe.cc:931
std::vector< Point< dim > > unit_support_points
Definition: fe.h:2457
const unsigned int first_face_line_index
Definition: fe_base.h:278
bool restriction_is_implemented() const
Definition: fe.cc:724
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
Definition: fe.cc:335
static::ExceptionBase & ExcMessage(std::string arg1)
size_type n() const
const unsigned int first_quad_index
Definition: fe_base.h:268
No update.
std::vector< std::vector< FullMatrix< double > > > prolongation
Definition: fe.h:2433
#define Assert(cond, exc)
Definition: exceptions.h:1227
unsigned int component_to_block_index(const unsigned int component) const
Definition: fe.cc:366
UpdateFlags
virtual Tensor< 1, dim > shape_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
Definition: fe.cc:193
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
virtual double shape_value_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
Definition: fe.cc:170
unsigned int adjust_quad_dof_index_for_face_orientation(const unsigned int index, const bool face_orientation, const bool face_flip, const bool face_rotation) const
Definition: fe.cc:634
Abstract base class for mapping classes.
Definition: dof_tools.h:57
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
unsigned int size() const
unsigned int adjust_line_dof_index_for_line_orientation(const unsigned int index, const bool line_orientation) const
Definition: fe.cc:670
static::ExceptionBase & ExcWrongInterfaceMatrixSize(int arg1, int arg2)
bool represents_the_all_selected_mask() const
Definition: block_mask.h:323
virtual Point< dim > unit_support_point(const unsigned int index) const
Definition: fe.cc:1047
const FullMatrix< double > & constraints(const ::internal::SubfaceCase< dim > &subface_case=::internal::SubfaceCase< dim >::case_isotropic) const
Definition: fe.cc:830
virtual std::string get_name() const =0
bool represents_the_all_selected_mask() const
static::ExceptionBase & ExcProjectionVoid()
bool has_generalized_support_points() const
Definition: fe.cc:1038
virtual Point< dim-1 > unit_face_support_point(const unsigned int index) const
Definition: fe.cc:1109
virtual bool operator==(const FiniteElement< dim, spacedim > &fe) const
Definition: fe.cc:976
unsigned int n_components() const
size_type m() const
virtual std::size_t memory_consumption() const
Definition: fe.cc:1215
virtual Tensor< 1, dim > shape_grad(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:182
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
Definition: fe.cc:898
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
Definition: fe.cc:914
unsigned int first_selected_component(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
const unsigned int dofs_per_cell
Definition: fe_base.h:297
const std::vector< Point< dim > > & get_generalized_support_points() const
Definition: fe.cc:1025
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
size_type n_elements() const
virtual std::unique_ptr< InternalDataBase > get_face_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim-1 > &quadrature,::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
Definition: fe.cc:1251
virtual Tensor< 3, dim > shape_3rd_derivative_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
Definition: fe.cc:240
virtual std::unique_ptr< InternalDataBase > get_subface_data(const UpdateFlags update_flags, const Mapping< dim, spacedim > &mapping, const Quadrature< dim-1 > &quadrature,::internal::FEValuesImplementation::FiniteElementRelatedData< dim, spacedim > &output_data) const
Definition: fe.cc:1269
Table< 2, int > adjust_quad_dof_index_for_face_orientation_table
Definition: fe.h:2493
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false) const
Definition: fe.cc:551
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
Definition: fe.cc:306
static::ExceptionBase & ExcEmbeddingVoid()
virtual std::size_t memory_consumption() const
Definition: fe.cc:49
virtual FiniteElementDomination::Domination compare_for_face_domination(const FiniteElement< dim, spacedim > &fe_other) const
Definition: fe.cc:964
const unsigned int first_face_quad_index
Definition: fe_base.h:283
std::vector< std::pair< unsigned int, unsigned int > > system_to_component_table
Definition: fe.h:2513
virtual Tensor< 4, dim > shape_4th_derivative(const unsigned int i, const Point< dim > &p) const
Definition: fe.cc:253
unsigned int n_blocks() const
ComponentMask component_mask(const FEValuesExtractors::Scalar &scalar) const
Definition: fe.cc:379
const unsigned int dofs_per_face
Definition: fe_base.h:290
const unsigned int first_line_index
Definition: fe_base.h:263
const bool cached_primitivity
Definition: fe.h:2611
const std::vector< ComponentMask > nonzero_components
Definition: fe.h:2595
void reinit_restriction_and_prolongation_matrices(const bool isotropic_restriction_only=false, const bool isotropic_prolongation_only=false)
Definition: fe.cc:276
virtual Tensor< 4, dim > shape_4th_derivative_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
Definition: fe.cc:264
std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > system_to_base_table
Definition: fe.h:2544
static::ExceptionBase & ExcNotImplemented()
bool has_generalized_face_support_points() const
Definition: fe.cc:1100
unsigned int size() const
const unsigned int dofs_per_vertex
Definition: fe_base.h:240
Definition: table.h:37
std::vector< std::pair< unsigned int, unsigned int > > face_system_to_component_table
Definition: fe.h:2525
std::pair< std::unique_ptr< FiniteElement< dim, spacedim > >, unsigned int > operator^(const unsigned int multiplicity) const
Definition: fe.cc:150
const std::vector< Point< dim-1 > > & get_unit_face_support_points() const
Definition: fe.cc:1060
BlockIndices base_to_block_indices
Definition: fe.h:2556
std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > face_system_to_base_table
Definition: fe.h:2550
bool has_support_points() const
Definition: fe.cc:1016
types::global_dof_index first_block_of_base(const unsigned int b) const
Definition: fe.h:3202
bool has_face_support_points() const
Definition: fe.cc:1076
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
Definition: fe.cc:1287
std::vector< int > adjust_line_dof_index_for_line_orientation_table
Definition: fe.h:2508
void fill(InputIterator entries, const bool C_style_indexing=true)
const std::vector< bool > restriction_is_additive_flags
Definition: fe.h:2586
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.cc:1198
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
virtual Tensor< 2, dim > shape_grad_grad_component(const unsigned int i, const Point< dim > &p, const unsigned int component) const
Definition: fe.cc:216
static::ExceptionBase & ExcInternalError()