dune-pdelab  2.7-git
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  std::size_t size = 0;
35  for (int d = 0 ; d <= dim ; ++d)
36  {
37  std::size_t gt_size = FEM::size(GeometryTypes::none(d));
38  if (gt_size > 0)
39  {
40  if (size > 0 and size != gt_size)
41  return 0;
42  else
43  size = gt_size;
44  }
45  for (unsigned int topology_id = 0 ; topology_id < (1 << dim) ; ++topology_id)
46  {
47  std::size_t gt_size = FEM::size(GeometryType(topology_id,d));
48  if (gt_size > 0)
49  {
50  if (size > 0 and size != gt_size)
51  return 0;
52  else
53  size = gt_size;
54  }
55  }
56  }
57  return size;
58  }
59 
60  // fallback version if `FEM::size()` is an instance method.
61  template<typename FEM>
62  constexpr std::size_t _femBlockSize(std::false_type)
63  {
64  return 0;
65  }
66 
67  } // namespace Impl
68 
69 #endif // DOXYGEN
70 
72 
80  template<typename FEM>
81  constexpr std::size_t finiteElementMapBlockSize()
82  {
83  return Impl::_femBlockSize<FEM>(Std::is_detected<StaticFEMSize,FEM>());
84  }
85 
87  template<typename FEM>
88  using FiniteElementMapBlockSize = std::integral_constant<std::size_t,finiteElementMapBlockSize<FEM>()>;
89 
90  } // namespace PDELab
91 } //namespace Dune
92 
93 #endif // DUNE_PDELAB_FINITEELEMENTMAP_UTILITY_HH
static const int dim
Definition: adaptivity.hh:84
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
decltype(FEM::size(GeometryTypes::vertex)) StaticFEMSize
Metafunction that returns the type of FEM::size() iff that function is static.
Definition: finiteelementmap/utility.hh:17
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:88
constexpr std::size_t finiteElementMapBlockSize()
Returns the block size for FEM if available, 0 otherwise.
Definition: finiteelementmap/utility.hh:81