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 MultiIndex>
48  struct FlatPreBasis<Dune::Functions::LagrangePreBasis<GV,-1,MI>, MultiIndex>
49  {
50  using type = Dune::Functions::LagrangePreBasis<GV,-1,MultiIndex>;
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  // NOTE: dirty hack to get access to protected member variable, due to missing
69  // function in dune-functions-2.6
70  template <class PreBasis>
71  class DerivedPreBasis {
72  public:
73  // specialization for PowerPreBasis
74  template <class PB, class SPB = typename PB::SubPreBasis>
75  static SPB const& subPreBasis(PB const& pb)
76  {
77  return access(pb).subPreBasis_;
78  }
79 
80  // specialization for CompositePreBasis
81  template <std::size_t I, class PB, class SPB = typename PB::template SubPreBasis<I>>
82  static SPB const& subPreBasis(PB const& pb, Dune::index_constant<I>)
83  {
84  return std::get<I>(access(pb).subPreBases_);
85  }
86 
87  template <class T>
88  class Accessor : public T { friend class DerivedPreBasis<PreBasis>; };
89 
90  template <class T>
91  static Accessor<T> const& access(T const& obj) { return static_cast<Accessor<T> const&>(obj); }
92  };
93 
94  template <class PreBasis, class... Index>
95  static auto const& subPreBasis(PreBasis const& preBasis, Index... ii)
96  {
97  return DerivedPreBasis<PreBasis>::subPreBasis(preBasis,ii...);
98  }
99 
100  } // end namespace Impl
101 
102 
103  // specialization for composite bases
104  template <class MI, class IMS, class... SPB, class MultiIndex>
105  struct FlatPreBasis<Dune::Functions::CompositePreBasis<MI, IMS, SPB...>, MultiIndex>
106  {
107  using FIMS = Dune::Functions::BasisFactory::FlatLexicographic;
108  using type = Dune::Functions::CompositePreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>...>;
109 
110  template <class PreBasis>
111  static type create(PreBasis const& preBasis)
112  {
113  return create(preBasis, std::index_sequence_for<SPB...>{});
114  }
115 
116  template <class PreBasis, std::size_t... I>
117  static type create(PreBasis const& preBasis, std::index_sequence<I...>)
118  {
119  test_warning(std::is_same_v<IMS,FIMS>, "Basis converted into flat index-merging strategy.");
120  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis,Dune::index_constant<I>{}))...};
121  }
122  };
123 
124  // specialization for flat power bases
125  template <class MI, class IMS, class SPB, std::size_t C, class MultiIndex>
126  struct FlatPreBasis<Dune::Functions::PowerPreBasis<MI, IMS, SPB, C>, MultiIndex>
127  {
128  using type = Dune::Functions::PowerPreBasis<MultiIndex, IMS, SPB, C>;
129 
130  template <class PreBasis>
131  static type create(PreBasis const& preBasis)
132  {
133  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
134  }
135  };
136 
137  // specialization for blocked power bases
138  template <class MI, class SPB, std::size_t C, class MultiIndex>
139  struct FlatPreBasis<Dune::Functions::PowerPreBasis
140  <MI, Dune::Functions::BasisFactory::BlockedInterleaved, SPB, C>, MultiIndex>
141  {
142  using FIMS = Dune::Functions::BasisFactory::FlatInterleaved;
143  using type = Dune::Functions::PowerPreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>, C>;
144 
145  template <class PreBasis>
146  static type create(PreBasis const& preBasis)
147  {
148  warning("Basis converted into flat index-merging strategy.");
149  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
150  }
151  };
152 
153  // specialization for blocked power bases
154  template <class MI, class SPB, std::size_t C, class MultiIndex>
155  struct FlatPreBasis<Dune::Functions::PowerPreBasis
156  <MI, Dune::Functions::BasisFactory::BlockedLexicographic, SPB, C>, MultiIndex>
157  {
158  using FIMS = Dune::Functions::BasisFactory::FlatLexicographic;
159  using type = Dune::Functions::PowerPreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>, C>;
160 
161  template <class PreBasis>
162  static type create(PreBasis const& preBasis)
163  {
164  warning("Basis converted into flat index-merging strategy.");
165  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
166  }
167  };
168 
169 } // end namespace AMDiS
constexpr bool MultiIndex
A multi-index type.
Definition: Concepts.hpp:150
Definition: AdaptBase.hpp:6
Definition: FlatPreBasis.hpp:20