ProblemStatTraits.hpp 5.27 KB
Newer Older
1
2
3
4
#pragma once

#include <tuple>

5
6
7
8
#include <dune/functions/functionspacebases/basistags.hh>
#include <dune/functions/functionspacebases/flatmultiindex.hh>
#include <dune/functions/functionspacebases/compositebasis.hh>
#include <dune/functions/functionspacebases/powerbasis.hh>
9
10
11
#include <dune/functions/functionspacebases/pqknodalbasis.hh>
#include <dune/functions/functionspacebases/pq1nodalbasis.hh>
#include <dune/grid/yaspgrid.hh>
12
13
14

namespace AMDiS
{
15
  namespace Impl
16
  {
17
18
19
20
21
    template <class GridView, int k, class MultiIndex>
    struct LagrangeBasisSubFactory
    {
      using type = Dune::Functions::PQkNodeFactory<GridView, k, MultiIndex>;
    };
22

23
24
    template <class GridView, class MultiIndex>
    struct LagrangeBasisSubFactory<GridView, 1, MultiIndex>
25
    {
26
      using type = Dune::Functions::PQ1NodeFactory<GridView, MultiIndex>;
27
    };
28

29
30
31
32
    template <class GridView, bool same, int... deg>
    struct LagrangeBasisBuilderImpl;

    // specialization for composite basis
33
    template <class GridView, int... deg>
34
    struct LagrangeBasisBuilderImpl<GridView, false, deg...>
35
    {
36
37
38
      using MultiIndex = Dune::ReservedVector<std::size_t,1>;
      using IndexTag = Dune::Functions::BasisBuilder::FlatLexicographic;

39
      using type = Dune::Functions::CompositeNodeFactory<MultiIndex, IndexTag,
40
        typename LagrangeBasisSubFactory<GridView,deg,MultiIndex>::type...>;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    };

    // specialization for power basis
    template <class GridView, int deg, int... degs>
    struct LagrangeBasisBuilderImpl<GridView, true, deg, degs...>
    {
      using MultiIndex = Dune::ReservedVector<std::size_t,1>;
      using IndexTag = Dune::Functions::BasisBuilder::FlatLexicographic;

      using type = Dune::Functions::PowerNodeFactory<MultiIndex, IndexTag,
        typename LagrangeBasisSubFactory<GridView,deg,MultiIndex>::type, 1 + sizeof...(degs)>;
    };

    // factory to construct a global basis of several lagrange bases, with flat indexing.
    template <class GridView, int deg, int... degs>
    struct LagrangeBasisBuilder
    {
      using type = typename LagrangeBasisBuilderImpl<GridView, and_t<(deg == degs)...>::value, deg, degs...>::type;
    };


    template <class GridView>
    struct TaylorHoodBasisBuilder
    {
      using MultiIndex = Dune::ReservedVector<std::size_t,1>;
      using IndexTagV = Dune::Functions::BasisBuilder::FlatInterleaved;
67

68
69
70
71
72
73
74
75
      using VelocityNodeFactory = Dune::Functions::PowerNodeFactory<MultiIndex, IndexTagV,
        typename LagrangeBasisSubFactory<GridView,2,MultiIndex>::type, 2>;

      using PressureNodeFactory = typename LagrangeBasisSubFactory<GridView,1,MultiIndex>::type;

      using IndexTag = Dune::Functions::BasisBuilder::FlatLexicographic;
      using type = Dune::Functions::CompositeNodeFactory<MultiIndex, IndexTag,
        VelocityNodeFactory, PressureNodeFactory>;
76
    };
77

78
  } // end namespace Impl
79

80

81
82
83
  /// \brief A factory for a composite basis composed of lagrange bases of different degree.
  template <class GridView, int... degrees>
  using LagrangeBasis
84
    = Dune::Functions::DefaultGlobalBasis<typename Impl::LagrangeBasisBuilder<GridView, degrees...>::type>;
85
86


87
  /// Specialization of \ref LagrangeBasis for Grid type \ref Dune::YaspGrid for a given dimension.
88
  template <int dim, int... degrees>
89
90
  using YaspGridBasis = LagrangeBasis<typename Dune::YaspGrid<dim>::LeafGridView, degrees...>;

91
92
93
94
95

  template <class GridView>
  using TaylorHoodBasis
    = Dune::Functions::DefaultGlobalBasis<typename Impl::TaylorHoodBasisBuilder<GridView>::type>;

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
} // end namespace AMDiS


namespace Dune {
namespace Functions {
namespace BasisBuilder {

  namespace Imp
  {
    struct PQ1NodeFactoryBuilder
    {
      static const std::size_t requiredMultiIndexSize=1;

      template<class MultiIndex, class GridView>
      auto build(const GridView& gridView)
        -> PQ1NodeFactory<GridView, MultiIndex>
      {
        return {gridView};
      }
    };

  } // end namespace Imp

  // define the basis-build (factory-tag) for a given node-factory
  template <class NodeFactory>
  struct FactoryTag;

  template <class MultiIndex, class IndexMergingStrategy, class... SubFactories>
  struct FactoryTag<CompositeNodeFactory<MultiIndex, IndexMergingStrategy, SubFactories...>>
  {
    using type = Imp::CompositeNodeFactoryBuilder<IndexMergingStrategy, typename FactoryTag<SubFactories>::type...>;
  };

  template <class MultiIndex, class IndexMergingStrategy, class SubFactory, std::size_t C>
  struct FactoryTag<PowerNodeFactory<MultiIndex, IndexMergingStrategy, SubFactory, C>>
  {
    using type = Imp::PowerNodeFactoryBuilder<C, IndexMergingStrategy, typename FactoryTag<SubFactory>::type>;
  };

  template <class GridView, int k, class MultiIndex>
  struct FactoryTag<PQkNodeFactory<GridView, k, MultiIndex>>
  {
    using type = Imp::PQkNodeFactoryBuilder<k>;
  };

  template <class GridView, class MultiIndex>
  struct FactoryTag<PQ1NodeFactory<GridView, MultiIndex>>
  {
    using type = Imp::PQ1NodeFactoryBuilder;
  };

}}} // end namespace Dune::Functions::BasisBuilder


namespace AMDiS
{
  template <class GlobalBasis, class GridView>
  GlobalBasis makeGlobalBasis(GridView const& gv)
  {
    using NodeFactory = typename GlobalBasis::NodeFactory;
    using Builder = typename Dune::Functions::BasisBuilder::FactoryTag<NodeFactory>::type;
    return makeBasis(gv, Builder{});
  }
159

160
} // end namespace AMDiS