AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
FlatPreBasis.hpp
1 #pragma once
2 
3 #include <dune/common/version.hh>
4 #include <dune/functions/functionspacebases/basistags.hh>
5 #include <dune/functions/functionspacebases/compositebasis.hh>
6 #include <dune/functions/functionspacebases/lagrangebasis.hh>
7 #include <dune/functions/functionspacebases/powerbasis.hh>
8 #include <dune/functions/functionspacebases/flatmultiindex.hh>
9 
10 #include <amdis/Output.hpp>
11 #include <amdis/common/TypeTraits.hpp>
12 #include <amdis/typetree/FiniteElementType.hpp>
13 
14 namespace AMDiS
15 {
16  // Convert the index-merging strategy to FlatLexicographic or FlatInterleaved for
17  // composite or power bases, respectively.
18  template <class PreBasis,
19  class MultiIndex = Dune::Functions::FlatMultiIndex<std::size_t>>
20  struct FlatPreBasis
21  {
22  using type = PreBasis;
23 
24  template <class PB>
25  static type create(PB const& preBasis)
26  {
27  return {preBasis.gridView()};
28  }
29 
30  static PreBasis const& create(PreBasis const& preBasis)
31  {
32  return preBasis;
33  }
34  };
35 
36  template <class PreBasis,
37  class MultiIndex = Dune::Functions::FlatMultiIndex<std::size_t>>
38  using FlatPreBasis_t = typename FlatPreBasis<PreBasis, MultiIndex>::type;
39 
40  template <class PreBasis>
41  auto flatPreBasis(PreBasis const& preBasis)
42  {
43  return FlatPreBasis<PreBasis>::create(preBasis);
44  }
45 
46  // specialization for Lagrange basis that needs an additional `order` parameter.
47  template <class GV, class MI, class R, class MultiIndex>
48  struct FlatPreBasis<Dune::Functions::LagrangePreBasis<GV,-1,MI,R>, MultiIndex>
49  {
50  using type = Dune::Functions::LagrangePreBasis<GV,-1,MultiIndex,R>;
51 
52  template <class PB>
53  static type create(PB const& preBasis)
54  {
55  auto node = preBasis.makeNode();
56  node.bind(*preBasis.gridView().template begin<0>());
57  return {preBasis.gridView(), (unsigned int)(node.finiteElement().localBasis().order())};
58  }
59 
60  static type const& create(type const& preBasis)
61  {
62  return preBasis;
63  }
64  };
65 
66  namespace Impl
67  {
68  template <class PreBasis, class... Index>
69  static auto const& subPreBasis(PreBasis const& preBasis, Index... ii)
70  {
71  return preBasis.subPreBasis(ii...);
72  }
73 
74  } // end namespace Impl
75 
76 
77  // specialization for composite bases
78  template <class MI, class IMS, class... SPB, class MultiIndex>
79  struct FlatPreBasis<Dune::Functions::CompositePreBasis<MI, IMS, SPB...>, MultiIndex>
80  {
81  using FIMS = Dune::Functions::BasisFactory::FlatLexicographic;
82  using type = Dune::Functions::CompositePreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>...>;
83 
84  template <class PreBasis>
85  static type create(PreBasis const& preBasis)
86  {
87  return create(preBasis, std::index_sequence_for<SPB...>{});
88  }
89 
90  template <class PreBasis, std::size_t... I>
91  static type create(PreBasis const& preBasis, std::index_sequence<I...>)
92  {
93  test_warning(std::is_same_v<IMS,FIMS>, "Basis converted into flat index-merging strategy.");
94  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis,Dune::index_constant<I>{}))...};
95  }
96  };
97 
98  // specialization for flat power bases
99  template <class MI, class IMS, class SPB, std::size_t C, class MultiIndex>
100  struct FlatPreBasis<Dune::Functions::PowerPreBasis<MI, IMS, SPB, C>, MultiIndex>
101  {
102  using type = Dune::Functions::PowerPreBasis<MultiIndex, IMS, SPB, C>;
103 
104  template <class PreBasis>
105  static type create(PreBasis const& preBasis)
106  {
107  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
108  }
109  };
110 
111  // specialization for blocked power bases
112  template <class MI, class SPB, std::size_t C, class MultiIndex>
113  struct FlatPreBasis<Dune::Functions::PowerPreBasis
114  <MI, Dune::Functions::BasisFactory::BlockedInterleaved, SPB, C>, MultiIndex>
115  {
116  using FIMS = Dune::Functions::BasisFactory::FlatInterleaved;
117  using type = Dune::Functions::PowerPreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>, C>;
118 
119  template <class PreBasis>
120  static type create(PreBasis const& preBasis)
121  {
122  warning("Basis converted into flat index-merging strategy.");
123  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
124  }
125  };
126 
127  // specialization for blocked power bases
128  template <class MI, class SPB, std::size_t C, class MultiIndex>
129  struct FlatPreBasis<Dune::Functions::PowerPreBasis
130  <MI, Dune::Functions::BasisFactory::BlockedLexicographic, SPB, C>, MultiIndex>
131  {
132  using FIMS = Dune::Functions::BasisFactory::FlatLexicographic;
133  using type = Dune::Functions::PowerPreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>, C>;
134 
135  template <class PreBasis>
136  static type create(PreBasis const& preBasis)
137  {
138  warning("Basis converted into flat index-merging strategy.");
139  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
140  }
141  };
142 
143 } // end namespace AMDiS
constexpr bool MultiIndex
A multi-index type.
Definition: Concepts.hpp:150
Definition: AdaptBase.hpp:6
Definition: FlatPreBasis.hpp:20