dune-pdelab  2.5-dev
finiteelementmap/utility.hh
Go to the documentation of this file.
1 #ifndef DUNE_PDELAB_FINITEELEMENTMAP_UTILITY_HH
2 #define DUNE_PDELAB_FINITEELEMENTMAP_UTILITY_HH
3 
4 #include <cstddef>
5 
6 #include <dune/common/keywords.hh>
7 #include <dune/geometry/type.hh>
8 
9 namespace Dune {
10  namespace PDELab {
11 
13 
16  template<typename FEM>
17  using StaticFEMSize = decltype(FEM::size(GeometryTypes::vertex));
18 
19 #ifndef DOXYGEN
20 
21  namespace Impl {
22 
23  // This function iterates over all geometry types up to the dimension of the finite element map
24  // and returns the value of FEM::size(gt) iff that number is constant for all geometry types for
25  // which the returned size is > 0. Otherwise it returns 0. As this only works if FEM::size() is
26  // static, we use the additional argument to provide a separate overload if it is not.
27  // Note that as there is no way to easily construct the set of "valid" geometry types for a
28  // given dimension, we manually iterate over all possible topology ids. This creates weird
29  // geometry types, but we just assume that FEM::size() will return 0 for invalid ones.
30  template<typename FEM>
31  constexpr std::size_t _femBlockSize(std::true_type)
32  {
33  constexpr int dim = FEM::dimension;
34  for (int d = 0 ; d <= dim ; ++d)
35  {
36  std::size_t size = FEM::size(GeometryTypes::none(d));
37  if (size > 0)
38  return size;
39  for (unsigned int topology_id = 0 ; topology_id < (1 << dim) ; ++topology_id)
40  {
41  std::size_t size = FEM::size(GeometryType(topology_id,d));
42  if (size > 0)
43  return size;
44  }
45  }
46  return 0;
47  }
48 
49  // fallback version if `FEM::size()` is an instance method.
50  template<typename FEM>
51  constexpr std::size_t _femBlockSize(std::false_type)
52  {
53  return 0;
54  }
55 
56  template<typename FEM>
57  using Dimension = std::integral_constant<decltype(FEM::dimension),FEM::dimension>;
58 
59  template<typename FEM>
60  constexpr std::size_t femBlockSizeCheckFEMInterface(std::true_type)
61  {
62  return _femBlockSize<FEM>(Std::is_detected<StaticFEMSize,FEM>());
63  }
64 
65  template<typename FEM>
66  DUNE_DEPRECATED_MSG("Your finite element map does not export the dimension. After the release of PDELab 2.6, this will cause compilation failures.")
67  constexpr std::size_t femBlockSizeCheckFEMInterface(std::false_type)
68  {
69  return 0;
70  }
71 
72  } // namespace Impl
73 
74 #endif // DOXYGEN
75 
77 
85  template<typename FEM>
86  constexpr std::size_t finiteElementMapBlockSize()
87  {
88  return Impl::femBlockSizeCheckFEMInterface<FEM>(Std::is_detected<Impl::Dimension,FEM>());
89  }
90 
92  template<typename FEM>
93  using FiniteElementMapBlockSize = std::integral_constant<std::size_t,finiteElementMapBlockSize<FEM>()>;
94 
95  } // namespace PDELab
96 } //namespace Dune
97 
98 #endif // DUNE_PDELAB_FINITEELEMENTMAP_UTILITY_HH
dim
static const int dim
Definition: adaptivity.hh:84
Dune
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
Dune::PDELab::StaticFEMSize
decltype(FEM::size(GeometryTypes::vertex)) StaticFEMSize
Metafunction that returns the type of FEM::size() iff that function is static.
Definition: finiteelementmap/utility.hh:17
Dune::PDELab::FiniteElementMapBlockSize
std::integral_constant< std::size_t, finiteElementMapBlockSize< FEM >()> FiniteElementMapBlockSize
An alias template that encapsulates the result of finiteElementMapBlockSize<FEM>() in an integral con...
Definition: finiteelementmap/utility.hh:93
Dune::PDELab::finiteElementMapBlockSize
constexpr std::size_t finiteElementMapBlockSize()
Returns the block size for FEM if available, 0 otherwise.
Definition: finiteelementmap/utility.hh:86