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_data.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) 2001 - 2026 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_data_h
14#define dealii_fe_data_h
15
16#include <deal.II/base/config.h>
17
19
21
23
24#include <vector>
25
27
28// Forward declarations:
29#ifndef DOXYGEN
30template <int dim>
32#endif
33
134
135namespace internal
136{
181 {
185 std::vector<std::vector<unsigned int>> dofs_per_object_exclusive;
186
190 std::vector<std::vector<unsigned int>> dofs_per_object_inclusive;
191
195 std::vector<std::vector<unsigned int>> object_index;
196
200 std::vector<std::vector<unsigned int>> first_object_index_on_face;
201
205 template <int dim>
208 };
209} // namespace internal
210
225template <int dim>
227{
228public:
260 {
264 unknown = 0x00,
265
269 L2 = 0x01,
270
275 Hcurl = 0x02,
276
281 Hdiv = 0x04,
282
287
292 H2 = 0x0e
293 };
294
299 static constexpr unsigned int dimension = dim;
300
301private:
306
313
318 const unsigned int number_unique_faces;
319
320public:
324 const unsigned int dofs_per_vertex;
325
330 const unsigned int dofs_per_line;
331
332private:
337 const std::vector<unsigned int> n_dofs_on_quad;
338
339public:
344 const unsigned int dofs_per_quad;
345
346private:
350 const unsigned int dofs_per_quad_max;
351
352public:
357 const unsigned int dofs_per_hex;
358
362 const unsigned int first_line_index;
363
364private:
370 const std::vector<unsigned int> first_index_of_quads;
371
372public:
376 const unsigned int first_quad_index;
377
381 const unsigned int first_hex_index;
382
383private:
387 const std::vector<unsigned int> first_line_index_of_faces;
388
389public:
393 const unsigned int first_face_line_index;
394
395private:
399 const std::vector<unsigned int> first_quad_index_of_faces;
400
401public:
405 const unsigned int first_face_quad_index;
406
407private:
412 const std::vector<unsigned int> n_dofs_on_face;
413
414public:
420 const unsigned int dofs_per_face;
421
422private:
426 const unsigned int dofs_per_face_max;
427
428public:
434 const unsigned int dofs_per_cell;
435
444 const unsigned int components;
445
450 const unsigned int degree;
451
456
463
502 FiniteElementData(const std::vector<unsigned int> &dofs_per_object,
503 const unsigned int n_components,
504 const unsigned int degree,
505 const Conformity conformity = unknown,
507
512 FiniteElementData(const std::vector<unsigned int> &dofs_per_object,
514 const unsigned int n_components,
515 const unsigned int degree,
516 const Conformity conformity = unknown,
518
527 const unsigned int n_components,
528 const unsigned int degree,
529 const Conformity conformity = unknown,
531
539
552 unsigned int
554
561 unsigned int
563
567 unsigned int
569
573 unsigned int
575
579 unsigned int
580 n_dofs_per_quad(unsigned int face_no = 0) const;
581
586 unsigned int
588
592 unsigned int
594
599 unsigned int
600 n_dofs_per_face(unsigned int face_no = 0, unsigned int child = 0) const;
601
606 unsigned int
608
613 unsigned int
615
624 template <int structdim>
625 unsigned int
626 n_dofs_per_object(const unsigned int i = 0) const;
627
633 unsigned int
635
641 unsigned int
642 n_blocks() const;
643
647 const BlockIndices &
649
656 unsigned int
658
665 bool
666 conforms(const Conformity) const;
667
671 bool
672 operator==(const FiniteElementData &) const;
673
677 unsigned int
679
683 unsigned int
684 get_first_quad_index(const unsigned int quad_no = 0) const;
685
689 unsigned int
691
695 unsigned int
696 get_first_face_line_index(const unsigned int face_no = 0) const;
697
701 unsigned int
702 get_first_face_quad_index(const unsigned int face_no = 0) const;
703};
704
705namespace internal
706{
711 template <int dim>
713 expand(const std::vector<unsigned int> &dofs_per_object,
714 const ReferenceCell<dim> reference_cell);
715} // namespace internal
716
717
718
719// --------- inline and template functions ---------------
720
721
722#ifndef DOXYGEN
723
725{
726 inline Domination
727 operator&(const Domination d1, const Domination d2)
728 {
729 // go through the entire list of possibilities. note that if we were into
730 // speed, obfuscation and cared enough, we could implement this operator
731 // by doing a bitwise & (and) if we gave these values to the enum values:
732 // neither_element_dominates=0, this_element_dominates=1,
733 // other_element_dominates=2, either_element_can_dominate=3
734 // =this_element_dominates|other_element_dominates
735 switch (d1)
736 {
738 if ((d2 == this_element_dominates) ||
741 else
743
745 if ((d2 == other_element_dominates) ||
748 else
750
753
755 if (d2 == no_requirements)
757 else
758 return d2;
759
760 case no_requirements:
761 return d2;
762
763 default:
764 // shouldn't get here
766 }
767
769 }
770} // namespace FiniteElementDomination
771
772
773template <int dim>
776{
777 return reference_cell_kind;
778}
779
780
781
782template <int dim>
783inline unsigned int
785{
786 return number_of_unique_2d_subobjects;
787}
788
789
790
791template <int dim>
792inline unsigned int
794{
795 return number_unique_faces;
796}
797
798
799
800template <int dim>
801inline unsigned int
803{
804 return dofs_per_vertex;
805}
806
807
808
809template <int dim>
810inline unsigned int
812{
813 return dofs_per_line;
814}
815
816
817
818template <int dim>
819inline unsigned int
820FiniteElementData<dim>::n_dofs_per_quad(unsigned int face_no) const
821{
822 return n_dofs_on_quad[n_dofs_on_quad.size() == 1 ? 0 : face_no];
823}
824
825
826
827template <int dim>
828inline unsigned int
830{
831 return dofs_per_quad_max;
832}
833
834
835
836template <int dim>
837inline unsigned int
839{
840 return dofs_per_hex;
841}
842
843
844
845template <int dim>
846inline unsigned int
847FiniteElementData<dim>::n_dofs_per_face(unsigned int face_no,
848 unsigned int child_no) const
849{
850 (void)child_no;
851
852 return n_dofs_on_face[n_dofs_on_face.size() == 1 ? 0 : face_no];
853}
854
855
856
857template <int dim>
858inline unsigned int
860{
861 return dofs_per_face_max;
862}
863
864
865
866template <int dim>
867inline unsigned int
869{
870 return dofs_per_cell;
871}
872
873
874
875template <int dim>
876template <int structdim>
877inline unsigned int
878FiniteElementData<dim>::n_dofs_per_object(const unsigned int i) const
879{
880 switch (structdim)
881 {
882 case 0:
883 return n_dofs_per_vertex();
884 case 1:
885 return n_dofs_per_line();
886 case 2:
887 return n_dofs_per_quad((structdim == 2 && dim == 3) ? i : 0);
888 case 3:
889 return n_dofs_per_hex();
890 default:
892 }
894}
895
896
897
898template <int dim>
899inline unsigned int
901{
902 return components;
903}
904
905
906
907template <int dim>
908inline const BlockIndices &
910{
911 return block_indices_data;
912}
913
914
915
916template <int dim>
917inline unsigned int
919{
920 return block_indices_data.size();
921}
922
923
924
925template <int dim>
926inline unsigned int
928{
929 return degree;
930}
931
932
933template <int dim>
934inline bool
935FiniteElementData<dim>::conforms(const Conformity space) const
936{
937 return ((space & conforming_space) == space);
938}
939
940
941
942template <int dim>
943unsigned int
945{
946 return first_line_index;
947}
948
949template <int dim>
950unsigned int
951FiniteElementData<dim>::get_first_quad_index(const unsigned int quad_no) const
952{
953 if (first_index_of_quads.size() == 1)
954 return first_index_of_quads[0] + quad_no * n_dofs_per_quad(0);
955 else
956 return first_index_of_quads[quad_no];
957}
958
959template <int dim>
960unsigned int
962{
963 return first_hex_index;
964}
965
966template <int dim>
967unsigned int
969 const unsigned int face_no) const
970{
971 return first_line_index_of_faces[first_line_index_of_faces.size() == 1 ?
972 0 :
973 face_no];
974}
975
976template <int dim>
977unsigned int
979 const unsigned int face_no) const
980{
981 return first_quad_index_of_faces[first_quad_index_of_faces.size() == 1 ?
982 0 :
983 face_no];
984}
985
986template <int dim>
989{
990 const auto reference_cell = fe.reference_cell();
991
993
994 result.dofs_per_object_exclusive.resize(4);
995 result.dofs_per_object_inclusive.resize(4);
996 result.object_index.resize(4);
997
998 unsigned int counter = 0;
999
1000 for (const unsigned int v : reference_cell.vertex_indices())
1001 {
1002 const auto c = fe.template n_dofs_per_object<0>(v);
1003
1004 result.dofs_per_object_exclusive[0].emplace_back(c);
1005 result.dofs_per_object_inclusive[0].emplace_back(c);
1006 result.object_index[0].emplace_back(counter);
1007
1008 counter += c;
1009 }
1010
1011 if (dim >= 2)
1012 for (const unsigned int l : reference_cell.line_indices())
1013 {
1014 const auto c = fe.template n_dofs_per_object<1>(l);
1015
1016 result.dofs_per_object_exclusive[1].emplace_back(c);
1017 result.dofs_per_object_inclusive[1].emplace_back(
1018 c + 2 * fe.template n_dofs_per_object<0>());
1019 result.object_index[1].emplace_back(counter);
1020
1021 counter += c;
1022 }
1023
1024 if (dim == 3)
1025 for (const unsigned int f : reference_cell.face_indices())
1026 {
1027 const auto c = fe.template n_dofs_per_object<2>(f);
1028
1029 result.dofs_per_object_exclusive[2].emplace_back(c);
1030 result.dofs_per_object_inclusive[2].emplace_back(fe.n_dofs_per_face(f));
1031 result.object_index[2].emplace_back(counter);
1032
1033 counter += c;
1034 }
1035
1036 {
1037 const auto c = fe.template n_dofs_per_object<dim>();
1038
1039 result.dofs_per_object_exclusive[dim].emplace_back(c);
1040 result.dofs_per_object_inclusive[dim].emplace_back(fe.n_dofs_per_cell());
1041 result.object_index[dim].emplace_back(counter);
1042
1043 counter += c;
1044 }
1045
1046 for (unsigned int d = dim + 1; d <= 3; ++d)
1047 {
1048 result.dofs_per_object_exclusive[d].emplace_back(0);
1049 result.dofs_per_object_inclusive[d].emplace_back(0);
1050 result.object_index[d].emplace_back(counter);
1051 }
1052
1053 result.first_object_index_on_face.resize(3);
1054 for (const unsigned int face_no : reference_cell.face_indices())
1055 {
1056 result.first_object_index_on_face[0].emplace_back(0);
1057
1058 result.first_object_index_on_face[1].emplace_back(
1059 fe.get_first_face_line_index(face_no));
1060
1061 result.first_object_index_on_face[2].emplace_back(
1062 fe.get_first_face_quad_index(face_no));
1063 }
1064
1065 return result;
1066}
1067
1068
1069#endif // DOXYGEN
1070
1071
1073
1074#endif
unsigned int size() const
const unsigned int dofs_per_quad
Definition fe_data.h:344
unsigned int get_first_line_index() const
unsigned int n_dofs_per_vertex() const
const unsigned int first_face_quad_index
Definition fe_data.h:405
const std::vector< unsigned int > first_index_of_quads
Definition fe_data.h:370
bool conforms(const Conformity) const
const std::vector< unsigned int > first_line_index_of_faces
Definition fe_data.h:387
const unsigned int components
Definition fe_data.h:444
const unsigned int degree
Definition fe_data.h:450
const std::vector< unsigned int > n_dofs_on_face
Definition fe_data.h:412
unsigned int n_dofs_per_cell() const
const unsigned int dofs_per_face
Definition fe_data.h:420
unsigned int n_dofs_per_line() const
unsigned int get_first_quad_index(const unsigned int quad_no=0) const
bool operator==(const FiniteElementData &) const
Definition fe_data.cc:189
const unsigned int dofs_per_line
Definition fe_data.h:330
unsigned int n_dofs_per_face(unsigned int face_no=0, unsigned int child=0) const
unsigned int n_blocks() const
unsigned int max_dofs_per_face() const
unsigned int tensor_degree() const
unsigned int n_components() const
const unsigned int first_hex_index
Definition fe_data.h:381
unsigned int n_dofs_per_object(const unsigned int i=0) const
const unsigned int first_face_line_index
Definition fe_data.h:393
const unsigned int dofs_per_quad_max
Definition fe_data.h:350
unsigned int n_unique_2d_subobjects() const
unsigned int get_first_face_line_index(const unsigned int face_no=0) const
const unsigned int first_line_index
Definition fe_data.h:362
const unsigned int dofs_per_hex
Definition fe_data.h:357
const BlockIndices block_indices_data
Definition fe_data.h:462
unsigned int get_first_face_quad_index(const unsigned int face_no=0) const
const unsigned int number_unique_faces
Definition fe_data.h:318
unsigned int max_dofs_per_quad() const
const BlockIndices & block_indices() const
const std::vector< unsigned int > first_quad_index_of_faces
Definition fe_data.h:399
const unsigned int number_of_unique_2d_subobjects
Definition fe_data.h:312
const std::vector< unsigned int > n_dofs_on_quad
Definition fe_data.h:337
const Conformity conforming_space
Definition fe_data.h:455
const unsigned int first_quad_index
Definition fe_data.h:376
unsigned int n_unique_faces() const
unsigned int n_dofs_per_quad(unsigned int face_no=0) const
const unsigned int dofs_per_vertex
Definition fe_data.h:324
const ReferenceCell< dim > reference_cell_kind
Definition fe_data.h:305
const unsigned int dofs_per_cell
Definition fe_data.h:434
static constexpr unsigned int dimension
Definition fe_data.h:299
unsigned int n_dofs_per_hex() const
ReferenceCell< dim > reference_cell() const
const unsigned int dofs_per_face_max
Definition fe_data.h:426
unsigned int get_first_hex_index() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ASSERT_UNREACHABLE()
unsigned int vertex_indices[2]
std::vector< index_type > data
Definition mpi.cc:734
Domination operator&(const Domination d1, const Domination d2)
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell< dim > &reference_cell)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
internal::GenericDoFsPerObject expand(const std::vector< unsigned int > &dofs_per_object, const ReferenceCell< dim > reference_cell)
Definition fe_data.cc:23
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
std::vector< std::vector< unsigned int > > object_index
Definition fe_data.h:195
std::vector< std::vector< unsigned int > > first_object_index_on_face
Definition fe_data.h:200
std::vector< std::vector< unsigned int > > dofs_per_object_inclusive
Definition fe_data.h:190
std::vector< std::vector< unsigned int > > dofs_per_object_exclusive
Definition fe_data.h:185
static GenericDoFsPerObject generate(const FiniteElementData< dim > &fe)