Reference documentation for deal.II version Git 9b341ae816 2021-01-21 15:59:19 -0700
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
fe_collection.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2003 - 2020 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 #ifndef dealii_fe_collection_h
17 #define dealii_fe_collection_h
18 
19 #include <deal.II/base/config.h>
20 
22 #include <deal.II/fe/fe.h>
24 
25 #include <memory>
26 
28 
29 namespace hp
30 {
50  template <int dim, int spacedim = dim>
51  class FECollection : public Subscriptor
52  {
53  public:
64  {
71  static unsigned int
72  next_index(const typename hp::FECollection<dim, spacedim> &fe_collection,
73  const unsigned int fe_index)
74  {
75  return ((fe_index + 1) < fe_collection.size()) ? fe_index + 1 :
76  fe_index;
77  }
78 
85  static unsigned int
87  const typename hp::FECollection<dim, spacedim> &fe_collection,
88  const unsigned int fe_index)
89  {
90  (void)fe_collection;
91  return (fe_index > 0) ? fe_index - 1 : fe_index;
92  }
93  };
94 
100  FECollection();
101 
108  explicit FECollection(const FiniteElement<dim, spacedim> &fe);
109 
116  template <class... FETypes>
117  explicit FECollection(const FETypes &... fes);
118 
126  FECollection(const std::vector<const FiniteElement<dim, spacedim> *> &fes);
127 
131  FECollection(const FECollection<dim, spacedim> &) = default;
132 
143  std::is_nothrow_move_constructible<
144  std::vector<std::shared_ptr<const FiniteElement<dim, spacedim>>>>::value
145  &&std::is_nothrow_move_constructible<std::function<
146  unsigned int(const typename hp::FECollection<dim, spacedim> &,
147  const unsigned int)>>::value) = default;
148 
153  operator=(FECollection<dim, spacedim> &&) = default; // NOLINT
154 
159  bool
160  operator==(const FECollection<dim, spacedim> &fe_collection) const;
161 
166  bool
167  operator!=(const FECollection<dim, spacedim> &fe_collection) const;
168 
178  void
180 
188  operator[](const unsigned int index) const;
189 
193  unsigned int
194  size() const;
195 
205  unsigned int
206  n_components() const;
207 
224  unsigned int
225  n_blocks() const;
226 
231  unsigned int
232  max_degree() const;
233 
238  unsigned int
239  max_dofs_per_vertex() const;
240 
245  unsigned int
246  max_dofs_per_line() const;
247 
252  unsigned int
253  max_dofs_per_quad() const;
254 
259  unsigned int
260  max_dofs_per_hex() const;
261 
266  unsigned int
267  max_dofs_per_face() const;
268 
273  unsigned int
274  max_dofs_per_cell() const;
275 
279  std::size_t
280  memory_consumption() const;
281 
282 
300  bool
302 
324  std::set<unsigned int>
325  find_common_fes(const std::set<unsigned int> &fes,
326  const unsigned int codim = 0) const;
327 
349  std::set<unsigned int>
350  find_enclosing_fes(const std::set<unsigned int> &fes,
351  const unsigned int codim = 0) const;
352 
385  unsigned int
386  find_dominating_fe(const std::set<unsigned int> &fes,
387  const unsigned int codim = 0) const;
388 
421  unsigned int
422  find_dominated_fe(const std::set<unsigned int> &fes,
423  const unsigned int codim = 0) const;
424 
448  unsigned int
449  find_dominating_fe_extended(const std::set<unsigned int> &fes,
450  const unsigned int codim = 0) const;
451 
474  unsigned int
475  find_dominated_fe_extended(const std::set<unsigned int> &fes,
476  const unsigned int codim = 0) const;
477 
490  void
491  set_hierarchy(const std::function<unsigned int(
492  const typename hp::FECollection<dim, spacedim> &,
493  const unsigned int)> &next,
494  const std::function<unsigned int(
495  const typename hp::FECollection<dim, spacedim> &,
496  const unsigned int)> &prev);
497 
505  void
507 
517  unsigned int
518  next_in_hierarchy(const unsigned int fe_index) const;
519 
529  unsigned int
530  previous_in_hierarchy(const unsigned int fe_index) const;
531 
549  component_mask(const FEValuesExtractors::Scalar &scalar) const;
550 
568  component_mask(const FEValuesExtractors::Vector &vector) const;
569 
589  const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const;
590 
612  component_mask(const BlockMask &block_mask) const;
613 
640  BlockMask
641  block_mask(const FEValuesExtractors::Scalar &scalar) const;
642 
665  BlockMask
666  block_mask(const FEValuesExtractors::Vector &vector) const;
667 
691  BlockMask
692  block_mask(const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const;
693 
722  BlockMask
723  block_mask(const ComponentMask &component_mask) const;
724 
736 
741  private:
745  std::vector<std::shared_ptr<const FiniteElement<dim, spacedim>>>
747 
752  std::function<unsigned int(const typename hp::FECollection<dim, spacedim> &,
753  const unsigned int)>
755 
760  std::function<unsigned int(const typename hp::FECollection<dim, spacedim> &,
761  const unsigned int)>
763  };
764 
765 
766 
767  /* --------------- inline functions ------------------- */
768 
769  template <int dim, int spacedim>
770  template <class... FETypes>
772  {
773  static_assert(
774  is_base_of_all<FiniteElement<dim, spacedim>, FETypes...>::value,
775  "Not all of the input arguments of this function "
776  "are derived from FiniteElement<dim,spacedim>!");
777 
778  // loop over all of the given arguments and add the finite elements to
779  // this collection. Inlining the definition of fe_pointers causes internal
780  // compiler errors on GCC 7.1.1 so we define it separately:
781  const auto fe_pointers = {
782  (static_cast<const FiniteElement<dim, spacedim> *>(&fes))...};
783  for (const auto p : fe_pointers)
784  push_back(*p);
785  }
786 
787 
788  template <int dim, int spacedim>
789  inline unsigned int
791  {
792  return finite_elements.size();
793  }
794 
795 
796  template <int dim, int spacedim>
797  inline unsigned int
799  {
801 
802  // note that there is no need
803  // here to enforce that indeed
804  // all elements have the same
805  // number of components since we
806  // have already done this when
807  // adding a new element to the
808  // collection.
809 
810  return finite_elements[0]->n_components();
811  }
812 
813 
814 
815  template <int dim, int spacedim>
816  inline bool
818  operator==(const FECollection<dim, spacedim> &fe_collection) const
819  {
820  const unsigned int n_elements = size();
821  if (n_elements != fe_collection.size())
822  return false;
823 
824  for (unsigned int i = 0; i < n_elements; ++i)
825  if (!(*finite_elements[i] == fe_collection[i]))
826  return false;
827 
828  return true;
829  }
830 
831 
832 
833  template <int dim, int spacedim>
834  inline bool
836  operator!=(const FECollection<dim, spacedim> &fe_collection) const
837  {
838  return !(*this == fe_collection);
839  }
840 
841 
842 
843  template <int dim, int spacedim>
845  operator[](const unsigned int index) const
846  {
847  AssertIndexRange(index, finite_elements.size());
848  return *finite_elements[index];
849  }
850 
851 
852 
853  template <int dim, int spacedim>
854  unsigned int
856  {
858 
859  unsigned int max = 0;
860  for (unsigned int i = 0; i < finite_elements.size(); ++i)
861  max = std::max(max, finite_elements[i]->degree);
862 
863  return max;
864  }
865 
866 
867 
868  template <int dim, int spacedim>
869  unsigned int
871  {
873 
874  unsigned int max = 0;
875  for (unsigned int i = 0; i < finite_elements.size(); ++i)
876  max = std::max(max, finite_elements[i]->n_dofs_per_vertex());
877 
878  return max;
879  }
880 
881 
882 
883  template <int dim, int spacedim>
884  unsigned int
886  {
888 
889  unsigned int max = 0;
890  for (unsigned int i = 0; i < finite_elements.size(); ++i)
891  max = std::max(max, finite_elements[i]->n_dofs_per_line());
892 
893  return max;
894  }
895 
896 
897 
898  template <int dim, int spacedim>
899  unsigned int
901  {
903 
904  unsigned int max = 0;
905  for (unsigned int i = 0; i < finite_elements.size(); ++i)
906  max = std::max(max, finite_elements[i]->max_dofs_per_quad());
907 
908  return max;
909  }
910 
911 
912 
913  template <int dim, int spacedim>
914  unsigned int
916  {
918 
919  unsigned int max = 0;
920  for (unsigned int i = 0; i < finite_elements.size(); ++i)
921  max = std::max(max, finite_elements[i]->n_dofs_per_hex());
922 
923  return max;
924  }
925 
926 
927 
928  template <int dim, int spacedim>
929  unsigned int
931  {
933 
934  unsigned int max = 0;
935  for (unsigned int i = 0; i < finite_elements.size(); ++i)
936  max = std::max(max, finite_elements[i]->max_dofs_per_face());
937 
938  return max;
939  }
940 
941 
942 
943  template <int dim, int spacedim>
944  unsigned int
946  {
948 
949  unsigned int max = 0;
950  for (unsigned int i = 0; i < finite_elements.size(); ++i)
951  max = std::max(max, finite_elements[i]->n_dofs_per_cell());
952 
953  return max;
954  }
955 
956 
957  template <int dim, int spacedim>
958  bool
960  {
962  return std::all_of(
963  finite_elements.cbegin(),
964  finite_elements.cend(),
965  [](const std::shared_ptr<const FiniteElement<dim, spacedim>> &fe) {
966  return fe->hp_constraints_are_implemented();
967  });
968  }
969 
970 
971 } // namespace hp
972 
974 
975 #endif
std::function< unsigned int(const typename hp::FECollection< dim, spacedim > &, const unsigned int)> hierarchy_prev
unsigned int find_dominated_fe_extended(const std::set< unsigned int > &fes, const unsigned int codim=0) const
static unsigned int next_index(const typename hp::FECollection< dim, spacedim > &fe_collection, const unsigned int fe_index)
Definition: fe_collection.h:72
ComponentMask component_mask(const FEValuesExtractors::Scalar &scalar) const
std::size_t memory_consumption() const
unsigned int find_dominating_fe(const std::set< unsigned int > &fes, const unsigned int codim=0) const
bool operator!=(const FECollection< dim, spacedim > &fe_collection) const
bool operator==(const FECollection< dim, spacedim > &fe_collection) const
#define AssertIndexRange(index, range)
Definition: exceptions.h:1691
unsigned int size() const
unsigned int next_in_hierarchy(const unsigned int fe_index) const
unsigned int find_dominating_fe_extended(const std::set< unsigned int > &fes, const unsigned int codim=0) const
std::function< unsigned int(const typename hp::FECollection< dim, spacedim > &, const unsigned int)> hierarchy_next
unsigned int n_blocks() const
BlockMask block_mask(const FEValuesExtractors::Scalar &scalar) const
unsigned int max_dofs_per_cell() const
void push_back(const FiniteElement< dim, spacedim > &new_fe)
bool hp_constraints_are_implemented() const
static ::ExceptionBase & ExcNoFiniteElements()
unsigned int max_dofs_per_hex() const
FECollection< dim, spacedim > & operator=(FECollection< dim, spacedim > &&)=default
#define Assert(cond, exc)
Definition: exceptions.h:1466
unsigned int max_degree() const
#define DeclException0(Exception0)
Definition: exceptions.h:470
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:380
unsigned int max_dofs_per_line() const
void set_hierarchy(const std::function< unsigned int(const typename hp::FECollection< dim, spacedim > &, const unsigned int)> &next, const std::function< unsigned int(const typename hp::FECollection< dim, spacedim > &, const unsigned int)> &prev)
Definition: hp.h:117
static unsigned int previous_index(const typename hp::FECollection< dim, spacedim > &fe_collection, const unsigned int fe_index)
Definition: fe_collection.h:86
unsigned int max_dofs_per_face() const
unsigned int max_dofs_per_vertex() const
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:379
std::set< unsigned int > find_common_fes(const std::set< unsigned int > &fes, const unsigned int codim=0) const
void set_default_hierarchy()
std::vector< std::shared_ptr< const FiniteElement< dim, spacedim > > > finite_elements
std::set< unsigned int > find_enclosing_fes(const std::set< unsigned int > &fes, const unsigned int codim=0) const
unsigned int find_dominated_fe(const std::set< unsigned int > &fes, const unsigned int codim=0) const
unsigned int n_components() const
T max(const T &t, const MPI_Comm &mpi_communicator)
const FiniteElement< dim, spacedim > & operator[](const unsigned int index) const
unsigned int max_dofs_per_quad() const
unsigned int previous_in_hierarchy(const unsigned int fe_index) const