deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17:20:01+00:00
\(\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\}}\)
Loading...
Searching...
No Matches
fe_collection.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2005 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_fe_collection_h
14#define dealii_fe_collection_h
15
16#include <deal.II/base/config.h>
17
19#include <deal.II/fe/fe.h>
21
23
24#include <memory>
25#include <set>
26
27
29
30// Forward declarations
31namespace hp
32{
33 template <int dim, int spacedim>
34 class MappingCollection;
35}
36
37
38namespace hp
39{
59 template <int dim, int spacedim = dim>
60 class FECollection : public Collection<FiniteElement<dim, spacedim>>
61 {
62 public:
73 {
80 static unsigned int
81 next_index(const typename hp::FECollection<dim, spacedim> &fe_collection,
82 const unsigned int fe_index)
83 {
84 return ((fe_index + 1) < fe_collection.size()) ? fe_index + 1 :
85 fe_index;
86 }
87
94 static unsigned int
96 const typename hp::FECollection<dim, spacedim> &fe_collection,
97 const unsigned int fe_index)
98 {
99 (void)fe_collection;
100 return (fe_index > 0) ? fe_index - 1 : fe_index;
101 }
102 };
103
109 FECollection();
110
117 explicit FECollection(const FiniteElement<dim, spacedim> &fe);
118
125 template <class... FETypes>
126 explicit FECollection(const FETypes &...fes);
127
135 FECollection(const std::vector<const FiniteElement<dim, spacedim> *> &fes);
136
141
152 std::is_nothrow_move_constructible_v<
153 std::vector<std::shared_ptr<const FiniteElement<dim, spacedim>>>>
154 &&std::is_nothrow_move_constructible_v<std::function<
155 unsigned int(const typename hp::FECollection<dim, spacedim> &,
156 const unsigned int)>>) = default;
157
161 FECollection<dim, spacedim> &
162 operator=(FECollection<dim, spacedim> &&) = default; // NOLINT
163
168 bool
169 operator==(const FECollection<dim, spacedim> &fe_collection) const;
170
175 bool
176 operator!=(const FECollection<dim, spacedim> &fe_collection) const;
177
187 void
188 push_back(const FiniteElement<dim, spacedim> &new_fe);
189
207 unsigned int
209
226 unsigned int
227 n_blocks() const;
228
233 unsigned int
234 max_degree() const;
235
240 unsigned int
242
247 unsigned int
249
254 unsigned int
256
261 unsigned int
263
268 unsigned int
270
275 unsigned int
277
286 const MappingCollection<dim, spacedim> &
288
318 bool
320
342 std::vector<std::map<unsigned int, unsigned int>>
343 hp_vertex_dof_identities(const std::set<unsigned int> &fes) const;
344
349 std::vector<std::map<unsigned int, unsigned int>>
350 hp_line_dof_identities(const std::set<unsigned int> &fes) const;
351
360 std::vector<std::map<unsigned int, unsigned int>>
361 hp_quad_dof_identities(const std::set<std::pair<unsigned int, unsigned int>>
362 &fes_and_faces) const;
363
385 std::set<unsigned int>
386 find_common_fes(const std::set<unsigned int> &fes,
387 const unsigned int codim = 0) const;
388
410 std::set<unsigned int>
411 find_enclosing_fes(const std::set<unsigned int> &fes,
412 const unsigned int codim = 0) const;
413
446 unsigned int
447 find_dominating_fe(const std::set<unsigned int> &fes,
448 const unsigned int codim = 0) const;
449
482 unsigned int
483 find_dominated_fe(const std::set<unsigned int> &fes,
484 const unsigned int codim = 0) const;
485
509 unsigned int
510 find_dominating_fe_extended(const std::set<unsigned int> &fes,
511 const unsigned int codim = 0) const;
512
535 unsigned int
536 find_dominated_fe_extended(const std::set<unsigned int> &fes,
537 const unsigned int codim = 0) const;
538
563 void
564 set_hierarchy(const std::function<unsigned int(
565 const typename hp::FECollection<dim, spacedim> &,
566 const unsigned int)> &next,
567 const std::function<unsigned int(
568 const typename hp::FECollection<dim, spacedim> &,
569 const unsigned int)> &prev);
570
578 void
580
600 std::vector<unsigned int>
601 get_hierarchy_sequence(const unsigned int fe_index = 0) const;
602
612 unsigned int
613 next_in_hierarchy(const unsigned int fe_index) const;
614
624 unsigned int
625 previous_in_hierarchy(const unsigned int fe_index) const;
626
656 component_mask(const FEValuesExtractors::Scalar &scalar) const;
657
675 component_mask(const FEValuesExtractors::Vector &vector) const;
676
696 const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const;
697
719 component_mask(const BlockMask &block_mask) const;
720
748 block_mask(const FEValuesExtractors::Scalar &scalar) const;
749
773 block_mask(const FEValuesExtractors::Vector &vector) const;
774
799 block_mask(const FEValuesExtractors::SymmetricTensor<2> &sym_tensor) const;
800
831
847
852 private:
857 std::shared_ptr<MappingCollection<dim, spacedim>>
859
864 std::function<unsigned int(const typename hp::FECollection<dim, spacedim> &,
865 const unsigned int)>
867
872 std::function<unsigned int(const typename hp::FECollection<dim, spacedim> &,
873 const unsigned int)>
875 };
876
877
878
879 /* --------------- inline functions ------------------- */
880
881 template <int dim, int spacedim>
882 template <class... FETypes>
883 FECollection<dim, spacedim>::FECollection(const FETypes &...fes)
884 {
885 static_assert(
887 "Not all of the input arguments of this function "
888 "are derived from FiniteElement<dim, spacedim>!");
889
890 // loop over all of the given arguments and add the finite elements to
891 // this collection. Inlining the definition of fe_pointers causes internal
892 // compiler errors on GCC 7.1.1 so we define it separately:
893 const auto fe_pointers = {
894 (static_cast<const FiniteElement<dim, spacedim> *>(&fes))...};
895 for (const auto p : fe_pointers)
896 push_back(*p);
897 }
898
899
900
901 template <int dim, int spacedim>
902 inline unsigned int
904 {
905 Assert(this->size() > 0, ExcNoFiniteElements());
906
907 // note that there is no need
908 // here to enforce that indeed
909 // all elements have the same
910 // number of components since we
911 // have already done this when
912 // adding a new element to the
913 // collection.
914
915 return this->operator[](0).n_components();
916 }
917
918
919
920 template <int dim, int spacedim>
921 inline bool
923 const FECollection<dim, spacedim> &fe_collection) const
924 {
925 const unsigned int n_elements = this->size();
926 if (n_elements != fe_collection.size())
927 return false;
928
929 for (unsigned int i = 0; i < n_elements; ++i)
930 if (!(this->operator[](i) == fe_collection[i]))
931 return false;
932
933 return true;
934 }
935
936
937
938 template <int dim, int spacedim>
939 inline bool
941 const FECollection<dim, spacedim> &fe_collection) const
942 {
943 return !(*this == fe_collection);
944 }
945
946
947
948 template <int dim, int spacedim>
949 unsigned int
951 {
952 Assert(this->size() > 0, ExcNoFiniteElements());
953
954 unsigned int max = 0;
955 for (unsigned int i = 0; i < this->size(); ++i)
956 max = std::max(max, this->operator[](i).degree);
957
958 return max;
959 }
960
961
962
963 template <int dim, int spacedim>
964 unsigned int
966 {
967 Assert(this->size() > 0, ExcNoFiniteElements());
968
969 unsigned int max = 0;
970 for (unsigned int i = 0; i < this->size(); ++i)
971 max = std::max(max, this->operator[](i).n_dofs_per_vertex());
972
973 return max;
974 }
975
976
977
978 template <int dim, int spacedim>
979 unsigned int
981 {
982 Assert(this->size() > 0, ExcNoFiniteElements());
983
984 unsigned int max = 0;
985 for (unsigned int i = 0; i < this->size(); ++i)
986 max = std::max(max, this->operator[](i).n_dofs_per_line());
987
988 return max;
989 }
990
991
992
993 template <int dim, int spacedim>
994 unsigned int
996 {
997 Assert(this->size() > 0, ExcNoFiniteElements());
998
999 unsigned int max = 0;
1000 for (unsigned int i = 0; i < this->size(); ++i)
1001 max = std::max(max, this->operator[](i).max_dofs_per_quad());
1002
1003 return max;
1004 }
1005
1006
1007
1008 template <int dim, int spacedim>
1009 unsigned int
1011 {
1012 Assert(this->size() > 0, ExcNoFiniteElements());
1013
1014 unsigned int max = 0;
1015 for (unsigned int i = 0; i < this->size(); ++i)
1016 max = std::max(max, this->operator[](i).n_dofs_per_hex());
1017
1018 return max;
1019 }
1020
1021
1022
1023 template <int dim, int spacedim>
1024 unsigned int
1026 {
1027 Assert(this->size() > 0, ExcNoFiniteElements());
1028
1029 unsigned int max = 0;
1030 for (unsigned int i = 0; i < this->size(); ++i)
1031 max = std::max(max, this->operator[](i).max_dofs_per_face());
1032
1033 return max;
1034 }
1035
1036
1037
1038 template <int dim, int spacedim>
1039 unsigned int
1041 {
1042 Assert(this->size() > 0, ExcNoFiniteElements());
1043
1044 unsigned int max = 0;
1045 for (unsigned int i = 0; i < this->size(); ++i)
1046 max = std::max(max, this->operator[](i).n_dofs_per_cell());
1047
1048 return max;
1049 }
1050
1051
1052 template <int dim, int spacedim>
1053 bool
1055 {
1056 Assert(this->size() > 0, ExcNoFiniteElements());
1057
1058 for (unsigned int i = 0; i < this->size(); ++i)
1059 if (this->operator[](i).hp_constraints_are_implemented() == false)
1060 return false;
1061
1062 return true;
1063 }
1064
1065
1066} // namespace hp
1067
1069
1070#endif
*  x_component_mask set(0, true)
unsigned int size() const
Definition collection.h:314
const T & operator[](const unsigned int index) const
Definition collection.h:332
std::vector< std::map< unsigned int, unsigned int > > hp_vertex_dof_identities(const std::set< unsigned int > &fes) const
unsigned int previous_in_hierarchy(const unsigned int fe_index) const
unsigned int max_dofs_per_line() const
unsigned int max_dofs_per_hex() const
std::vector< unsigned int > get_hierarchy_sequence(const unsigned int fe_index=0) const
unsigned int max_dofs_per_vertex() const
unsigned int find_dominating_fe_extended(const std::set< unsigned int > &fes, const unsigned int codim=0) const
std::vector< std::map< unsigned int, unsigned int > > hp_quad_dof_identities(const std::set< std::pair< unsigned int, unsigned int > > &fes_and_faces) const
bool hp_constraints_are_implemented() const
bool operator==(const FECollection< dim, spacedim > &fe_collection) const
std::function< unsigned int(const typename hp::FECollection< dim, spacedim > &, const unsigned int)> hierarchy_next
const MappingCollection< dim, spacedim > & get_reference_cell_default_linear_mapping() const
std::set< unsigned int > find_common_fes(const std::set< unsigned int > &fes, const unsigned int codim=0) const
FECollection(const FETypes &...fes)
void push_back(const FiniteElement< dim, spacedim > &new_fe)
unsigned int next_in_hierarchy(const unsigned int fe_index) const
std::shared_ptr< MappingCollection< dim, spacedim > > reference_cell_default_linear_mapping
unsigned int max_degree() const
unsigned int find_dominating_fe(const std::set< unsigned int > &fes, const unsigned int codim=0) const
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 max_dofs_per_face() const
FECollection(FECollection< dim, spacedim > &&) noexcept(std::is_nothrow_move_constructible_v< std::vector< std::shared_ptr< const FiniteElement< dim, spacedim > > > > &&std::is_nothrow_move_constructible_v< std::function< unsigned int(const typename hp::FECollection< dim, spacedim > &, const unsigned int)> >)=default
ComponentMask component_mask(const FEValuesExtractors::Scalar &scalar) const
bool operator!=(const FECollection< dim, spacedim > &fe_collection) const
std::vector< std::map< unsigned int, unsigned int > > hp_line_dof_identities(const std::set< unsigned int > &fes) 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)
unsigned int max_dofs_per_quad() const
unsigned int find_dominated_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_prev
unsigned int n_blocks() const
FECollection(const FECollection< dim, spacedim > &)=default
unsigned int n_components() const
unsigned int max_dofs_per_cell() const
BlockMask block_mask(const FEValuesExtractors::Scalar &scalar) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DeclException0(Exception0)
#define Assert(cond, exc)
static ::ExceptionBase & ExcNoFiniteElements()
Definition hp.h:115
STL namespace.
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
static unsigned int next_index(const typename hp::FECollection< dim, spacedim > &fe_collection, const unsigned int fe_index)
static unsigned int previous_index(const typename hp::FECollection< dim, spacedim > &fe_collection, const unsigned int fe_index)
void prev(std::tuple< I1, I2 > &t)