FiniteElementType.hpp 1.98 KB
Newer Older
1
2
#pragma once

3
4
5
6
7
#include <cmath>

#include <dune/amdis/common/Loops.hpp>
#include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/Tags.hpp>
8

9
10
11
12
13
namespace AMDiS
{
  namespace Impl
  {
    template <class Node, bool isLeaf, bool isPower, bool isComposite>
14
    struct FiniteElementTypeImpl
15
16
    {
      static_assert( isLeaf || isPower || isComposite, "Unknown node-type for range definition" );
17
18
19

      // polynomial degree of finite-element basis functions
      static int order(Node const&) { return 0; }
20
    };
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  }

  template <class Node>
  using FiniteElementType =
    Impl::FiniteElementTypeImpl<Node, Node::isLeaf, Node::isPower, Node::isComposite>;

  template <class Node>
  using FiniteElementType_t = typename FiniteElementType<Node>::type;

  template <class Node>
  int polynomialDegree(Node const& node)
  {
    return FiniteElementType<Node>::order(node);
  }

36

37
38
39
  namespace Impl
  {
    // Leaf node
40
    template <class Node>
41
    struct FiniteElementTypeImpl<Node, true, false, false>
42
43
    {
      using type = typename Node::FiniteElement;
44
45
46
47
48

      static int order(Node const& node)
      {
        return node.finiteElement().localBasis().order();
      }
49
50
    };

51
    // Power node
52
    template <class Node>
53
    struct FiniteElementTypeImpl<Node, false, true, false>
54
55
    {
      using ChildNode = typename Node::template Child<0>::type;
56
57
58
59
60
61
      using type = FiniteElementType_t<ChildNode>;

      static int order(Node const& node)
      {
        return FiniteElementType<ChildNode>::order(node.child(0));
      }
62
63
    };

64
    // Composite node
65
    template <class Node>
66
    struct FiniteElementTypeImpl<Node, false, false, true>
67
    {
68
69
70
71
72
73
74
75
76
77
      using type = tag::unknown; // no common FiniteElement type

      static int order(Node const& node)
      {
        int degree = 0;
        forEach(range_<0,Node::CHILDREN>, [&](auto const _i) {
          degree = std::max(degree, polynomialDegree(node.child(_i)));
        });
        return degree;
      }
78
79
80
81
82
    };

  } // end namespace Impl

} // end namespace AMDiS